简单PE类代码

三个文件分别是类定义文件pefile.h;类实现文件pefile.cpp;类调用文件petype.cpp.
#ifndef PE_FILE_H
#define PE_FILE_H
#include "windows.h"

#define ISMZHEADER            (*(WORD*)File_memory == 0x5a4d)
#define ISPEHEADER            (*(WORD*)((BYTE*)File_memory + *(DWORD*)((BYTE*)File_memory + 0x3c)) == 0x4550)
#define ISPE32MAGIC            (*(WORD*)((BYTE*)File_memory + *(DWORD*)((BYTE*)File_memory + 0x3c) + sizeof(IMAGE_FILE_HEADER) + 4) == 0x10b)
#define ISPE64MAGIC            (*(WORD*)((BYTE*)File_memory + *(DWORD*)((BYTE*)File_memory + 0x3c) + sizeof(IMAGE_FILE_HEADER) + 4) == 0x20b)
#define ISPEROMMAGIC        (*(WORD*)((BYTE*)File_memory + *(DWORD*)((BYTE*)File_memory + 0x3c) + sizeof(IMAGE_FILE_HEADER) + 4) == 0x107)


#define X_PE_32                32
#define X_PE_64                64

#define    READ_ERRO            0x0
#define    NOT_PE_FILE            0x200
#define    PE_FILE                0x100
#define    PE64_FILE            0x40
#define    PE32_FILE            0x20
#define    ROM_IMAGE            0x10
#define    EXE_FILE            0x8
#define    DLL_FILE            0x4
#define    SYS_FILE            0x2
#define    OTHER_FILE            0x1

typedef struct X_IMAGE_NT_HEADERS32 {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} MX_IMAGE_NT_HEADERS32;

typedef struct X_IMAGE_NT_HEADERS64 {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} MX_IMAGE_NT_HEADERS64;

typedef struct X_IMAGE_NT_HEADERS {
    DWORD systembit;
    union {
        MX_IMAGE_NT_HEADERS32* Ntheader32;
        MX_IMAGE_NT_HEADERS64* Ntheader64;
    };
} MX_IMAGE_NT_HEADERS;

typedef struct X_IMPORT_FUNCTION {
    union{
        DWORD Flag32;
        UINT64 Flag64;
    }uf;
    union {
        DWORD* FunOrdinal32;
        UINT64* FunOrdinal64;
        char* FunName;
    }ud;
} MX_IMPORT_FUNCTION;

typedef struct X_EXPORT_FUNCTION {
    DWORD Flag;
    union {
        DWORD FunOrdinal;
        char* FunName;
    }ud;
} MX_EXPORT_FUNCTION;

typedef struct X_RESOURCE_TYPE {
    DWORD Flag;
    union {
        DWORD ResourceID;
        char* ResourceName;
    }u;
} MX_RESOURCE_TYPE;


class XPEFILE
{
public:
    XPEFILE(char* lpFileName);
    virtual ~XPEFILE();
    int GetType();
    int GetSize();
    IMAGE_DOS_HEADER* GetDosHeader();
    IMAGE_FILE_HEADER* GetFileHeader();
    VOID GetNTHeader(MX_IMAGE_NT_HEADERS* ntheader);
    IMAGE_SECTION_HEADER* GetSectionInfo();
    int Rva2Raw(DWORD* lpaddress);
    int Raw2Rva(DWORD* lpaddress);
    int CheckImportDll(char* dllname);
    int CheckImportFun(char* dllname, MX_IMPORT_FUNCTION* importfun);
    int CheckExportFun(MX_EXPORT_FUNCTION* exportfun);
    IMAGE_RESOURCE_DATA_ENTRY* GetFileResource(MX_RESOURCE_TYPE* resourcetype1, MX_RESOURCE_TYPE* resourcetype2);
    

private:
    void* File_memory;
    int File_size;
    int File_type;
};

#endif
pefile.h
#include "stdafx.h"
#include "windows.h"
#include "pefile.h"
#include "winnls.h"

