Hi gueys,
I have question searched in google but without something that can help.
How to get the binary stream from files ( especially executable files) using winapi (CreateFile , etc)????
I learned in these days how to read write files using Createfile, ReadFile, WriteFile , etc and all these WINAPI functions.
But ReadFile get me characters contains of files, and when I want to read exe files it get me a few bytes and that's it.
The reason of this behaviour is that the readfile read the file until get NULL and as you know the exe files have alot of NULL codes. So I must read the binary code of the exe file and do my process on it, this way is better.... but how to do it???

I hope you have some ideas for me.

Thanx

Recommended Answers

All 10 Replies

The reason of this behaviour is that the readfile read the file until get NULL

I think you misunderstood. ReadFile() reads in binary mode, the same as fstream.read() or in C fread(). You tell it how many bytes to read and it will read that many bytes, or until end-of-file. ReadFile() doesn't do text reads like c++ getline() or fgets().

So, why this function return me the character contains of the file???

When I want to read from EXE file the function read the first 3 bytes and no more, even though I have detemined the size of buffer to read.
The following code explain my program:

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <strsafe.h>

void GetTheError(LPTSTR lpszFunction);
HANDLE          hIOCP = NULL;
void _tmain(int argc, TCHAR *argv[])
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hFile;

    hFile = FindFirstFile(TEXT("I:\\Kaspersky Password Manager\\stpass.exe"), &FindFileData);
    if (hFile == INVALID_HANDLE_VALUE) 
    {
        GetTheError(TEXT("FindFirstFile"));
        return;
    } 
    else 
    {
        _tprintf (TEXT("The first file found is %s\n"), 
                    FindFileData.cFileName);
    }
    _tprintf(TEXT("\n"));
    char* File;
    char* c1;
    char* c2;
    c1 = "I:\\Kaspersky Password Manager\\";
    c2 = FindFileData.cFileName;
    File = (char *)malloc((strlen(c1) + strlen(c2 +1)));
    strcpy(File,c1);
    strcat(File,c2);
    hFile = CreateFile( File ,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if (hFile == INVALID_HANDLE_VALUE) 
    { 
        GetTheError(TEXT("CreateFile"));
        _tprintf(TEXT("Terminal failure: unable to open file \"%s\" for read.\n"), (LPCWSTR)File);
        return; 
    }
    DWORD BytRet;
    DWORD BufferSize = GetFileSize(hFile,NULL);
    char  ReadData[1000000] = {0};
    if (FALSE == ReadFile(hFile, ReadData, 1000000 - 1, &BytRet, NULL))
    {
        GetTheError(TEXT("ReadFile"));
        _tprintf(TEXT("\n"));
        FindClose(hFile);
        return; 
    }
    else
    {
        ReadData[BytRet] = '\0';
        printf(ReadData);
    }
    FindClose(hFile);
    printf("\n");
    system("pause");
}

void GetTheError(LPTSTR lpszFunction) 
{ 

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw);
}

If My guess is correct, I think you phrase the question wrong because of the way your saying that it reads contents of the file.. I think you mean read the instructions of an EXE file. Such as the OPCodes or I think what you mean by "EXE's have a lot of nulls" is that they have a lot of NOP's Aka No-Operations.

That's Assembly code. ReadFile doesn't do that for you. It opens the file as a text and reads the contents of that. It's the same as opening the EXE in Notepad and reading it. ReadFile reads in Binary MODE but doesn't actually read in the assembly of the file.

I'm also looking for a way to read/write Assembly to an exe. So.. :S If I find a way then I'll answer here until then I'll just be looking around.

I am not saying " I want to read the assembly code", I mean that to read the file and display the HEXA DECIMAL code of the file (binary stream).
That's what I mean.

Sorry gueys, I have misunderstood the way of the function work.
I have make a debug step by step and I have discoverd that the (ReadData) variable value contain the hole characters specified, but how to convert it to HEXADECIMAL?
Thanx gueys, I will complete the road by myselft.
Thank you all.

you can use stringstream to convert to hex or cast each character to decimal like:

(int)String[I];

Then

int DecToHex(int DecNumber)
{
    int Hexa = 0, Pos = 1;
    while (DecNumber > 0)
    {
        Hexa += (DecNumber % 16) * Pos;
        DecNumber /= 16;
        Pos *= 10;
    }
    return Hexa;
}

Which will give you the hex equivalent of the decimal.. Now convert that to a string with 0x infront of it and whala.

EDIT: Hmm Why does my code tags look like that :S Wish we had the old ones back..

char ReadData[1000000] = {0};

Just an observation. If you are reading a binary file, you should define ReadData as an unsigned char to accomodate binary values from 0 to 255. Otherwise, the ReadFile variable will contain negative values for any binary data over 127.

EDIT: Hmm Why does my code tags look like that :S

Like what exactly?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.