头文件CpeUtil.h的内容:
#pragma once #include<Windows.h> class CPeUtil { public: CPeUtil(); ~CPeUtil(); BOOL LoadFile(const char* path); BOOL InitPeInfo(); void PrintSectionHeaders(); void GetExportTable(); private: char* fileBuff; DWORD FileSize; PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pNtHeader; PIMAGE_FILE_HEADER pFileHeader; PIMAGE_OPTIONAL_HEADER pOptionHeader; DWORD Rva2Foa(DWORD rva); };
源文件CPeUtil.cpp内容:
#include "CPeUtil.h" #include "stdio.h" CPeUtil::CPeUtil() { fileBuff = NULL; FileSize = 0; pDosHeader = NULL; pNtHeader = NULL;; pFileHeader = NULL; pOptionHeader = NULL; } CPeUtil::~CPeUtil() { if (NULL != fileBuff) { delete[] fileBuff; } } BOOL CPeUtil::LoadFile(const char* path) { HANDLE hFile = CreateFileA(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hFile == 0) { return FALSE; } FileSize = GetFileSize(hFile, 0); fileBuff = new char[FileSize] {0}; DWORD realReadBytes = 0; BOOL readSuccess = ReadFile(hFile, fileBuff, FileSize, &realReadBytes, 0); if (0 == readSuccess) { return FALSE; } if (this->InitPeInfo()) { return TRUE; } return FALSE; } BOOL CPeUtil::InitPeInfo() { pDosHeader = (PIMAGE_DOS_HEADER)fileBuff; if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { return FALSE; } pNtHeader = (PIMAGE_NT_HEADERS)(pDosHeader->e_lfanew + fileBuff); if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { return FALSE; } pFileHeader = &pNtHeader->FileHeader; pOptionHeader = &pNtHeader->OptionalHeader; return TRUE; } void CPeUtil::PrintSectionHeaders() { PIMAGE_SECTION_HEADER pSectionHeaders = IMAGE_FIRST_SECTION(pNtHeader); for (int i = 0; i < pFileHeader->NumberOfSections; ++i) { char name[9] = { 0 }; memcpy_s(name, 9, pSectionHeaders->Name, 8); printf("区段名称=%s ", name); pSectionHeaders++; } } ///< 解析导出表 void CPeUtil::GetExportTable() { IMAGE_DATA_DIRECTORY directory = pOptionHeader->DataDirectory[0]; ///< 得到导出表的位置 PIMAGE_EXPORT_DIRECTORY pexport = (PIMAGE_EXPORT_DIRECTORY)(Rva2Foa(directory.VirtualAddress) + fileBuff); char* dllName = Rva2Foa(pexport->Name) + fileBuff; printf("文件名称:%s ", dllName); DWORD * funcAddr = (DWORD*)(Rva2Foa(pexport->AddressOfFunctions) + fileBuff); WORD * peot = (WORD*)(Rva2Foa(pexport->AddressOfNameOrdinals) + fileBuff); ///<序号表的地址 DWORD * pent = (DWORD*)(Rva2Foa(pexport->AddressOfNames) + fileBuff); for (int i = 0; i < pexport->NumberOfFunctions; ++i) { printf("函数地址为:%x **** ", *funcAddr); for (int j = 0; j < pexport->NumberOfNames; ++j) { if (peot[j] == i) { char* funName =(char*)(Rva2Foa(pent[j]) + fileBuff); printf("函数名称为: %s ", funName); } } funcAddr++; } } DWORD CPeUtil::Rva2Foa(DWORD rva) { PIMAGE_SECTION_HEADER pSectionHeaders = IMAGE_FIRST_SECTION(pNtHeader); for (int i = 0; i < pFileHeader->NumberOfSections; ++i) { if (rva >= pSectionHeaders->VirtualAddress && rva < pSectionHeaders->VirtualAddress + pSectionHeaders->Misc.VirtualSize) { ///< FOA = 数据的RVA - 区段的RVA + 数据的FOA return rva - pSectionHeaders->VirtualAddress + pSectionHeaders->PointerToRawData; } pSectionHeaders++; } return 0; }
main.cpp的内容
#include<iostream> #include "CPeUtil.h" int main() { CPeUtil peUtil; BOOL success = peUtil.LoadFile("./7z.dll"); if (success) { //peUtil.PrintSectionHeaders(); peUtil.GetExportTable(); return 0; } printf("加载PE文件失败 "); return 0; }