VC PE導出/輸入表演示(讀文件版)

// GetPeTable.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "stdio.h"

VOID PrintImportTable(LPSTR strPath);
VOID PrintExportTable(LPSTR strPath);
ULONG muVAddr=0,muPAddr=0;
int main(int argc, char* argv[])
{
 if (argc==1)
  return 0;
 printf("導出表信息:/n/n");
 PrintExportTable(argv[1]);
 printf("/n");
 printf("----------------------------------------------/n/n");
 printf("輸入表信息:/n/n");
 PrintImportTable(argv[1]);
 return 0;
}

//獲取虛擬地址在文件中的偏移
DWORD RvaToOffset(PIMAGE_SECTION_HEADER pSectionHeader,int intNumOfSections,DWORD VirtualAddress)
{
 int i=0;
 DWORD dwAposRAV=0;
 DWORD dwOffset=0;
 for (i=0;i<intNumOfSections;i++)
 {
  if(VirtualAddress >= pSectionHeader->VirtualAddress &&
   VirtualAddress < pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize) 
  {
   dwAposRAV=VirtualAddress-pSectionHeader->VirtualAddress;
   dwOffset=pSectionHeader->PointerToRawData+dwAposRAV;
   return dwOffset;
  }
  pSectionHeader++;
 }
 return VirtualAddress;
}

//文件中的偏移轉換虛擬地址
DWORD OffsetToRva(PIMAGE_SECTION_HEADER pSectionHeader,int intNumOfSections,DWORD FileOffset)
{
 int i=0;
 DWORD dwAposOffset=0;
 DWORD dwRAV=0;
 for (i=0;i<intNumOfSections;i++)
 {
  if(FileOffset >= pSectionHeader->PointerToRawData &&
   FileOffset < pSectionHeader->PointerToRawData + pSectionHeader->SizeOfRawData) 
  {
   dwAposOffset=FileOffset-pSectionHeader->PointerToRawData;
   dwRAV=pSectionHeader->VirtualAddress+dwAposOffset;
   return dwRAV;
  }
  pSectionHeader++;
 }
 return FileOffset;
}

