设为首页 加入收藏

TOP

2.2 PE结构:文件头详细解析(六)
2023-09-09 10:25:33 】 浏览:235
Tags:2.2 结构 文件头 解析
emVersion); printf("从子系统版本: 0x%08X \t %08d \n", NtHeader->OptionalHeader.MinorSubsystemVersion, NtHeader->OptionalHeader.MinorSubsystemVersion); printf("Win32版本: 0x%08X \t %08d \n", NtHeader->OptionalHeader.Win32VersionValue, NtHeader->OptionalHeader.Win32VersionValue); printf("DLL标识: 0x%08X \t %08d \n", NtHeader->OptionalHeader.DllCharacteristics, NtHeader->OptionalHeader.DllCharacteristics); printf("SizeOfStackReserve: 0x%08X \t %08d \n", NtHeader->OptionalHeader.SizeOfStackReserve, NtHeader->OptionalHeader.SizeOfStackReserve); printf("SizeOfStackCommit: 0x%08X \t %08d \n", NtHeader->OptionalHeader.SizeOfStackCommit, NtHeader->OptionalHeader.SizeOfStackCommit); printf("SizeOfHeapReserve: 0x%08X \t %08d \n", NtHeader->OptionalHeader.SizeOfHeapReserve, NtHeader->OptionalHeader.SizeOfHeapReserve); printf("SizeOfHeapCommit: 0x%08X \t %08d \n", NtHeader->OptionalHeader.SizeOfHeapCommit, NtHeader->OptionalHeader.SizeOfHeapCommit); printf("LoaderFlags: 0x%08X \t %08d \n", NtHeader->OptionalHeader.LoaderFlags, NtHeader->OptionalHeader.LoaderFlags); } else { printf("非标准程序 \n"); } system("pause"); return 0; }

当程序被运行后,则可输出NT头中针对FileHeaderOptionalHeader表中的所有内容,输出效果图如下图所示;

此外针对数据目录表的枚举,也将变得很容易实现,一般而言通过NtHeader->OptionalHeader.NumberOfRvaAndSizes读者可得到数据目录表的数量,当得到了数据目录表的数量后则可通过循环的方式依次输出DataDirectory[x]数组中每一个变量的参数信息,根据每次循环的不同则输出不同的参数;

// --------------------------------------------------
// 临时将RVA转换为FOA的函数
// --------------------------------------------------
DWORD RVAtoFOA(DWORD rva)
{
    auto SectionTables = IMAGE_FIRST_SECTION(NtHeader);    // 获取区段表
    WORD Count = NtHeader->FileHeader.NumberOfSections;    // 获取区段数量

    for (int i = 0; i < Count; ++i)
    {
        // 判断是否存在于区段中
        DWORD Section_Start = SectionTables[i].VirtualAddress;
        DWORD Section_Ends = SectionTables[i].VirtualAddress + SectionTables[i].SizeOfRawData;
        if (rva >= Section_Start && rva < Section_Ends)
        {
            // 找到之后计算位置并返回值
            return rva - SectionTables[i].VirtualAddress + SectionTables[i].PointerToRawData;
        }
    }
    return -1;
}

int main(int argc, char * argv[])
{
    BOOL PE = IsPeFile(OpenPeFile("c://pe/x86.exe"), 0);

    if (PE == TRUE)
    {
        int Data_Size = NtHeader->OptionalHeader.NumberOfRvaAndSizes;
        printf("编号 \t 目录RVA \t 目录FOA \t Size长度(十进制) \t Size长度(十六进制) \t 功能描述 \n");

        for (int x = 0; x < Data_Size; x++)
        {
            printf("%03d \t 0x%08X \t 0x%08X \t %08d \t\t 0x%08X \t\t", x + 1, NtHeader->OptionalHeader.DataDirectory[x].VirtualAddress,
                RVAtoFOA(NtHeader->OptionalHeader.DataDirectory[x].VirtualAddress),
                NtHeader->OptionalHeader.DataDirectory[x].Size, NtHeader->OptionalHeader.DataDirectory[x].Size);

            switch (x)
            {
            case 0: printf("Export symbols \n"); break;
            case 1: printf("Import symbols \n"); break;
            case 2: printf("Resources \n"); break;
            case 3: printf("Exception \n"); break;
            case 4: printf("Security \n"); break;
            case 5: printf("Base relocation \n"); break;
            case 6: printf("Debug \n"); break;
            case 7: printf("Copyright string
首页 上一页 3 4 5 6 下一页 尾页 6/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++系列十:日常学习-元编程 下一篇C++的编译链接与在vs中build提速

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目