-
-
[原创]Pe解析总结
-
发表于: 2013-12-2 20:34 4196
-
前言
一个操作系统的可执行文件格式在很多方面是这个系统的一面镜子。虽然学习一个可执行文件格式通常不是一个程序员的首要任务,但是你可以从这其中学到大量的知识。在可预知的未来,包括, PE文件格式在 MicroSoft 的操作系统中扮演一个重要的角色。如果你在使用 Win32 或 Winnt ,那么你已经在使用 PE 文件了。甚至你只是在 Windows3.1 下使用 Visual C++编程,你使用的仍然是 PE 文件(Visual C++ 的 32 位扩展组件用这个格式)。简而言之,PE 格式已经普遍应用,并且在不短的将来仍是不可避免的。PE结构如此重要,我们可以通过写一个PE_EDIT 工具来理解pe文件,这是本文的目的(15pb项目)
总体设计
以简洁,直观的设计理念。我以树控件为主要控件,如下图:
当然,树控件总体展现能力强,具体数据展示能力比较弱。为了弥补这一缺陷,我加了右键菜单功能。鼠标点击树控件哪一项,来展示具体数据。
为了数据和界面分离,可以写个数据类,这里是CPeTool。所有的数据组织都在这个类里面,当然这个pe工具所有的逻辑都在这个类里面
class PeTool { private: MAP_FILE_STRUCT m_filestruct; public: vector<LPVOID> m_importVector; vector<DOSHEADER*> m_DosHeaderVector; vector<DOSHEADER*> m_FileHeaderVector; vector<DOSHEADER*> m_OptionHeaderVector; vector<SECTION*> m_SectionVector; vector<EXPORT_FUNC_DESCRIPTOR> m_ExportFucDecVector; vector<IMPORT_TABLE> m_ImportTableVector; IMAGE_IMPORT_DESCRIPTOR m_Image_Import; IMAGE_EXPORT_DIRECTORY m_Image_Export; DWORD m_exportOffset; bool m_isHasExport; bool m_isHaxImport; public: PeTool(); ~PeTool(); TREENODE* m_pHeadNode; TREENODE* m_pResourceHeadNode; bool LoadFile(LPSTR lpFileName); //是否为PE bool IsPe(); //我用的是树形框,构造树,初始化后,此数据初始化树形框 void CreateTree(); //创建资源数 void CreateResourceTree(); void AddNodeToResourceTree(TREENODE*,PIMAGE_RESOURCE_DIRECTORY,int depath); void PreAddNode(TREENODE*,int&); //释放空间 void DeleteTree(TREENODE*); //分析dosheader void DosHeaderAnalysis(); //分析Fileheader void FileHeaderAnalysis(); //分析Optionheader void OptionHeaderAnalysis(); //分析Section void SectionAnalysis(); //分析EXport_Table void ExportTableAnalysis(); //分析Import_table void ImportTableAnalysis(); //得到资源指针 DWORD GetResourceOffset(); PIMAGE_DOS_HEADER GetDosHeaderPt(); //地址转换 DWORD RSAtoOffset(DWORD); //得到NT指针 PIMAGE_NT_HEADERS GetNTheaderPt(); //得到数据目录地址 根据INDEX PIMAGE_DATA_DIRECTORY GetDataDirectoryEnty(int index); //得到第一个节的指针 PIMAGE_SECTION_HEADER GetFirstSectionHeader(); //地址转换 LPVOID RvaToOffet(LPVOID Rva); //得到可选头指针 PIMAGE_OPTIONAL_HEADER32 GetOptionHeader(); //得到文件头指针 PIMAGE_FILE_HEADER GetFileHeader(); };
/*********************************************************************/ /* 此函数最先调用 保存文件句柄,内存文件地址 */ bool PeTool::LoadFile(LPSTR lpFileName) { HANDLE hFile; HANDLE hMapping; LPVOID ImageBase; memset(&m_filestruct,0,sizeof(MAP_FILE_STRUCT)); hFile=CreateFile(lpFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0); if (!hFile) return false; hMapping=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL); if(!hMapping) { CloseHandle(hFile); return FALSE; } ImageBase=MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0); if(!ImageBase) { CloseHandle(hFile); CloseHandle(hMapping); return false; } m_filestruct.hFile=hFile; m_filestruct.hMapping=hMapping; m_filestruct.ImageBase=ImageBase; } /*********************************************************************/ /* 把pe内存文件地址转换成dos header pointer */ PIMAGE_DOS_HEADER PeTool::GetDosHeaderPt() { PIMAGE_DOS_HEADER pDosHeader; pDosHeader=(PIMAGE_DOS_HEADER)m_filestruct.ImageBase; return pDosHeader; } /*********************************************************************/ /* 根据 dos header 中的e_lfanew字段 求出文件的NT headers 的指针 */ PIMAGE_NT_HEADERS PeTool::GetNTheaderPt() { PIMAGE_DOS_HEADER pDosHeader=NULL; pDosHeader=GetDosHeaderPt(); PIMAGE_NT_HEADERS pNtHeader=NULL; pNtHeader=(PIMAGE_NT_HEADERS)(pDosHeader->e_lfanew+(DWORD)m_filestruct.ImageBase); return pNtHeader; } /*********************************************************************/ /* 根据NT header FileHeader 字段得出PIMAGE_FILE_HEADER */ PIMAGE_FILE_HEADER PeTool::GetFileHeader() { PIMAGE_NT_HEADERS pNTHeader; PIMAGE_FILE_HEADER pFileHeader; pNTHeader=GetNTheaderPt(); pFileHeader=&(pNTHeader->FileHeader); return pFileHeader; } /*********************************************************************/ /* 根据RVA 求出文件地址 */ LPVOID PeTool::RvaToOffet(LPVOID Rva) { PIMAGE_FILE_HEADER pFileHeader; // get file pointer of fileheader pFileHeader=GetFileHeader(); int NumberOfSections=0; NumberOfSections=pFileHeader->NumberOfSections; PIMAGE_SECTION_HEADER pSectionHeader; // get the first section pointer pSectionHeader=GetFirstSectionHeader(); for(int i=0;i<NumberOfSections;i++) { int virtualsize; DWORD VirtualAddress; virtualsize=pSectionHeader->Misc.VirtualSize; VirtualAddress=pSectionHeader->VirtualAddress; if((DWORD)Rva>=VirtualAddress&&(DWORD)Rva<(VirtualAddress+virtualsize)) { return LPVOID((DWORD)Rva-VirtualAddress+pSectionHeader->PointerToRawData+(DWORD)m_filestruct.ImageBase); } pSectionHeader++; } return 0; } /*********************************************************************/ /* 根据索引值求的相应数据的数据目录表 */ PIMAGE_DATA_DIRECTORY PeTool::GetDataDirectoryEnty(int index) { PIMAGE_OPTIONAL_HEADER pOptionHeader; pOptionHeader=GetOptionHeader(); return &(pOptionHeader->DataDirectory[index]); } /*********************************************************************/ /* 得到第一个节表的文件地址 */ PIMAGE_SECTION_HEADER PeTool::GetFirstSectionHeader() { PIMAGE_NT_HEADERS pNtH=NULL; PIMAGE_SECTION_HEADER pSH=NULL; pNtH=GetNTheaderPt(); pSH=IMAGE_FIRST_SECTION(pNtH); return pSH; } /*********************************************************************/ /* 得到OptionHeader 的文件地址 */ PIMAGE_OPTIONAL_HEADER32 PeTool::GetOptionHeader() { PIMAGE_NT_HEADERS pNTHeader; PIMAGE_OPTIONAL_HEADER pOptionalHeader; pNTHeader=GetNTheaderPt(); pOptionalHeader=&(pNTHeader->OptionalHeader); return pOptionalHeader; }
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏记录
参与人
雪币
留言
时间
心游尘世外
为你点赞~
2024-5-31 07:02
QinBeast
为你点赞~
2024-5-31 06:53
飘零丶
为你点赞~
2024-5-31 01:23
shinratensei
为你点赞~
2024-5-31 01:05
一笑人间万事
为你点赞~
2023-3-5 04:16
赞赏
看原图
赞赏
雪币:
留言: