WinPE IAT EAT解析

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心有猛虎细嗅蔷薇&_&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值