1.如何读取导入文件
2.如何找到每个结构体的地址
3.熟悉PE文件结构对应的结构体(参考PE文件结构1)
首先通过CreatFileA函数打开文件;然后通过HeapAlloc函数分配空间;最后经过ReadFile函数读取文件内容至指定空间。这几个与文件有关的WindowsAPI函数是我们处理PE文件的关键。
在PE文件结构1当中已经介绍了,PE文件结构的每个组成部分都有其对应的结构体,那么只要我们熟悉了结构体的组成然后找到每个结构体对应的指针,那么问题也就解决了。
现在依次介绍每个部分对应指针应该如何寻址:
DOS首部:dosHeader = (PIMAGE_DOS_HEADER)lpBuffer;
这里的lpBuffer其实就是文件的起始句柄了,PE文件是从DOS首部开始的,所以只要将起始句柄类型转化一下为对应的指针即可。
PE文件首部:ntHeader = (PIMAGE_NT_HEADERS)(lpBuffer + dosHeader->e_lfanew);
这里就是一个RVA和VA的概念了,相对于文件起始地址为RVA也就是dosHeader->e_lfanew,加上文件的起始地址后才是我们可以用来寻址的指针。
ntHeader->FileHeader.Machine;
ntHeader->OptionalHeader.Magic;
由于PE文件首部内部还包含了两个结构体,这里举两个例子。
区块首部:imageSectionHeaderStruct = (PIMAGE_SECTION_HEADER)((DWORD)lpBuffer + dosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
要找到区块表的首部地址就需要先找到PE文件首部地址再加上PE文件首部大小,即为对应的区块首部地址。
由于节块的数目是不一定的,需要通过循环将其依次打印。
for (int i = 0; i < numSections; i++)
{
printf("SECTION HEADER #%d\n", i);
printf("\t%s\n", imageSectionHeaderStruct->Name);
printf("\t\tVirtual Size: 0x%x\n", imageSectionHeaderStruct->Misc.VirtualSize);
printf("\t\tVirtual Address: 0x%x\n", imageSectionHeaderStruct->VirtualAddress);
printf("\t\tRaw Size: 0x%x\n", imageSectionHeaderStruct->SizeOfRawData);
printf("\t\tRaw Address: 0x%x\n", imageSectionHeaderStruct->PointerToRawData);
printf("\t\tReloc Address: 0x%x\n", imageSectionHeaderStruct->PointerToRelocations);
printf("\t\tRelocations Number: 0x%x\n", imageSectionHeaderStruct->NumberOfRelocations);
printf("\t\tLine Numbers: 0x%x\n", imageSectionHeaderStruct->NumberOfLinenumbers);
printf("\t\tCharacteristics: 0x%x\n", imageSectionHeaderStruct->Characteristics);
imageSectionHeaderStruct++;
}
导入表,导出表和资源表相对来说就比较麻烦一点,需要先在数据目录表当中寻找对应地址,然后再去数据段找到相应数据打印。
这里以导入表为例:
IMAGE_IMPORT_DESCRIPTOR* ImportTables = (IMAGE_IMPORT_DESCRIPTOR_)(RTF(_rvaaddr) + pBegin); 这里我们先找到导入表的数据目录表对应的地址。 2. 然后找到对应的IAT地址,即
int firstthunk = (int)ImportTables2->FirstThunkl;```这就是我们需要找的地址,之后依次打印即可。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章