连载23:代码输出可选头
2020-03-13 本文已影响0人
码农UP2U
这是可选头的最后一篇文章了,用代码将可选头进行一个输出,其实整个输出和前面也是没有什么差别的,逐个字段的输出即可。
代码如下:
void PrintOptHdr(PIMAGE_NT_HEADERS pNtHdr)
{
PIMAGE_OPTIONAL_HEADER pOptHdr = (PIMAGE_OPTIONAL_HEADER)(((DWORD)pNtHdr) + 4 + sizeof(IMAGE_FILE_HEADER));
printf("IMAGE_OPTIONAL_HEADER: \r\n");
printf("Standard fields. \r\n");
printf("\t Magic:%04x \r\n", pOptHdr->Magic);
printf("\t MajorLinkerVersion:%02x \r\n", pOptHdr->MajorLinkerVersion);
printf("\t MinorLinkerVersion:%02x \r\n", pOptHdr->MinorLinkerVersion);
printf("\t SizeOfCode:%08x \r\n", pOptHdr->SizeOfCode);
printf("\t SizeOfInitializedData:%08x \r\n", pOptHdr->SizeOfInitializedData);
printf("\t SizeOfUninitializedData:%08x \r\n", pOptHdr->SizeOfUninitializedData);
printf("\t AddressOfEntryPoint:%08x \r\n", pOptHdr->AddressOfEntryPoint);
printf("\t BaseOfCode:%08x \r\n", pOptHdr->BaseOfCode);
printf("\t BaseOfData:%08x \r\n", pOptHdr->BaseOfData);
printf("NT additional fields. \r\n");
printf("\t ImageBase:%08x \r\n", pOptHdr->ImageBase);
printf("\t SectionAlignment:%08x \r\n", pOptHdr->SectionAlignment);
printf("\t FileAlignment:%08x \r\n", pOptHdr->FileAlignment);
printf("\t MajorOperatingSystemVersion:%04x \r\n", pOptHdr->MajorOperatingSystemVersion);
printf("\t MinorOperatingSystemVersion:%04x \r\n", pOptHdr->MinorOperatingSystemVersion);
printf("\t MajorImageVersion:%04x \r\n", pOptHdr->MajorImageVersion);
printf("\t MinorImageVersion:%04x \r\n", pOptHdr->MinorImageVersion);
printf("\t MajorSubsystemVersion:%04x \r\n", pOptHdr->MajorSubsystemVersion);
printf("\t MinorSubsystemVersion:%04x \r\n", pOptHdr->MinorSubsystemVersion);
printf("\t Win32VersionValue:%08x \r\n", pOptHdr->Win32VersionValue);
printf("\t SizeOfImage:%08x \r\n", pOptHdr->SizeOfImage);
printf("\t SizeOfHeaders:%08x \r\n", pOptHdr->SizeOfHeaders);
printf("\t CheckSum:%08x \r\n", pOptHdr->CheckSum);
for (int i = 0; i < sizeof(SubsystemArr) / sizeof(WORD); i++)
{
if (SubsystemArr[i] == pOptHdr->Subsystem)
{
printf("\t Subsystem:%ws \r\n", SubsystemStrArr[i]);
break;
}
}
printf("\t DllCharacteristics:%04x \r\n", pOptHdr->DllCharacteristics);
printf("\t SizeOfStackReserve:%08x \r\n", pOptHdr->SizeOfStackReserve);
printf("\t SizeOfStackCommit:%08x \r\n", pOptHdr->SizeOfStackCommit);
printf("\t SizeOfHeapReserve:%08x \r\n", pOptHdr->SizeOfHeapReserve);
printf("\t SizeOfHeapCommit:%08x \r\n", pOptHdr->SizeOfHeapCommit);
printf("\t LoaderFlags:%08x \r\n", pOptHdr->LoaderFlags);
printf("\t NumberOfRvaAndSizes:%08x \r\n", pOptHdr->NumberOfRvaAndSizes);
printf("\t DataDirectory:\r\n");
for (int i = 0; i < 15; i ++)
{
printf("\t \t %ws:[%08x, %08x] \r\n", DataDirectoryStr[i], pOptHdr->DataDirectory[i].VirtualAddress, pOptHdr->DataDirectory[i].Size);
}
}
从代码可以看出,本身代码的编写是没有任何难度的,只要把结构体进行相应的输出即可。其中数据目录的输出需要进行注意,数据目录中也是一个结构体,需要把数据目录的两个字段进行相应的输出即可。
运行结果如下:

下篇文章开始介绍节表,即 IMAGE_SECTION_HEADER 结构体,介绍完节表之后,就可以手动完成几个简单的实例了。
微信中搜索 “码农UP2U” 关注我的公众号吧!!!