连载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” 关注我的公众号吧!!!
上一篇 下一篇

猜你喜欢

热点阅读