//打印輸入表
VOID PrintImportTable(LPSTR strPath)
{
 DWORD dwReads,dwOffset;
 char strName[130];
 int intStup=0,intStup1=0;
 PIMAGE_DOS_HEADER pDosHeader=(PIMAGE_DOS_HEADER)new BYTE[sizeof(IMAGE_DOS_HEADER)];
 PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)new BYTE[sizeof(IMAGE_IMPORT_DESCRIPTOR)];
 PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)new BYTE[sizeof(IMAGE_FILE_HEADER)];
 PIMAGE_OPTIONAL_HEADER pOptional = (PIMAGE_OPTIONAL_HEADER)new BYTE[sizeof(IMAGE_OPTIONAL_HEADER)];
 PIMAGE_SECTION_HEADER pSection = NULL;
 PIMAGE_THUNK_DATA pThunk=(PIMAGE_THUNK_DATA)new BYTE[sizeof(IMAGE_THUNK_DATA)];
 HANDLE hFile = CreateFile(strPath,GENERIC_READ,FILE_SHARE_READ,NULL,3,0,NULL);
 if (!hFile)
  goto RET;
 SetFilePointer(hFile,0,NULL,0);
 ReadFile(hFile,pDosHeader,sizeof(IMAGE_DOS_HEADER),&dwReads,NULL);
 //判斷是否是'MZ'標誌此來判斷是否爲PE文件
 if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
 {
  CloseHandle(hFile);
  goto RET;
 }
 SetFilePointer(hFile,pDosHeader->e_lfanew,NULL,0);
 ReadFile(hFile,&dwOffset,sizeof(dwOffset),&dwReads,NULL);
 //判斷是否爲'PE00'標誌,來判斷是否爲PE文件
 if (dwOffset!=IMAGE_NT_SIGNATURE)
 {
  CloseHandle(hFile);
  goto RET;
 }
 SetFilePointer(hFile,pDosHeader->e_lfanew + 4,NULL,0);
 ReadFile(hFile,pFileHeader,sizeof(IMAGE_FILE_HEADER),&dwReads,NULL);
 ReadFile(hFile,pOptional,sizeof(IMAGE_OPTIONAL_HEADER),&dwReads,NULL);
 pSection=(PIMAGE_SECTION_HEADER)new BYTE[sizeof(IMAGE_SECTION_HEADER) * pFileHeader->NumberOfSections];
 ReadFile(hFile,pSection,sizeof(IMAGE_SECTION_HEADER) * pFileHeader->NumberOfSections,&dwReads,NULL);
 intStup=0;
 while (TRUE)
 {
  dwOffset=RvaToOffset(pSection,pFileHeader->NumberOfSections,pOptional->DataDirectory[1].VirtualAddress + intStup * sizeof(IMAGE_IMPORT_DESCRIPTOR));
  SetFilePointer(hFile,dwOffset,NULL,0);
  //獲取輸入表
  ReadFile(hFile,pImport,sizeof(IMAGE_IMPORT_DESCRIPTOR),&dwReads,NULL);
  if (pImport->OriginalFirstThunk==0 && pImport->FirstThunk==0) break;
  dwOffset=RvaToOffset(pSection,pFileHeader->NumberOfSections,pImport->Name);
  SetFilePointer(hFile,dwOffset,NULL,0);
  ReadFile(hFile,strName,sizeof(strName),&dwReads,NULL);
  printf("模塊:%s/n",strName);
  intStup1=0;
  do
  {
   //獲取IMAGE_THUNK_DATA結構
   if (pImport->OriginalFirstThunk!=0)
   {
    //獲取IMAGE_THUNK_DATA地址在文件中的真實地址
    dwOffset=RvaToOffset(pSection,pFileHeader->NumberOfSections,pImport->OriginalFirstThunk + intStup1 * sizeof(IMAGE_THUNK_DATA));
    if (dwOffset==0) break;
    SetFilePointer(hFile,dwOffset,NULL,0);
    ReadFile(hFile,pThunk,sizeof(IMAGE_THUNK_DATA),&dwReads,NULL);
   }
   else
   {
    //獲取IMAGE_THUNK_DATA地址在文件中的真實地址
    dwOffset=RvaToOffset(pSection,pFileHeader->NumberOfSections,pImport->FirstThunk + intStup1 * sizeof(IMAGE_THUNK_DATA));
    if (dwOffset==0) break;
    SetFilePointer(hFile,dwOffset,NULL,0);
    ReadFile(hFile,pThunk,sizeof(IMAGE_THUNK_DATA),&dwReads,NULL);
   }
   if (pThunk->u1.AddressOfData==0) break;
   //獲取函數名在文件中的真實地址
   dwOffset=RvaToOffset(pSection,pFileHeader->NumberOfSections,(ULONG)pThunk->u1.AddressOfData->Name);
   if (dwOffset==0) break;
   SetFilePointer(hFile,dwOffset,NULL,0);
   memset(strName,0,sizeof(strName));
   ReadFile(hFile,strName,sizeof(strName),&dwReads,NULL);
   //打印函數名
   printf("/t函數:%s/n",strName);
   intStup1 ++;
  } while (dwOffset!=0);
  intStup++;
 };
RET:
 if (pDosHeader) delete []pDosHeader;
 if (pImport) delete []pImport;
 if (pFileHeader) delete []pFileHeader;
 if (pOptional) delete []pOptional;
 if (pSection) delete []pSection;
 if (pThunk) delete []pThunk;
 CloseHandle(hFile);
}

