PE总结9 --PE文件结构之 解析导出表

来源:互联网 发布:淘宝店铺美工 编辑:程序博客网 时间:2024/05/22 05:29
// 导出表2.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <windows.h>#include <stdlib.h>#include <stdlib.h>DWORD RVA2OffSet(DWORD dwRVA, PIMAGE_NT_HEADERS32  pNt){  DWORD dwOffset = 0;   //获取区段头表  PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNt);  //获取区段的数量  DWORD dwSize = pNt->FileHeader.NumberOfSections;  //遍历找到dwRVA所在的区段  for (DWORD i = 0; i < dwSize; i++)  {     if (dwRVA>=pSection[i].VirtualAddress  &&       dwRVA < (pSection[i].Misc.VirtualSize + pSection[i].VirtualAddress))     {       dwOffset = dwRVA - pSection[i].VirtualAddress + pSection[i].PointerToRawData;       return dwOffset;     }  }  return dwOffset;}void ShowExport(PVOID lpImage, DWORD dwSize){  //获取Dos头  PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage;  if (IMAGE_DOS_SIGNATURE != pDos->e_magic )  {     return;  }  //获取nt头  PIMAGE_NT_HEADERS32 pNt = (PIMAGE_NT_HEADERS32)((DWORD)lpImage + pDos->e_lfanew);  if (IMAGE_NT_SIGNATURE != pNt->Signature)  {     return;  }  //获取目录表  PIMAGE_DATA_DIRECTORY pData = pNt->OptionalHeader.DataDirectory;  //获取导出表RVA  pData = &(pData[IMAGE_DIRECTORY_ENTRY_EXPORT]);  //获取导出表在文件中的偏移  DWORD dwExtOffset = RVA2OffSet(pData->VirtualAddress, pNt);  PIMAGE_EXPORT_DIRECTORY pExpt = (PIMAGE_EXPORT_DIRECTORY)((DWORD)lpImage + dwExtOffset);  //获取数量  DWORD dwFunCount = pExpt->NumberOfFunctions;  DWORD dwNameCount = pExpt->NumberOfNames;  DWORD dwModName = pExpt->Name;  //获取地址表  PDWORD pEAT = (PDWORD)((DWORD)lpImage + RVA2OffSet(pExpt->AddressOfFunctions, pNt));  //获取名称表  PDWORD pENT = (PDWORD)((DWORD)lpImage +RVA2OffSet(pExpt->AddressOfNames, pNt));  //获取索引表-----这里要使用WORD  PWORD pEIT = (PWORD)((DWORD)lpImage + RVA2OffSet(pExpt->AddressOfNameOrdinals, pNt));  for (DWORD dwOrd = 0; dwOrd < dwFunCount; dwOrd++)  {   //这里如果没有的话是个NULL     if (!pEAT[dwOrd])     {       continue;     }     //获取函数的实际序号     DWORD dwID = pExpt->Base + dwOrd;     //获取导出函数地址值     DWORD dwFunOffset = RVA2OffSet(pEAT[dwOrd], pNt);     printf("函数序号: %08d RVA:%p  函数偏移:%p ",       dwID,       pEAT[dwOrd],       dwFunOffset);           //获取函数名     // 根据序号索引到函数名称表中的名字     for (DWORD dwIndex = 0; dwIndex < dwNameCount; dwIndex++)     {       // 在序号表中查找函数的序号<span style="font-family: Arial, Helvetica, sans-serif;">------------序号表的值 对应着 地址表的下标</span>       if (pEIT[dwIndex] == dwOrd)       {          // 根据序号索引到函数名称表中的名字          DWORD dwNameOffset = RVA2OffSet(pENT[dwIndex], pNt);          char* pFunName = (char*)((DWORD)lpImage + dwNameOffset);          printf("函数名称: %s\n",            pFunName);          continue;       }               }     printf("\n");  }  }int _tmain(int argc, _TCHAR* argv[]){  LPCTSTR path = L"C:\\Users\\Denny\\Desktop\\(手动查找导入导出表)\\(手动查找导入导出表)\\MFCLibrary1Dll.dll";  HANDLE hFile = nullptr;  if ( INVALID_HANDLE_VALUE == (hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL) ))  {     return 0;  }  DWORD dwSize = 0;  if ( INVALID_FILE_SIZE == (dwSize = GetFileSize(hFile, NULL)))  {     CloseHandle(hFile);     return 0;  }  PVOID lpFileImage = nullptr;  if (!(lpFileImage = VirtualAlloc(NULL, dwSize, MEM_COMMIT, PAGE_READWRITE)))  {     CloseHandle(hFile);     return 0;  }  DWORD dwRet = 0;  //将文件内容读取到内容空间  if (! ReadFile(hFile, lpFileImage, dwSize, &dwRet, NULL))  {     CloseHandle(hFile);     VirtualFree(lpFileImage, dwSize, MEM_RELEASE);     return 0;  }  ShowExport(lpFileImage, dwSize);  system("pause");  return 0;} 

0 0
原创粉丝点击