XPEFILE::XPEFILE(char* strFileName)
{
    HANDLE hfile;
    unsigned long sizehigh;
    void* lpmemory;

    File_memory = NULL;
    File_type = READ_ERRO;

    hfile = CreateFile(strFileName, GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0);
    if (hfile != INVALID_HANDLE_VALUE)
    {
        File_size = GetFileSize(hfile, &sizehigh);
        lpmemory = LocalAlloc(LPTR,File_size);
        if(ReadFile(hfile,lpmemory,File_size,&sizehigh,0) != NULL)
        {
            File_memory = lpmemory;
        }
        CloseHandle(hfile);
    }
}

XPEFILE::~XPEFILE()
{
    if (File_memory == NULL)
    {
        LocalFree(File_memory);
    }
}

int XPEFILE::GetSize()
{
    return File_size;
}

int XPEFILE::GetType()
{
    MX_IMAGE_NT_HEADERS32* ntheader32;
    MX_IMAGE_NT_HEADERS64* ntheader64;

    File_type = READ_ERRO;

    if (File_memory == NULL)
    {
        return File_type;
    }
    File_type = NOT_PE_FILE;
    if(ISMZHEADER && ISPEHEADER)
    {
        File_type = PE_FILE;
    }
    if (File_type == PE_FILE)
    {
        if (ISPE32MAGIC)
        {
            File_type = File_type | PE32_FILE;
            ntheader32 = (MX_IMAGE_NT_HEADERS32*) ((BYTE*)File_memory + *(DWORD*)((BYTE*)File_memory + 0x3c));
            if (ntheader32->FileHeader.Characteristics & IMAGE_FILE_DLL)
            {
                File_type = File_type | DLL_FILE;
            }
            else if ((ntheader32->OptionalHeader.Subsystem & IMAGE_SUBSYSTEM_WINDOWS_CUI)||(ntheader32->OptionalHeader.Subsystem & IMAGE_SUBSYSTEM_WINDOWS_GUI))
            {
                File_type = File_type | EXE_FILE;
            }
            else if ((ntheader32->OptionalHeader.Subsystem & IMAGE_SUBSYSTEM_NATIVE)||(ntheader32->OptionalHeader.Subsystem & IMAGE_SUBSYSTEM_NATIVE_WINDOWS))
            {
                File_type = File_type | SYS_FILE;
            }
        }
        if (ISPE64MAGIC)
        {
            File_type = File_type | PE64_FILE;
            ntheader64 = (MX_IMAGE_NT_HEADERS64*) ((BYTE*)File_memory + *(DWORD*)((BYTE*)File_memory + 0x3c));
            if (ntheader64->FileHeader.Characteristics & IMAGE_FILE_DLL)
            {
                File_type = File_type | DLL_FILE;
            }
            else if ((ntheader64->OptionalHeader.Subsystem & IMAGE_SUBSYSTEM_WINDOWS_CUI)|(ntheader64->OptionalHeader.Subsystem & IMAGE_SUBSYSTEM_WINDOWS_GUI))
            {
                File_type = File_type | EXE_FILE;
            }
            else if ((ntheader32->OptionalHeader.Subsystem & IMAGE_SUBSYSTEM_NATIVE)||(ntheader32->OptionalHeader.Subsystem & IMAGE_SUBSYSTEM_NATIVE_WINDOWS))
            {
                File_type = File_type | SYS_FILE;
            }
        }
        if (ISPEROMMAGIC)
        {
            File_type = File_type | ROM_IMAGE;
        }
    }
    return  File_type;
}

IMAGE_DOS_HEADER* XPEFILE::GetDosHeader()
{
    IMAGE_DOS_HEADER* dosheader;
    if (ISMZHEADER && ISPEHEADER)
    {
        dosheader = (IMAGE_DOS_HEADER*) File_memory;
        return dosheader;
    }
    return NULL;
}