VOID PrintExportTable(LPSTR strPath)
{
 DWORD dwReads,dwOffset;
 char strName[130];
 int intStup=0;
 PIMAGE_DOS_HEADER pDosHeader=(PIMAGE_DOS_HEADER)new BYTE[sizeof(IMAGE_DOS_HEADER)];
 PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)new BYTE[sizeof(IMAGE_EXPORT_DIRECTORY)];
 PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)new BYTE[sizeof(IMAGE_FILE_HEADER)];
 PIMAGE_OPTIONAL_HEADER pOptional = (PIMAGE_OPTIONAL_HEADER)new BYTE[sizeof(IMAGE_OPTIONAL_HEADER)];
 PIMAGE_SECTION_HEADER pSection = NULL;
 HANDLE hFile = CreateFile(strPath,GENERIC_READ,FILE_SHARE_READ,NULL,3,0,NULL);
 if (!hFile)
  goto RET;
 SetFilePointer(hFile,0,NULL,0);
 ReadFile(hFile,pDosHeader,sizeof(IMAGE_DOS_HEADER),&dwReads,NULL);
 if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
 {
  CloseHandle(hFile);
  goto RET;
 }
 SetFilePointer(hFile,pDosHeader->e_lfanew,NULL,0);
 ReadFile(hFile,&dwOffset,sizeof(dwOffset),&dwReads,NULL);
 if (dwOffset!=IMAGE_NT_SIGNATURE)
 {
  CloseHandle(hFile);
  goto RET;
 }
 SetFilePointer(hFile,pDosHeader->e_lfanew + 4,NULL,0);
 ReadFile(hFile,pFileHeader,sizeof(IMAGE_FILE_HEADER),&dwReads,NULL);
 ReadFile(hFile,pOptional,sizeof(IMAGE_OPTIONAL_HEADER),&dwReads,NULL);
 pSection=(PIMAGE_SECTION_HEADER)new BYTE[sizeof(IMAGE_SECTION_HEADER) * pFileHeader->NumberOfSections];
 ReadFile(hFile,pSection,sizeof(IMAGE_SECTION_HEADER) * pFileHeader->NumberOfSections,&dwReads,NULL);

 if (pOptional->DataDirectory[0].VirtualAddress==0)
 {
  printf("沒有導出表信息!!/n");
  goto RET;
 }
 dwOffset=RvaToOffset(pSection,pFileHeader->NumberOfSections,pOptional->DataDirectory[0].VirtualAddress);
 ///dwOffset=OffsetToRva(pSection,pFileHeader->NumberOfSections,dwOffset);
 SetFilePointer(hFile,dwOffset,NULL,0);
 ReadFile(hFile,pExport,sizeof(IMAGE_EXPORT_DIRECTORY),&dwReads,NULL);
 dwOffset=RvaToOffset(pSection,pFileHeader->NumberOfSections,pExport->Name);
 SetFilePointer(hFile,dwOffset,NULL,0);
 ReadFile(hFile,strName,sizeof(strName),&dwReads,NULL);
 printf("模塊:%s/n",strName);
 intStup=0;
 do
 {
  if (intStup>=(int)pExport->NumberOfFunctions) break;
  dwOffset=RvaToOffset(pSection,pFileHeader->NumberOfSections,pExport->AddressOfNames + intStup * sizeof(intStup));
  if (dwOffset==0) break;
  SetFilePointer(hFile,dwOffset,NULL,0);
  ReadFile(hFile,&dwOffset,sizeof(dwOffset),&dwReads,NULL);
  dwOffset=RvaToOffset(pSection,pFileHeader->NumberOfSections,dwOffset);
  if (dwOffset==0) break;
  SetFilePointer(hFile,dwOffset,NULL,0);
  memset(strName,0,sizeof(strName));
  ReadFile(hFile,strName,sizeof(strName),&dwReads,NULL);
  printf("/t函數:%s/n",strName);
  intStup ++;
 } while (dwOffset!=0);
RET:
 if (pDosHeader) delete []pDosHeader;
 if (pExport) delete []pExport;
 if (pFileHeader) delete []pFileHeader;
 if (pOptional) delete []pOptional;
 if (pSection) delete []pSection;
 CloseHandle(hFile);
}

發佈了81 篇原創文章 · 獲贊 4 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章