// 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);
}