Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to parse EXE file and get data from IMAGE_DOS_HEADER structure using c++ and Window.h?

I am trying to parse PE file in windows and get data from this structure

IMAGE_DOS_HEADER

I wrote this code, that reads bytes from exe file.

 #include <Windows.h>
    
    int main()
    {
        // open the file for binary reading
        std::ifstream file;
            file.open("D:/SomeProgram.exe", ios_base::binary);
    
        if (!file.is_open())
            return 1;
    
        // get the length of the file
        file.seekg(0, ios::end);
        size_t fileSize = file.tellg();
        file.seekg(0, ios::beg);
    
        // create a vector to hold all the bytes in the file
        std::vector<byte> data(fileSize, 0);
    
        // read the file
        file.read(reinterpret_cast<char*>(&data[0]), fileSize);

I have no idea, how to get data, that contains e_magic, e_cbip, e_cp .... and the most important e_ifanew. I know, that this structure IMAGE_DOS_HEADER is stored in Windows.h, but I don't know how to use it to get fields from any exe file.

like image 470
Dsdsd Avatar asked Sep 03 '17 15:09

Dsdsd


3 Answers

Find below process to get data from different headers :

LPCSTR fileName; //exe file to parse
HANDLE hFile; 
HANDLE hFileMapping;
LPVOID lpFileBase;
PIMAGE_DOS_HEADER dosHeader;
PIMAGE_NT_HEADERS peHeader;

hFile = CreateFileA(fileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

if(hFile==INVALID_HANDLE_VALUE)
{
    printf("\n CreateFile failed in read mode \n");
    return 1;
}

hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);

if(hFileMapping==0)
{
    printf("\n CreateFileMapping failed \n");
    CloseHandle(hFile);
    return 1;
}

lpFileBase = MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0);

if(lpFileBase==0)
{
    printf("\n MapViewOfFile failed \n");
    CloseHandle(hFileMapping);
    CloseHandle(hFile);
    return 1;
}

dosHeader = (PIMAGE_DOS_HEADER) lpFileBase;  //pointer to dos headers

if(dosHeader->e_magic==IMAGE_DOS_SIGNATURE)
{
    //if it is executable file print different fileds of structure
    //dosHeader->e_lfanew : RVA for PE Header
    printf("\n DOS Signature (MZ) Matched");

    //pointer to PE/NT header
    peHeader = (PIMAGE_NT_HEADERS) ((u_char*)dosHeader+dosHeader->e_lfanew);

    if(peHeader->Signature==IMAGE_NT_SIGNATURE)
    {
        printf("\n PE Signature (PE) Matched \n");
        //important fileds
        //peHeader->FileHeader : Refrence to FileHeader
        //peHeader->OptionalHeader :  Refrence to Optional Header
        // lots of imprtant fileds are present in File header and Optional header to retrive code/data/different sections address of exe

    }

    UnmapViewOfFile(lpFileBase);
    CloseHandle(hFileMapping);
    CloseHandle(hFile);
    return 0;
}
else
{
    printf("\n DOS Signature (MZ) Not Matched \n");
    UnmapViewOfFile(lpFileBase);
    CloseHandle(hFileMapping);
    CloseHandle(hFile);
    return 1;
}
like image 121
Nishikant Mokashi Avatar answered Nov 15 '22 03:11

Nishikant Mokashi


Declare an instance of the structure and copy the data into it:

IMAGE_DOS_HEADER idh;

if ( fileSize >= sizeof(idh) )
{
    std::memcpy(&idh, &data[0], sizeof(idh));
}
like image 44
Jim Rhodes Avatar answered Nov 15 '22 03:11

Jim Rhodes


Read the file into buffer and cast part of it as structs.

// READ FILE ASSUMING IT EXISTS AND IS A VALID PE FILE
char* buffer = nullptr;
std::ifstream infile("C:\\file.exe", std::ios::binary);

std::filebuf* pbuf = infile.rdbuf();

size_t size = pbuf->pubseekoff(0, infile.end, infile.in);

buffer = new char[size];

pbuf->pubseekpos(0, infile.in);
pbuf->sgetn(buffer, size);

infile.close();

// CAST
IMAGE_DOS_HEADER* MS_DOS = (IMAGE_DOS_HEADER*)buffer;
IMAGE_NT_HEADERS* PE = (IMAGE_NT_HEADERS*)((DWORD)buffer + MS_DOS->e_lfanew);

// DO YOUR STUFF
// ...

delete[] buffer;
like image 28
IXSO Avatar answered Nov 15 '22 03:11

IXSO