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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: WinPEWindows Preinstallation Environment)是微软开发的一款轻量级操作系统环境,用于在计算机上进行安装、部署和恢复Windows操作系统。它以精简的方式提供了一些基本的工具和驱动程序,用于进行系统维护、故障排除和系统部署。虚拟化技术在当前计算机环境中发挥着越来越重要的作用,而virtio是一种用于虚拟化环境的一组驱动程序。 在WinPE中使用virtio驱动程序可以提供更好的虚拟化性能和功能。virtio驱动程序在虚拟化环境中可以与主机系统进行更高效的通信,提供更好的网络和磁盘性能,减少对CPU和内存的使用。通过使用virtio驱动程序,WinPE可以充分利用虚拟机的优势,提高操作效率和性能。 使用virtio驱动程序可以带来多个好处。首先,它可以提供更快的网络连接,更高的数据传输速度和更低的延迟,这对于在WinPE中进行网络安装和配置非常重要。其次,virtio驱动程序还可以提供更好的磁盘性能,包括更高的传输速率和更低的读写延迟。这对于进行文件复制、备份和恢复操作非常有用。 总之,使用WinPE virtio可以显著提高虚拟化环境中的操作效率和性能。它可以带来更快的网络连接和更好的磁盘性能,从而提高系统部署、维护和恢复的效率。对于后续的Windows操作系统安装和配置工作,virtio驱动程序也是一个非常有价值的选择。 ### 回答2: WinPEWindows预安装环境(Windows Preinstallation Environment)的简称,它是一个独立的操作系统环境,用于进行Windows操作系统的安装、部署和维护等任务。而VirtIO是一种基于虚拟化技术的IO设备驱动模型,它旨在提供高性能和高效率的虚拟化IO体验。 当我们在WinPE环境中运行虚拟机时,通常需要安装虚拟机的IO设备驱动才能正常使用。而VirtIO提供的驱动则是专门为虚拟机设计的,可以提供与物理机相当的IO性能。 在WinPE环境下使用VirtIO驱动可以带来一些好处。首先,由于VirtIO驱动是专为虚拟机设计的,它与虚拟化平台紧密集成,可以充分发挥虚拟机的性能优势。其次,使用VirtIO驱动可以减少在WinPE环境中运行虚拟机的I/O延迟,提高虚拟机的响应速度和性能。此外,VirtIO驱动还可以提供更好的设备兼容性和可靠性,保证虚拟机在WinPE环境中的正常运行。 总之,WinPE VirtIO是指在WinPE环境中使用VirtIO驱动以提供高性能、高效率和可靠性的虚拟化IO体验。这是一种优化虚拟机运行的方式,可以提升虚拟机在WinPE环境下的性能和稳定性。 ### 回答3: WinPE是微软开发的一种轻量级的预安装环境,它通常用于在系统启动之前进行诊断、部署和恢复操作。而Virtio是一种虚拟化设备驱动技术,它提供了一套通用的接口,用于在虚拟机与物理主机之间进行高效的数据传输。 在WinPE中使用Virtio技术可以带来一些好处。首先,Virtio驱动可以提供更好的性能和稳定性,因为它们专门为虚拟化环境进行了优化。其次,使用Virtio驱动可以使WinPE能够与虚拟化平台更好地进行通信,实现更高效的数据传输和访问。 使用WinPE和Virtio可以实现许多任务,比如部署操作系统、备份和恢复数据、进行病毒检测和修复、分区管理等。在这些任务中,Virtio驱动可以提供更快的磁盘和网络访问速度,从而加快操作的完成时间。 总之,WinPE和Virtio的结合可以提升预安装环境的功能和性能,使其更适用于虚拟化环境。无论是在企业的系统部署还是个人的系统维护中,使用WinPE virtio都可以带来更好的用户体验和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

心有猛虎细嗅蔷薇&_&

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

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

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

打赏作者

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

抵扣说明:

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

余额充值