获取PE文件的区段表,用的方法是,首先打开CreateFile,然后读取这个文件的DosHeader,
从DosHeader中取e_lfanew这个成员的值,这样就能知道“PE00”的偏移,然后SetFilePointer文件的指针
到e_lfanew + sizeof(IMAGE_NT_SIGNATURE)这个地址,读取FileHeader结构
,从文件头结构中获取NumberOfSections区段的个数,根据区段个数分配够用的缓冲区,
最后SetFilePointer将文件指针从当前位置偏移FileHeader.SizeOfOptionalHeader,进行读取IMAGE_SECTION_HEADER。
OK,搞定。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
//清空列表控件 m_ListCtrlSection.DeleteAllItems(); IMAGE_DOS_HEADER DosHeader = {0}; IMAGE_FILE_HEADER FileHeader = {0}; HANDLE hFile = INVALID_HANDLE_VALUE; DWORD dwReadLen = 0; WORD NumOfSec = 0; //区段表个数 IMAGE_SECTION_HEADER *pSecHeader = NULL; //打开文件 hFile = CreateFile("C://windows//system32//cmd.exe",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (hFile == INVALID_HANDLE_VALUE) { MessageBox(_T("无法打开文件,分析失败!")); return; } //读取数据 if (!ReadFile(hFile,&DosHeader,sizeof(DosHeader),&dwReadLen,NULL)) { MessageBox(_T("无法读取文件,分析失败!")); return; } SetFilePointer(hFile,DosHeader.e_lfanew + sizeof(IMAGE_NT_SIGNATURE),NULL,FILE_BEGIN); ReadFile(hFile,&FileHeader,sizeof(FileHeader),&dwReadLen,NULL); //得出区段个数 NumOfSec = FileHeader.NumberOfSections; //分配区段内存 DWORD SectionSize = NumOfSec * IMAGE_SIZEOF_SECTION_HEADER; char *pSecBuff = new char[SectionSize + 1]; //移动指针到区段表 SetFilePointer(hFile,FileHeader.SizeOfOptionalHeader,NULL,FILE_CURRENT); ReadFile(hFile,pSecBuff,SectionSize,&dwReadLen,NULL); //读取完毕,关闭句柄 CloseHandle(hFile); int iIndexItem = 0; TCHAR tzBuff[10] = {0}; char szSecName[IMAGE_SIZEOF_SHORT_NAME] = {0}; //内存数据指针转换 pSecHeader = (PIMAGE_SECTION_HEADER)pSecBuff; for (int i = 0; i < NumOfSec; i++) { memcpy(szSecName,pSecHeader->Name,8); iIndexItem = m_ListCtrlSection.InsertItem(i,(LPCTSTR)szSecName); //显示VirtualAddress和VirtualSize wsprintf(tzBuff,_T("%08X"),pSecHeader->VirtualAddress); m_ListCtrlSection.SetItemText(iIndexItem,1,tzBuff); wsprintf(tzBuff,_T("%08X"),pSecHeader->Misc.VirtualSize); m_ListCtrlSection.SetItemText(iIndexItem,2,tzBuff); //显示RawAddress和RawData wsprintf(tzBuff,_T("%08X"),pSecHeader->PointerToRawData); m_ListCtrlSection.SetItemText(iIndexItem,3,tzBuff); wsprintf(tzBuff,_T("%08X"),pSecHeader->SizeOfRawData); m_ListCtrlSection.SetItemText(iIndexItem,4,tzBuff); wsprintf(tzBuff,_T("%08X"),pSecHeader->Characteristics); m_ListCtrlSection.SetItemText(iIndexItem,5,tzBuff); //指针后移 pSecHeader++; } //释放内存 if (pSecBuff) { delete []pSecBuff; } |
转载请注明:exchen's blog » 获取 PE 文件的区段表