VOID XPEFILE::GetNTHeader(MX_IMAGE_NT_HEADERS* ntheader)
{
    if (ISMZHEADER && ISPEHEADER && ISPE32MAGIC)
    {
        ntheader->systembit = X_PE_32;
        ntheader->Ntheader32 = (MX_IMAGE_NT_HEADERS32*) ((BYTE*)File_memory + *(DWORD*)((BYTE*)File_memory + 0x3c));
    }
    else if (ISMZHEADER && ISPEHEADER && ISPE64MAGIC)
    {
        ntheader->systembit = X_PE_64;
        ntheader->Ntheader64 = (MX_IMAGE_NT_HEADERS64*) ((BYTE*)File_memory + *(DWORD*)((BYTE*)File_memory + 0x3c));
    }
    else
    {
        ntheader->systembit = NULL;
    }
}

IMAGE_SECTION_HEADER* XPEFILE::GetSectionInfo()
{
    IMAGE_SECTION_HEADER* sectioninfo;
    MX_IMAGE_NT_HEADERS32* ntheader32;
    MX_IMAGE_NT_HEADERS64* ntheader64;

    if (ISMZHEADER && ISPEHEADER && ISPE32MAGIC)
    {
        ntheader32 = (MX_IMAGE_NT_HEADERS32*) ((BYTE*)File_memory + *(DWORD*)((BYTE*)File_memory + 0x3c));
        sectioninfo = (IMAGE_SECTION_HEADER*)((BYTE*)ntheader32 + sizeof(ntheader32->Signature) + ntheader32->FileHeader.SizeOfOptionalHeader + sizeof(ntheader32->FileHeader));
        return sectioninfo;
    }    
    if (ISMZHEADER && ISPEHEADER && ISPE64MAGIC)
    {
        ntheader64 = (MX_IMAGE_NT_HEADERS64*) ((BYTE*)File_memory + *(DWORD*)((BYTE*)File_memory + 0x3c));
        sectioninfo = (IMAGE_SECTION_HEADER*)((BYTE*)ntheader64 + sizeof(ntheader64->Signature) + ntheader64->FileHeader.SizeOfOptionalHeader + sizeof(ntheader64->FileHeader));
        return sectioninfo;
    }
    return NULL;
}

IMAGE_FILE_HEADER* XPEFILE::GetFileHeader()
{
    if (ISMZHEADER && ISPEHEADER)
    {
        return (IMAGE_FILE_HEADER*)((BYTE*)File_memory + *(DWORD*)((BYTE*)File_memory + 0x3c) +4);
    }
    else
    {
        return NULL;
    }
}

int XPEFILE::Rva2Raw(DWORD* lpaddress)
{
    IMAGE_FILE_HEADER* fileheader;
    IMAGE_SECTION_HEADER* sectionheader;
    int numberofsection, secnumber1, notinsection;
    
    notinsection = 1;
    secnumber1 = 0;
    sectionheader = GetSectionInfo();
    fileheader = GetFileHeader();
    numberofsection = fileheader->NumberOfSections;
    while (secnumber1 < numberofsection)
    {
        if((sectionheader[secnumber1].VirtualAddress <= *lpaddress) && ((sectionheader[secnumber1].VirtualAddress + sectionheader[secnumber1].Misc.VirtualSize) > *lpaddress))
        {
            *lpaddress = (*lpaddress - sectionheader[secnumber1].VirtualAddress + sectionheader[secnumber1].PointerToRawData);
            if ((sectionheader[secnumber1].PointerToRawData <= *lpaddress) && ((sectionheader[secnumber1].PointerToRawData + sectionheader[secnumber1].SizeOfRawData) > *lpaddress))
            {
                notinsection = 0;
                secnumber1 += numberofsection;
            }
        }
        secnumber1++;
    }
    if (notinsection)
    {
        return 0;
    }
    return (secnumber1 - numberofsection);
}

