简单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
#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; //返回要获取的资源数据的数据结构 }
// 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; }