// PEViewer.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "windows.h"
#include "winnt.h"
#include <ctime>
#include <assert.h>
using namespace std;
char szFileName[256] = "";
DWORD RVA2FOA(PIMAGE_SECTION_HEADER pImageSectionHeader, WORD NumberOfSections, DWORD RVA, DWORD FileAlignment, PIMAGE_SECTION_HEADER* pPImageSectionHeaderInfo = nullptr)
{
for (int i = 0; i < NumberOfSections; i++)
{
if (RVA >= pImageSectionHeader->VirtualAddress && RVA <= pImageSectionHeader->VirtualAddress + pImageSectionHeader->Misc.VirtualSize)
{
DWORD PointerToRawData = pImageSectionHeader->PointerToRawData - (pImageSectionHeader->PointerToRawData % FileAlignment);
if (pPImageSectionHeaderInfo)
{
*pPImageSectionHeaderInfo = pImageSectionHeader;
}
return RVA - pImageSectionHeader->VirtualAddress + PointerToRawData;
}
++pImageSectionHeader;
}
return RVA;
}
DWORD FOA2RVA(PIMAGE_SECTION_HEADER pImageSectionHeader, WORD NumberOfSections, DWORD FOA, DWORD FileAlignment)
{
for (int i = 0; i < NumberOfSections; i++)
{
DWORD PointerToRawData = pImageSectionHeader->PointerToRawData - (pImageSectionHeader->PointerToRawData % FileAlignment);
if (FOA >= PointerToRawData && FOA <= PointerToRawData + pImageSectionHeader->SizeOfRawData)
{
return FOA - PointerToRawData + pImageSectionHeader->VirtualAddress;
}
++pImageSectionHeader;
}
return FOA;
}
int main(int argc, char **argv)
{
if (argc < 2)
{
return 0;
}
else
{
memcpy_s(szFileName, 256, argv[1], strlen(argv[1]));
}
FILE* fp = nullptr;
fopen_s(&fp, szFileName, "rb");
char* fileBuffer = nullptr;
if (fp)
{
fseek(fp, 0, SEEK_END);
long fileSize = ftell(fp);
fileBuffer = (char *)malloc(fileSize);
if (fileBuffer != nullptr)
{
memset(fileBuffer, 0, fileSize);
fseek(fp, 0, SEEK_SET);
size_t readSize = fread_s(fileBuffer, fileSize, 1, fileSize, fp);
assert(readSize == fileSize);
// DOS头
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
assert(pDosHeader != nullptr);
printf("DosHeader:\ne_magic:%04x\ne_lfanew:%04x\n", pDosHeader->e_magic, pDosHeader->e_lfanew);
// IMAGE_FILE_HEADER
PIMAGE_FILE_HEADER pImageFileHeader = (PIMAGE_FILE_HEADER)(fileBuffer + pDosHeader->e_lfanew + 4);
assert(pImageFileHeader != nullptr);
time_t t = (pImageFileHeader->TimeDateStamp);
char timeBuff[128];
ctime_s(timeBuff, 128, &t);
printf("\nImageFileHeader:\nMachine: % 04x\nNumberOfSections:%04x\nSizeOfOptionalHeader:%04x\nCharacteristics:%04x\nTime:%s\n",
pImageFileHeader->Machine,
pImageFileHeader->NumberOfSections,
pImageFileHeader->SizeOfOptionalHeader,
pImageFileHeader->Characteristics,
timeBuff
);
PIMAGE_SECTION_HEADER pImageSectionHeader = nullptr;
DWORD IAT_RVA = 0, EAT_RVA = 0, FileAlignment = 0;
// 是否是64位程序
ULONGLONG ullImageBase = 0;
WORD Magic = *(WORD *)(fileBuffer + pDosHeader->e_lfanew + 4 + sizeof(IMAGE_FILE_HEADER));
bool bIsX64File = (Magic == 0x20b);
if (bIsX64File)
{
PIMAGE_OPTIONAL_HEADER64 pImageOptionalHeader = (PIMAGE_OPTIONAL_HEADER64)(fileBuffer + pDosHeader->e_lfanew + 4 + sizeof(IMAGE_FILE_HEADER));
assert(pImageOptionalHeader != nullptr);
printf("\nImageOptionalHeader:\n");
printf("Magic:%04x\n", pImageOptionalHeader->Magic);
printf("AddressOfEntryPoint:%04x\n", pImageOptionalHeader->AddressOfEntryPoint);
printf("ImageBase:%llx\n", pImageOptionalHeader->ImageBase);
printf("SectionAlignment:%04x\n", pImageOptionalHeader->SectionAlignment);
printf("FileAlignment:%04x\n", pImageOptionalHeader->FileAlignment);
printf("SizeOfImage:%04x\n", pImageOptionalHeader->SizeOfImage);
printf("SizeOfHeaders:%04x\n", pImageOptionalHeader->SizeOfHeaders);
printf("Subsystem:%04x\n", pImageOptionalHeader->Subsystem);
printf("NumberOfRvaAndSizes:%04x\n", pImageOptionalHeader->NumberOfRvaAndSizes);
for (int i = 0; i < int(pImageOptionalHeader->NumberOfRvaAndSizes); i++)
{
printf("DataDirectory%d RVA:%04x\n", i, pImageOptionalHeader->DataDirectory[i].VirtualAddress);
printf("DataDirectory%d Size:%04x\n", i, pImageOptionalHeader->DataDirectory[i].Size);
}
IAT_RVA = pImageOptionalHeader->DataDirectory[1].VirtualAddress;
EAT_RVA = pImageOptionalHeader->DataDirectory[0].VirtualAddress;
ullImageBase = pImageOptionalHeader->ImageBase;
FileAlignment = pImageOptionalHeader->FileAlignment;
pImageSectionHeader = (PIMAGE_SECTION_HEADER)((char*)pImageOptionalHeader + pImageFileHeader->SizeOfOptionalHeader);
}
else
{
PIMAGE_OPTIONAL_HEADER32 pImageOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(fileBuffer + pDosHeader->e_lfanew + 4 + sizeof(IMAGE_FILE_HEADER));
assert(pImageOptionalHeader != nullptr);
printf("\nImageOptionalHeader:\n");
printf("Magic:%04x\n", pImageOptionalHeader->Magic);
printf("AddressOfEntryPoint:%04x\n", pImageOptionalHeader->AddressOfEntryPoint);
printf("ImageBase:%lx\n", pImageOptionalHeader->ImageBase);
printf("SectionAlignment:%04x\n", pImageOptionalHeader->SectionAlignment);
printf("FileAlignment:%04x\n", pImageOptionalHeader->FileAlignment);
printf("SizeOfImage:%04x\n", pImageOptionalHeader->SizeOfImage);
printf("SizeOfHeaders:%04x\n", pImageOptionalHeader->SizeOfHeaders);
printf("Subsystem:%04x\n", pImageOptionalHeader->Subsystem);
printf("NumberOfRvaAndSizes:%04x\n", pImageOptionalHeader->NumberOfRvaAndSizes);
for (int i = 0; i < int(pImageOptionalHeader->NumberOfRvaAndSizes); i++)
{
printf("DataDirectory%d RVA:%04x\n", i, pImageOptionalHeader->DataDirectory[i].VirtualAddress);
printf("DataDirectory%d Size:%04x\n", i, pImageOptionalHeader->DataDirectory[i].Size);
}
IAT_RVA = pImageOptionalHeader->DataDirectory[1].VirtualAddress;
EAT_RVA = pImageOptionalHeader->DataDirectory[0].VirtualAddress;
ullImageBase = pImageOptionalHeader->ImageBase;
FileAlignment = pImageOptionalHeader->FileAlignment;
pImageSectionHeader = (PIMAGE_SECTION_HEADER)((char *)pImageOptionalHeader + pImageFileHeader->SizeOfOptionalHeader);
}
//IMAGE_SECTION_HEADER
printf("\nImageSectionHeader:\n");
assert(pImageSectionHeader != nullptr);
PIMAGE_SECTION_HEADER pTmpImageSectionHeader = pImageSectionHeader;
for (int i = 0; i < pImageFileHeader->NumberOfSections; i++)
{
printf("Name:%s\n", pTmpImageSectionHeader->Name);
printf("VirtualSize:%04x\n", pTmpImageSectionHeader->Misc.VirtualSize);
printf("VirtualAddress:%04x\n", pTmpImageSectionHeader->VirtualAddress);
printf("SizeOfRawData:%04x\n", pTmpImageSectionHeader->SizeOfRawData);
printf("PointerToRawData:%04x\n", pTmpImageSectionHeader->PointerToRawData);
printf("Characteristics:%04x\n\n", pTmpImageSectionHeader->Characteristics);
++pTmpImageSectionHeader;
}
//IMAGE_IMPORT_DESCRIPTOR
if (IAT_RVA > 0)
{
PIMAGE_SECTION_HEADER pImageSectionHeaderInfo = nullptr;
DWORD FOA = RVA2FOA(pImageSectionHeader, pImageFileHeader->NumberOfSections, IAT_RVA, FileAlignment, &pImageSectionHeaderInfo);
PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(fileBuffer + FOA);
IMAGE_IMPORT_DESCRIPTOR imageImportDescriptor;
memset(&imageImportDescriptor, 0, sizeof(IMAGE_IMPORT_DESCRIPTOR));
bool bIATArrEnd = false;
if (FOA + sizeof(IMAGE_IMPORT_DESCRIPTOR) > ULONGLONG(pImageSectionHeaderInfo->PointerToRawData) + pImageSectionHeaderInfo->SizeOfRawData)
{
bIATArrEnd = true;
DWORD excessCount = FOA + sizeof(IMAGE_IMPORT_DESCRIPTOR) - pImageSectionHeaderInfo->PointerToRawData - pImageSectionHeaderInfo->SizeOfRawData;
memcpy_s(&imageImportDescriptor, sizeof(IMAGE_IMPORT_DESCRIPTOR) - excessCount, pImageImportDescriptor, sizeof(IMAGE_IMPORT_DESCRIPTOR) - excessCount);
pImageImportDescriptor = &imageImportDescriptor;
}
assert(pImageImportDescriptor != nullptr);
printf("\nIAT:\n");
int Count = 0;
while (pImageImportDescriptor->FirstThunk)
{
printf("\nImageImportDescriptor %d:\n", Count++);
char* Name = (fileBuffer + RVA2FOA(pImageSectionHeader, pImageFileHeader->NumberOfSections, pImageImportDescriptor->Name, FileAlignment));
printf("Name: %s\n", Name);
printf("OriginalFirstThunk: %04x\n", pImageImportDescriptor->OriginalFirstThunk);
printf("FirstThunk: %04x\n", pImageImportDescriptor->FirstThunk);
printf("ForwarderChain: %04x\n", pImageImportDescriptor->ForwarderChain);
t = (pImageImportDescriptor->TimeDateStamp);
ctime_s(timeBuff, 128, &t);
printf("Time: %s", timeBuff);
printf("Functions: \n");
// IMAGE_IMPORT_BY_NAME
if (bIsX64File)
{
ULONGLONG* Thunk = (ULONGLONG*)(fileBuffer + RVA2FOA(pImageSectionHeader, pImageFileHeader->NumberOfSections, pImageImportDescriptor->FirstThunk, FileAlignment));
while (Thunk && *Thunk > 0)
{
if ((*Thunk & 0x8000000000000000) >> 63 == 1) //序号导入
{
printf("Ordinal: %llu\n", (*Thunk & 0x7fffffffffffffff));
}
else
{
PIMAGE_IMPORT_BY_NAME pImageImportByName = (PIMAGE_IMPORT_BY_NAME)(fileBuffer + RVA2FOA(pImageSectionHeader, pImageFileHeader->NumberOfSections, DWORD(*Thunk), FileAlignment));
assert(pImageImportByName != nullptr);
printf("Name: %s\n", pImageImportByName->Name);
}
++Thunk;
}
}
else
{
DWORD* Thunk = (DWORD*)(fileBuffer + RVA2FOA(pImageSectionHeader, pImageFileHeader->NumberOfSections, pImageImportDescriptor->FirstThunk, FileAlignment));
while (Thunk && *Thunk > 0)
{
if ((*Thunk & 0x80000000) >> 31 == 1) //序号导入
{
printf("Ordinal: %lu\n", (*Thunk & 0x7fffffff));
}
else
{
PIMAGE_IMPORT_BY_NAME pImageImportByName = (PIMAGE_IMPORT_BY_NAME)(fileBuffer + RVA2FOA(pImageSectionHeader, pImageFileHeader->NumberOfSections, *Thunk, FileAlignment));
assert(pImageImportByName != nullptr);
printf("Hint: %04x, Name: %s\n", pImageImportByName->Hint, pImageImportByName->Name);
}
++Thunk;
}
}
if (!bIATArrEnd)
{
++pImageImportDescriptor;
}
else
{
break;
}
}
}
//IMAGE_EXPORT_DIRECTORY
if (EAT_RVA > 0)
{
PIMAGE_EXPORT_DIRECTORY pImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(fileBuffer + RVA2FOA(pImageSectionHeader, pImageFileHeader->NumberOfSections, EAT_RVA, FileAlignment));
assert(pImageExportDirectory != nullptr);
printf("\nEAT:\n");
char* Name = (fileBuffer + RVA2FOA(pImageSectionHeader, pImageFileHeader->NumberOfSections, pImageExportDirectory->Name, FileAlignment));
printf("Name: %s\n", Name);
printf("NumberOfFunctions: %04x\n", pImageExportDirectory->NumberOfFunctions);
printf("NumberOfNames: %04x\n", pImageExportDirectory->NumberOfNames);
printf("AddressOfFunctions: %04x\n", pImageExportDirectory->AddressOfFunctions);
printf("AddressOfNameOrdinals: %04x\n", pImageExportDirectory->AddressOfNameOrdinals);
printf("AddressOfNames: %04x\n", pImageExportDirectory->AddressOfNames);
printf("Characteristics: %04x\n", pImageExportDirectory->Characteristics);
printf("MajorVersion: %04x\n", pImageExportDirectory->MajorVersion);
printf("MinorVersion: %04x\n", pImageExportDirectory->MinorVersion);
t = (pImageExportDirectory->TimeDateStamp);
ctime_s(timeBuff, 128, &t);
printf("Time: %s", timeBuff);
printf("Functions:\n");
DWORD* pNameAddr = (DWORD*)(fileBuffer + RVA2FOA(pImageSectionHeader, pImageFileHeader->NumberOfSections, pImageExportDirectory->AddressOfNames, FileAlignment));
WORD* pOrdinalAddr = (WORD*)(fileBuffer + RVA2FOA(pImageSectionHeader, pImageFileHeader->NumberOfSections, pImageExportDirectory->AddressOfNameOrdinals, FileAlignment));
DWORD* pFuncAddr = (DWORD*)(fileBuffer + RVA2FOA(pImageSectionHeader, pImageFileHeader->NumberOfSections, pImageExportDirectory->AddressOfFunctions, FileAlignment));
for (int i = 0; i < int(pImageExportDirectory->NumberOfFunctions); i++)
{
DWORD dwOrdinal = *pOrdinalAddr;
char* funcName = (fileBuffer + RVA2FOA(pImageSectionHeader, pImageFileHeader->NumberOfSections, *pNameAddr, FileAlignment));
printf("FN%d:%s Ordinal:%d VA:%llx\n", i+1, funcName, dwOrdinal, (*(pFuncAddr + dwOrdinal)+ ullImageBase));
++pNameAddr;
++pOrdinalAddr;
}
}
}
free(fileBuffer);
std::fclose(fp);
}
return 0;
}
WinPE IAT EAT解析
于 2023-03-03 17:44:18 首次发布