int XPEFILE::Raw2Rva(DWORD* lpaddress)
{
    IMAGE_FILE_HEADER* fileheader;
    IMAGE_SECTION_HEADER* sectionheader;
    int numberofsection, secnumber1, notinsection;
    
    notinsection = 1;
    secnumber1 = 0;
    sectionheader = GetSectionInfo();
    fileheader = GetFileHeader();
    numberofsection = fileheader->NumberOfSections;
    while (secnumber1 < numberofsection)
    {
        if((sectionheader[secnumber1].PointerToRawData <= *lpaddress) && ((sectionheader[secnumber1].PointerToRawData + sectionheader[secnumber1].SizeOfRawData) > *lpaddress))
        {
            *lpaddress = (*lpaddress - sectionheader[secnumber1].PointerToRawData + sectionheader[secnumber1].VirtualAddress);
            if ((sectionheader[secnumber1].VirtualAddress <= *lpaddress) && ((sectionheader[secnumber1].VirtualAddress + sectionheader[secnumber1].Misc.VirtualSize) > *lpaddress))
            {
                notinsection = 0;
                secnumber1 += numberofsection;
            }
        }
        secnumber1++;
    }
    if (notinsection)
    {
        return 0;
    }
    return (secnumber1 - numberofsection);
}

int XPEFILE::CheckImportDll(char* dllname)
{
    MX_IMAGE_NT_HEADERS* ntheader;
    ntheader = new MX_IMAGE_NT_HEADERS;
    DWORD importaddress;
    int sectionnumber;
    IMAGE_IMPORT_DESCRIPTOR* importdesc;
    int returnvalue;

    
    returnvalue = 0;
    GetNTHeader(ntheader);
    if (ntheader->systembit == X_PE_32)
    {
        importaddress = ntheader->Ntheader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
        sectionnumber = Rva2Raw(&importaddress);
        if (sectionnumber)
        {
            importdesc = (IMAGE_IMPORT_DESCRIPTOR*) (importaddress + (BYTE*)File_memory);
            while(importdesc->Characteristics||importdesc->FirstThunk||importdesc->ForwarderChain||importdesc->Name||importdesc->TimeDateStamp)
            {
                DWORD namerva = (importdesc->Name);
                if (Rva2Raw(&namerva))
                {
                    char* b = (char*)(namerva + (BYTE*)File_memory);
                    if (!(stricmp((char*)(namerva + (BYTE*)File_memory) , dllname)))
                    {
                        returnvalue = 1;
                        break;
                    }
                }
                importdesc += 1;                
            }
        }
    }
    else if (ntheader->systembit == X_PE_64)
    {
        importaddress = ntheader->Ntheader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
        sectionnumber = Rva2Raw(&importaddress);
        if (sectionnumber)
        {
            importdesc = (IMAGE_IMPORT_DESCRIPTOR*) (importaddress + (BYTE*)File_memory);
            while(importdesc->Characteristics||importdesc->FirstThunk||importdesc->ForwarderChain||importdesc->Name||importdesc->TimeDateStamp)
            {
                DWORD namerva = (importdesc->Name);
                if (Rva2Raw(&namerva))
                {
                    if (!(stricmp((char*)(namerva + (BYTE*)File_memory) , dllname)))
                    {
                        returnvalue = 1;
                        break;
                    }
                }
                importdesc += 1;                
            }
        }

    }
    return returnvalue;
}


int XPEFILE::CheckImportFun(char* dllname, MX_IMPORT_FUNCTION* importfun)
{
    MX_IMAGE_NT_HEADERS* ntheader;
    ntheader = new MX_IMAGE_NT_HEADERS;
    DWORD importaddress;
    int sectionnumber;
    IMAGE_IMPORT_DESCRIPTOR* importdesc;
    IMAGE_THUNK_DATA32* data32;
    IMAGE_THUNK_DATA64* data64;
    IMAGE_IMPORT_BY_NAME* funname;
    DWORD funoridinal;
    UINT64 funoridinal64;
    int returnvalue;
    
    
    returnvalue = 0;
    GetNTHeader(ntheader);
    if (ntheader->systembit == X_PE_32)
    {
        importaddress = ntheader->Ntheader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
        sectionnumber = Rva2Raw(&importaddress);
        if (sectionnumber)
        {
            importdesc = (IMAGE_IMPORT_DESCRIPTOR*) (importaddress + (BYTE*)File_memory);
            while(importdesc->Characteristics||importdesc->FirstThunk||importdesc->ForwarderChain||importdesc->Name||importdesc->TimeDateStamp)
            {
                if (returnvalue == 1) break;
                DWORD namerva = (importdesc->Name);
                if (Rva2Raw(&namerva))
                {
                    if (!(stricmp((char*)(namerva + (BYTE*)File_memory) , dllname)))
                    {
//                        returnvalue = 2;
                        DWORD data32rva = importdesc->OriginalFirstThunk;
                        if (!Rva2Raw(&data32rva)) continue;
                        data32 = (IMAGE_THUNK_DATA32*)(data32rva + (BYTE*)File_memory);
                        while (data32->u1.Ordinal)
                        {    
                            funoridinal = data32->u1.Ordinal;
                            if ((funoridinal & 0x80000000) != importfun->uf.Flag32)
                            {
                                data32 += 1;
                                continue;
                            }
                            funoridinal = data32->u1.Ordinal;
                            if ((funoridinal & 0x80000000) == 0x80000000)
                            {
                                funoridinal = data32->u1.Ordinal;
                                funoridinal = funoridinal &0x7fffffff;                                
                                if (funoridinal == *(DWORD*)importfun->ud.FunOrdinal32)
                                {
                                    returnvalue = 1;
                                    break;
                                }
                                data32 += 1;
                                continue;
                            }
                            else
                            {
                                DWORD funnamerva =(DWORD) data32->u1.AddressOfData;
                                if (Rva2Raw(&funnamerva))
                                {
                                    funname = (IMAGE_IMPORT_BY_NAME*)(funnamerva + (BYTE*)File_memory);
                                    if (!(stricmp((char*)funname->Name , importfun->ud.FunName)))
                                    {
                                        returnvalue = 1;
                                        break;
                                    }
                                }
                                data32 += 1;
                                continue;
                            }
                        }
                        break;
                    }
                }
                importdesc += 1;                
            }
        }
    }
    else if (ntheader->systembit == X_PE_64)
    {
        importaddress = ntheader->Ntheader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
        sectionnumber = Rva2Raw(&importaddress);
        if (sectionnumber)
        {
            importdesc = (IMAGE_IMPORT_DESCRIPTOR*) (importaddress + (BYTE*)File_memory);
            while(importdesc->Characteristics||importdesc->FirstThunk||importdesc->ForwarderChain||importdesc->Name||importdesc->TimeDateStamp)
            {
                if (returnvalue == 1) break;
                DWORD namerva = (importdesc->Name);
                if (Rva2Raw(&namerva))
                {
                    char* aa = (char*)(namerva + (BYTE*)File_memory);
                    if (!(stricmp((char*)(namerva + (BYTE*)File_memory) , dllname)))
                    {
//                        returnvalue = 2;
                        DWORD data64rva = importdesc->OriginalFirstThunk;
                        if (!Rva2Raw(&data64rva)) continue;
                        data64 = (IMAGE_THUNK_DATA64*)(data64rva + (BYTE*)File_memory);
                        while (data64->u1.Ordinal)
                        {    
                            funoridinal64 = data64->u1.Ordinal;
                            if ((funoridinal64 & 0x8000000000000000) != importfun->uf.Flag64)
                            {
                                data64 += 1;
                                continue;
                            }
                            funoridinal64 = data64->u1.Ordinal;
                            if ((funoridinal64 & 0x8000000000000000) == 0x8000000000000000)
                            {
                                funoridinal64 = data64->u1.Ordinal;
                                funoridinal64 = funoridinal64 &0x7fffffffffffffff;                                
                                if (funoridinal64 == *(UINT64*)importfun->ud.FunOrdinal64)
                                {
                                    returnvalue = 1;
                                    break;
                                }
                                data64 += 1;
                                continue;
                            }
                            else
                            {
                                DWORD funnamerva =(DWORD) data64->u1.AddressOfData;
                                if (Rva2Raw(&funnamerva))
                                {
                                    funname = (IMAGE_IMPORT_BY_NAME*)(funnamerva + (BYTE*)File_memory);
                                    if (!(stricmp((char*)funname->Name , importfun->ud.FunName)))
                                    {
                                        returnvalue = 1;
                                        break;
                                    }
                                }
                                data64 += 1;
                                continue;
                            }
                        }
                        break;
                    }
                }
                importdesc += 1;                
            }
        }

    }
    return returnvalue;
}


int XPEFILE::CheckExportFun(MX_EXPORT_FUNCTION* exportfun)
{
    MX_IMAGE_NT_HEADERS* ntheader;
    ntheader = new MX_IMAGE_NT_HEADERS;
    IMAGE_EXPORT_DIRECTORY* exportdir;

    GetNTHeader(ntheader);
    exportdir = NULL;
    if (ntheader->systembit == X_PE_32)
    {
        DWORD namerva = (ntheader->Ntheader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
        DWORD namesize = (ntheader->Ntheader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);
        if ((namerva == 0)&&(namesize == 0)) return false;
        if (Rva2Raw(&namerva))
        {
            exportdir = (IMAGE_EXPORT_DIRECTORY*)(namerva + (BYTE*)File_memory);
        }
    }
    else if (ntheader->systembit == X_PE_64)
    {
        DWORD namerva = (ntheader->Ntheader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
        DWORD namesize = (ntheader->Ntheader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);
        if ((namerva == 0) &&(namesize == 0)) return false;
        if (Rva2Raw(&namerva))
        {
            exportdir = (IMAGE_EXPORT_DIRECTORY*)(namerva + (BYTE*)File_memory);
        }
    }
    if (exportfun->Flag == 1)
    {
        if ((exportfun->ud.FunOrdinal >= exportdir->Base) && (exportfun->ud.FunOrdinal <= exportdir->NumberOfFunctions + exportdir->Base))
        {
            return true;
        }
        return false;
    }
    if (exportfun->Flag == 0)
    {
        
        DWORD funnamerva = exportdir->AddressOfNames;
        if (Rva2Raw(&funnamerva))
        {
            DWORD* funnamelistrva = (DWORD*)(funnamerva + (BYTE*)File_memory);
            for (UINT i = 0; i < exportdir->NumberOfFunctions ; i++)
            {
                DWORD namerva = funnamelistrva[i];
                if (Rva2Raw(&namerva))
                {
                    char* funname = (char*)(namerva + (BYTE*)File_memory);
                    if (!(stricmp(funname , exportfun->ud.FunName)))
                    {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

IMAGE_RESOURCE_DATA_ENTRY* XPEFILE::GetFileResource(MX_RESOURCE_TYPE* resourcetype1, MX_RESOURCE_TYPE* resourcetype2)
{
    IMAGE_RESOURCE_DATA_ENTRY* resourcedata;
    MX_IMAGE_NT_HEADERS* ntheader;
    ntheader = new MX_IMAGE_NT_HEADERS;
    IMAGE_RESOURCE_DIRECTORY* resourcebase;
    IMAGE_RESOURCE_DIRECTORY* resourcedir;
    char str[256];
    char* funnamestr = str;

    GetNTHeader(ntheader);
    //获取文件的ntheader,需要对ntheader判断其是32位还是64位pe
    if (ntheader->systembit == X_PE_32)
    {
        DWORD resourcerva= (ntheader->Ntheader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
        DWORD resourcesize = (ntheader->Ntheader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
        if ((resourcerva == 0)&&(resourcesize == 0)) return false;
        if (Rva2Raw(&resourcerva))
        {
            resourcebase = (IMAGE_RESOURCE_DIRECTORY*)(resourcerva + (BYTE*)File_memory);
        }
    }
    //计算32位pe文件的资源基址
    else if (ntheader->systembit == X_PE_64)
    {
        DWORD resourcerva = (ntheader->Ntheader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
        DWORD resourcesize = (ntheader->Ntheader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
        if ((resourcerva == 0) &&(resourcesize == 0)) return false;
        if (Rva2Raw(&resourcerva))
        {
            resourcebase = (IMAGE_RESOURCE_DIRECTORY*)(resourcerva + (BYTE*)File_memory);
        }
    }
    //计算64位pe文件的资源基址
    resourcedir = resourcebase;
    if (!resourcedir) return NULL;
    //以上代码分win32和win64两种情况分别获取文件可选头中数据目录表中的资源项数据,判断其不为空。
    //返回的是资源数据的raw起始地址resourcebase
    
    DWORD resourcenum = resourcedir->NumberOfIdEntries + resourcedir->NumberOfNamedEntries;
    IMAGE_RESOURCE_DIRECTORY_ENTRY* resourcedirentry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)((BYTE*)resourcedir + sizeof(IMAGE_RESOURCE_DIRECTORY));
    DWORD dataoffset = 0;
    for (UINT i = 0; i < resourcenum; i++)
    {
        if (resourcetype1->Flag == (resourcedirentry->Name & 0x80000000))
        {
            if (resourcetype1->Flag == 0x0)
            {
                //是通过id调用
                if (resourcetype1->u.ResourceID == resourcedirentry->Name)
                {
                    //是要获取的资源类型
                    dataoffset = resourcedirentry->OffsetToData;
                    break;
                }
            }
            else if (resourcetype1->Flag == 0x80000000)
            {
                //是通过名字调用
                IMAGE_RESOURCE_DIR_STRING_U* resourcetypename = (IMAGE_RESOURCE_DIR_STRING_U*)((BYTE*)resourcedir + (resourcedirentry->Name & 0x7FFFFFFF));
                memset(funnamestr,0x0,0x100);
                WideCharToMultiByte(CP_ACP,NULL,resourcetypename->NameString,resourcetypename->Length,funnamestr,0x255,0,0);
                if (!stricmp(resourcetype1->u.ResourceName, funnamestr))
                {
                    //是要获取的资源类型
                    dataoffset = resourcedirentry->OffsetToData;
                    break;
                }
            }
        }
        resourcedirentry += 1;
    }
    if (!dataoffset) return NULL;
    //以上部分是匹配资源的第一级目录中也就是资源的type是否为需要获取的type,返回的数据为资源目录项指针IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData

    if (!(dataoffset & 0x80000000)) return NULL;
    //如果二级目录就是数据,不符合资源的层级结构,目前也没有发现有此类资源结构,直接返回null。
    if (dataoffset & 0x80000000)
    {
        resourcedir = (IMAGE_RESOURCE_DIRECTORY*)((unsigned char*)resourcebase + (dataoffset & 0x7fffffff));
        resourcenum = resourcedir->NumberOfIdEntries + resourcedir->NumberOfNamedEntries;
        resourcedirentry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)((BYTE*)resourcedir + sizeof(IMAGE_RESOURCE_DIRECTORY));
        dataoffset = 0;
        for (UINT i = 0; i < resourcenum; i++)
        {
            if (resourcetype2->Flag == (resourcedirentry->Name & 0x80000000))
            {
                if (resourcetype2->Flag == 0x0)
                {
                    //是通过id调用
                    if (resourcetype2->u.ResourceID == resourcedirentry->Name)
                    {
                        //是要获取的资源id
                        dataoffset = resourcedirentry->OffsetToData;
                        break;
                    }
                }
                else if (resourcetype2->Flag == 0x80000000)
                {
                    //是通过名字调用
                    IMAGE_RESOURCE_DIR_STRING_U* resourcetypename = (IMAGE_RESOURCE_DIR_STRING_U*)((BYTE*)resourcedir + (resourcedirentry->Name & 0x7FFFFFFF));
                    memset(funnamestr,0x0,0x100);
                    WideCharToMultiByte(CP_ACP,NULL,resourcetypename->NameString,resourcetypename->Length,funnamestr,0x255,0,0);
                    if (!stricmp(resourcetype2->u.ResourceName, funnamestr))
                    {
                        //是要获取的资源id
                        dataoffset = resourcedirentry->OffsetToData;
                        break;
                    }
                }
            }
        resourcedirentry += 1;
        }
    }
    //以上部分是匹配资源的第二级目录中也就是资源的id是否为需要获取的id,返回的数据为资源目录项指针IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData

    if (!(dataoffset & 0x80000000)) return NULL;
    //如果三级目录就是数据,不符合资源的层级结构,目前也没有发现有此类资源结构,直接返回null。
    if (dataoffset & 0x80000000)
    {
        resourcedir = (IMAGE_RESOURCE_DIRECTORY*)((unsigned char*)resourcebase + (dataoffset & 0x7fffffff));
        resourcenum = resourcedir->NumberOfIdEntries + resourcedir->NumberOfNamedEntries;
        if (resourcenum != 1) return NULL;
        IMAGE_RESOURCE_DIRECTORY_ENTRY* resourcedirentry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)((BYTE*)resourcedir + sizeof(IMAGE_RESOURCE_DIRECTORY));
        dataoffset = resourcedirentry->OffsetToData;
    }
    //以上部分是从第三级目录中读取第四级结构的偏移

    if ((dataoffset & 0x80000000)) return NULL;
    //如果第四级不是数据,不符合资源的层级结构,目前也没有发现有此类资源结构,直接返回null。
    resourcedata = (IMAGE_RESOURCE_DATA_ENTRY*)((unsigned char*)resourcebase + dataoffset);
    return resourcedata;
    //返回要获取的资源数据的数据结构
}
pefile.cpp
// TEST.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "pefile.h"
#include <iostream>
 
int main(int argc, char* argv[])
{
    int filetype;
    IMAGE_DOS_HEADER* dosheader;
    MX_IMAGE_NT_HEADERS* ntheader;    
    IMAGE_SECTION_HEADER* sectioninfo;
    DWORD address;
    int a,b,c,d,e;
    
    ntheader = new MX_IMAGE_NT_HEADERS;
    address = 0x39000;

    char* file = "c:\64.exe";
    char* dllname = "kernel32.dll";
    char* funname = "CreateFileA";
    MX_IMPORT_FUNCTION* impfun;
    impfun = new MX_IMPORT_FUNCTION;
    impfun->uf.Flag64 = 0;
    impfun->ud.FunName = funname;
    MX_EXPORT_FUNCTION* expfun;
    expfun = new MX_EXPORT_FUNCTION;
    expfun->Flag = 0;
    expfun->ud.FunName = funname;
    MX_RESOURCE_TYPE* resourcetype1;
    MX_RESOURCE_TYPE* resourcetype2;
    char* rtypename = "KERNEL";

    IMAGE_RESOURCE_DATA_ENTRY* resoursedataentry;
    resourcetype1 = new MX_RESOURCE_TYPE;
    resourcetype2 = new MX_RESOURCE_TYPE;

    resourcetype1->Flag = 0x80000000;
    resourcetype1->u.ResourceName = rtypename;

    resourcetype2->Flag = 0x0;
    resourcetype2->u.ResourceID = 231;

    XPEFILE pefile1(file);
    
    filetype = pefile1.GetType();
    dosheader = pefile1.GetDosHeader();
    pefile1.GetNTHeader(ntheader);
    sectioninfo = pefile1.GetSectionInfo();

    a=pefile1.Raw2Rva(&address);
    b=pefile1.Rva2Raw(&address);
    c=pefile1.CheckImportDll(dllname);
    d=pefile1.CheckImportFun(dllname, impfun);
    e=pefile1.CheckExportFun(expfun);

    resoursedataentry = pefile1.GetFileResource(resourcetype1, resourcetype2);

    system("pause");
    return 0;
}
petype.cpp
原文地址:https://www.cnblogs.com/Mikhail/p/4509113.html