读取调试目录时出现奇怪的条目类型 4194304

问题描述 投票:0回答:1

它不是 PE 文件的重复:IMAGE_DEBUG_TYPE_VC_FEATURE 类型的调试目录。它在 0 到 16 之间。

我正在尝试解析PE头及其目录,正如IMAGE_DATA_DIRECTORY结构所示,调试信息偏移距可选头144字节。这就是我访问整个 PE 头和调试目录的方式:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cstring>
#include <exception>
BOOL CALLBACK ENUMRESPROCCALLBACK(
                 HMODULE hModule,
                 LPCSTR lpType,
                 LPSTR lpName,
                 LONG_PTR lParam
)
{
    HRSRC hResource=FindResource(hModule,lpName,lpType);
    printf("\t%02X\t\tSize\n", SizeofResource(hModule,hResource));
    return TRUE;
}

int main(int argc, char* argv[]) {
    HANDLE file = NULL;
    DWORD fileSize = NULL;
    DWORD bytesRead = NULL;
    LPVOID fileData = NULL;
    PIMAGE_DOS_HEADER dosHeader = {};
    PIMAGE_NT_HEADERS imageNTHeaders = {};
    PIMAGE_SECTION_HEADER sectionHeader = {};
    PIMAGE_SECTION_HEADER importSection = {};
    IMAGE_IMPORT_DESCRIPTOR* importDescriptor = {};
    PIMAGE_SECTION_HEADER exportSection = {};
    PIMAGE_EXPORT_DIRECTORY exportDescriptor={};
    PIMAGE_THUNK_DATA thunkData = {};
    DWORD thunk = NULL;
    DWORD rawOffset = NULL;

    // open file
    file = CreateFileA(argv[1], GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (file == INVALID_HANDLE_VALUE) printf("Could not read file");

    // allocate heap
    fileSize = GetFileSize(file, NULL);
    fileData = HeapAlloc(GetProcessHeap(), 0, fileSize);

    // read file bytes to memory
    ReadFile(file, fileData, fileSize, &bytesRead, NULL);

    // IMAGE_DOS_HEADER
    dosHeader = (PIMAGE_DOS_HEADER)fileData;
    printf("******* DOS HEADER *******\n");
    printf("\t0x%x\t\tMagic number\n", dosHeader->e_magic);
    printf("\t0x%x\t\tBytes on last page of file\n", dosHeader->e_cblp);
    printf("\t0x%x\t\tPages in file\n", dosHeader->e_cp);
    printf("\t0x%x\t\tRelocations\n", dosHeader->e_crlc);
    printf("\t0x%x\t\tSize of header in paragraphs\n", dosHeader->e_cparhdr);
    printf("\t0x%x\t\tMinimum extra paragraphs needed\n", dosHeader->e_minalloc);
    printf("\t0x%x\t\tMaximum extra paragraphs needed\n", dosHeader->e_maxalloc);
    printf("\t0x%x\t\tInitial (relative) SS value\n", dosHeader->e_ss);
    printf("\t0x%x\t\tInitial SP value\n", dosHeader->e_sp);
    printf("\t0x%x\t\tInitial SP value\n", dosHeader->e_sp);
    printf("\t0x%x\t\tChecksum\n", dosHeader->e_csum);
    printf("\t0x%x\t\tInitial IP value\n", dosHeader->e_ip);
    printf("\t0x%x\t\tInitial (relative) CS value\n", dosHeader->e_cs);
    printf("\t0x%x\t\tFile address of relocation table\n", dosHeader->e_lfarlc);
    printf("\t0x%x\t\tOverlay number\n", dosHeader->e_ovno);
    printf("\t0x%x\t\tOEM identifier (for e_oeminfo)\n", dosHeader->e_oemid);
    printf("\t0x%x\t\tOEM information; e_oemid specific\n", dosHeader->e_oeminfo);
    printf("\t0x%x\t\tFile address of new exe header\n", dosHeader->e_lfanew);

    // IMAGE_NT_HEADERS
    imageNTHeaders = (PIMAGE_NT_HEADERS)((DWORD)fileData + dosHeader->e_lfanew);
    printf("\n******* NT HEADERS *******\n");
    printf("\t%x\t\tSignature\n", imageNTHeaders->Signature);

    // FILE_HEADER
    printf("\n******* FILE HEADER *******\n");
    printf("\t0x%x\t\tMachine\n", imageNTHeaders->FileHeader.Machine);
    printf("\t0x%x\t\tNumber of Sections\n", imageNTHeaders->FileHeader.NumberOfSections);
    printf("\t0x%x\tTime Stamp\n", imageNTHeaders->FileHeader.TimeDateStamp);
    printf("\t0x%x\t\tPointer to Symbol Table\n", imageNTHeaders->FileHeader.PointerToSymbolTable);
    printf("\t0x%x\t\tNumber of Symbols\n", imageNTHeaders->FileHeader.NumberOfSymbols);
    printf("\t0x%x\t\tSize of Optional Header\n", imageNTHeaders->FileHeader.SizeOfOptionalHeader);
    printf("\t0x%x\t\tCharacteristics\n", imageNTHeaders->FileHeader.Characteristics);

    // OPTIONAL_HEADER
    printf("\n******* OPTIONAL HEADER *******\n");
    printf("\t0x%x\t\tMagic\n", imageNTHeaders->OptionalHeader.Magic);
    printf("\t0x%x\t\tMajor Linker Version\n", imageNTHeaders->OptionalHeader.MajorLinkerVersion);
    printf("\t0x%x\t\tMinor Linker Version\n", imageNTHeaders->OptionalHeader.MinorLinkerVersion);
    printf("\t0x%x\t\tSize Of Code\n", imageNTHeaders->OptionalHeader.SizeOfCode);
    printf("\t0x%x\t\tSize Of Initialized Data\n", imageNTHeaders->OptionalHeader.SizeOfInitializedData);
    printf("\t0x%x\t\tSize Of UnInitialized Data\n", imageNTHeaders->OptionalHeader.SizeOfUninitializedData);
    printf("\t0x%x\t\tAddress Of Entry Point (.text)\n", imageNTHeaders->OptionalHeader.AddressOfEntryPoint);
    printf("\t0x%x\t\tBase Of Code\n", imageNTHeaders->OptionalHeader.BaseOfCode);
    printf("\t0x%x\t\tBase Of Data\n", imageNTHeaders->OptionalHeader.BaseOfData);
    printf("\t0x%x\t\tImage Base\n", imageNTHeaders->OptionalHeader.ImageBase);
    printf("\t0x%x\t\tSection Alignment\n", imageNTHeaders->OptionalHeader.SectionAlignment);
    printf("\t0x%x\t\tFile Alignment\n", imageNTHeaders->OptionalHeader.FileAlignment);
    printf("\t0x%x\t\tMajor Operating System Version\n", imageNTHeaders->OptionalHeader.MajorOperatingSystemVersion);
    printf("\t0x%x\t\tMinor Operating System Version\n", imageNTHeaders->OptionalHeader.MinorOperatingSystemVersion);
    printf("\t0x%x\t\tMajor Image Version\n", imageNTHeaders->OptionalHeader.MajorImageVersion);
    printf("\t0x%x\t\tMinor Image Version\n", imageNTHeaders->OptionalHeader.MinorImageVersion);
    printf("\t0x%x\t\tMajor Subsystem Version\n", imageNTHeaders->OptionalHeader.MajorSubsystemVersion);
    printf("\t0x%x\t\tMinor Subsystem Version\n", imageNTHeaders->OptionalHeader.MinorSubsystemVersion);
    printf("\t0x%x\t\tWin32 Version Value\n", imageNTHeaders->OptionalHeader.Win32VersionValue);
    printf("\t0x%x\t\tSize Of Image\n", imageNTHeaders->OptionalHeader.SizeOfImage);
    printf("\t0x%x\t\tSize Of Headers\n", imageNTHeaders->OptionalHeader.SizeOfHeaders);
    printf("\t0x%x\t\tCheckSum\n", imageNTHeaders->OptionalHeader.CheckSum);
    printf("\t0x%x\t\tSubsystem\n", imageNTHeaders->OptionalHeader.Subsystem);
    printf("\t0x%x\t\tDllCharacteristics\n", imageNTHeaders->OptionalHeader.DllCharacteristics);
    printf("\t0x%x\t\tSize Of Stack Reserve\n", imageNTHeaders->OptionalHeader.SizeOfStackReserve);
    printf("\t0x%x\t\tSize Of Stack Commit\n", imageNTHeaders->OptionalHeader.SizeOfStackCommit);
    printf("\t0x%x\t\tSize Of Heap Reserve\n", imageNTHeaders->OptionalHeader.SizeOfHeapReserve);
    printf("\t0x%x\t\tSize Of Heap Commit\n", imageNTHeaders->OptionalHeader.SizeOfHeapCommit);
    printf("\t0x%x\t\tLoader Flags\n", imageNTHeaders->OptionalHeader.LoaderFlags);
    printf("\t0x%x\t\tNumber Of Rva And Sizes\n", imageNTHeaders->OptionalHeader.NumberOfRvaAndSizes);

    // DATA_DIRECTORIES
    printf("\n******* DATA DIRECTORIES *******\n");
    printf("\tExport Directory Address: 0x%x; Size: 0x%x\n", imageNTHeaders->OptionalHeader.DataDirectory[0].VirtualAddress, imageNTHeaders->OptionalHeader.DataDirectory[0].Size);
    printf("\tImport Directory Address: 0x%x; Size: 0x%x\n", imageNTHeaders->OptionalHeader.DataDirectory[1].VirtualAddress, imageNTHeaders->OptionalHeader.DataDirectory[1].Size);
    printf("\tResource Directory Address: 0x%x; Size: 0x%x\n", imageNTHeaders->OptionalHeader.DataDirectory[2].VirtualAddress, imageNTHeaders->OptionalHeader.DataDirectory[2].Size);
    printf("\tDebug Directory Address: 0x%x; Size: 0x%x\n", imageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress, imageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size);

    // SECTION_HEADERS
    printf("\n******* SECTION HEADERS *******\n");
    // get offset to first section headeer
    DWORD sectionLocation = (DWORD)imageNTHeaders + sizeof(DWORD) + (DWORD)(sizeof(IMAGE_FILE_HEADER)) + (DWORD)imageNTHeaders->FileHeader.SizeOfOptionalHeader;
    DWORD sectionSize = (DWORD)sizeof(IMAGE_SECTION_HEADER);

    // get offset to the import directory RVA
    DWORD importDirectoryRVA = imageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;

    // get offset to the export directory RVA
    //DWORD exportDirectoryRVA = imageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;

    // print section data
    for (int i = 0; i < imageNTHeaders->FileHeader.NumberOfSections; i++) {
        sectionHeader = (PIMAGE_SECTION_HEADER)sectionLocation;
        printf("\t%s\n", sectionHeader->Name);
        printf("\t\t0x%x\t\tVirtual Size\n", sectionHeader->Misc.VirtualSize);
        printf("\t\t0x%x\t\tVirtual Address\n", sectionHeader->VirtualAddress);
        printf("\t\t0x%x\t\tSize Of Raw Data\n", sectionHeader->SizeOfRawData);
        printf("\t\t0x%x\t\tPointer To Raw Data\n", sectionHeader->PointerToRawData);
        printf("\t\t0x%x\t\tPointer To Relocations\n", sectionHeader->PointerToRelocations);
        printf("\t\t0x%x\t\tPointer To Line Numbers\n", sectionHeader->PointerToLinenumbers);
        printf("\t\t0x%x\t\tNumber Of Relocations\n", sectionHeader->NumberOfRelocations);
        printf("\t\t0x%x\t\tNumber Of Line Numbers\n", sectionHeader->NumberOfLinenumbers);
        printf("\t\t0x%x\tCharacteristics\n", sectionHeader->Characteristics);

        // save section that contains import directory table
        if (importDirectoryRVA >= sectionHeader->VirtualAddress && importDirectoryRVA < sectionHeader->VirtualAddress + sectionHeader->Misc.VirtualSize) {
            importSection = sectionHeader;
        }
        if (sectionHeader->Characteristics & IMAGE_SCN_CNT_CODE) printf("\t\tCode\t\tFlags\n");
        sectionLocation += sectionSize;
    }

    // get file offset to import table
    rawOffset = (DWORD)fileData + importSection->PointerToRawData;

    // get pointer to import descriptor's file offset. Note that the formula for calculating file offset is: imageBaseAddress + pointerToRawDataOfTheSectionContainingRVAofInterest + (RVAofInterest - SectionContainingRVAofInterest.VirtualAddress)
    importDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(rawOffset + (imageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress - importSection->VirtualAddress));
    printf("\n******* DLL IMPORTS *******\n");
    for (; importDescriptor->Name != 0; importDescriptor++) {
        // imported dll modules
        printf("\t%s\n", rawOffset + (importDescriptor->Name - importSection->VirtualAddress));
        thunk = importDescriptor->OriginalFirstThunk == 0 ? importDescriptor->FirstThunk : importDescriptor->OriginalFirstThunk;
        thunkData = (PIMAGE_THUNK_DATA)(rawOffset + (thunk - importSection->VirtualAddress));

        // dll exported functions
        for (; thunkData->u1.AddressOfData != 0; thunkData++) {
            //a cheap and probably non-reliable way of checking if the function is imported via its ordinal number ¯\_(ツ)_/¯
            if (imageNTHeaders->OptionalHeader.Magic==IMAGE_NT_OPTIONAL_HDR32_MAGIC){
                if (thunkData->u1.AddressOfData > 0x80000000) {
                    //show lower bits of the value to get the ordinal ¯\_(ツ)_/¯
                    printf("\t\tOrdinal: %x\n", (WORD)thunkData->u1.AddressOfData);
                } else {
                    printf("\t\t%s\n", (rawOffset + (thunkData->u1.AddressOfData - importSection->VirtualAddress + 2)));
                }
            }
            else if (imageNTHeaders->OptionalHeader.Magic==IMAGE_NT_OPTIONAL_HDR64_MAGIC){
                if (thunkData->u1.AddressOfData > 0x8000000000000000) {
                    //show lower bits of the value to get the ordinal ¯\_(ツ)_/¯
                    printf("\t\tOrdinal: %x\n", (WORD)thunkData->u1.AddressOfData);
                } else {
                    printf("\t\t%s\n", (rawOffset + (thunkData->u1.AddressOfData - importSection->VirtualAddress + 2)));
                }
            }
        }
    }
    PIMAGE_EXPORT_DIRECTORY exportDir = (PIMAGE_EXPORT_DIRECTORY)((DWORD_PTR)fileData + imageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    DWORD* functions = (DWORD*)((DWORD_PTR)fileData + exportDir->AddressOfFunctions);
    DWORD* names = (DWORD*)((DWORD_PTR)fileData + exportDir->AddressOfNames);
    WORD* ordinals = (WORD*)((DWORD_PTR)fileData + exportDir->AddressOfNameOrdinals);
    HMODULE hModule=LoadLibraryEx(argv[1],NULL,DONT_RESOLVE_DLL_REFERENCES);
    DWORD moduleBase = (DWORD)hModule;
    printf("******* DLL EXPORTS *******\n");
    printf("\t%i of functions\n\t%i of names\n",sizeof(functions)/sizeof(DWORD*),sizeof(names)/sizeof(DWORD*));
    printf("\tordinal\t\thint\t\tRVA\t\tname\n");
    for (DWORD j=0;j<exportDir->NumberOfFunctions;j++){
        try
        {
            printf("\t%i\t\t%02X\t\t%0002X\t\t%s\n", ((DWORD)fileData + ordinals[j]) - (((DWORD)fileData + ordinals[0])), j, ((DWORD*)((BYTE*)moduleBase + exportDir->AddressOfFunctions))[j], ((DWORD)fileData + names[j]));
        }
        catch (...){
            continue;
        }
    }
    FreeLibrary(hModule);
    if (!imageNTHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) printf("\t1\t\t01\t\t%i\t\tstart\n",imageNTHeaders->OptionalHeader.AddressOfEntryPoint);
    printf("******** .IDATA DISASSEMBLY ********\n");
    // get file offset to import table
    rawOffset = (DWORD)fileData + importSection->PointerToRawData;

    // get pointer to import descriptor's file offset. Note that the formula for calculating file offset is: imageBaseAddress + pointerToRawDataOfTheSectionContainingRVAofInterest + (RVAofInterest - SectionContainingRVAofInterest.VirtualAddress)
    importDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(rawOffset + (imageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress - importSection->VirtualAddress));

    for (; importDescriptor->Name != 0; importDescriptor++) {
        thunk = importDescriptor->OriginalFirstThunk == 0 ? importDescriptor->FirstThunk : importDescriptor->OriginalFirstThunk;
        thunkData = (PIMAGE_THUNK_DATA)(rawOffset + (thunk - importSection->VirtualAddress));

        // dll exported functions
        for (; thunkData->u1.AddressOfData != 0; thunkData++) {
            //a cheap and probably non-reliable way of checking if the function is imported via its ordinal number ¯\_(ツ)_/¯
            try
            {
                printf("\textern __imp__%s@%i(...)\n",(rawOffset + (thunkData->u1.AddressOfData - importSection->VirtualAddress + 2)),(WORD)thunkData->u1.AddressOfData);
            }
            catch (std::exception e){
                printf("Exception thrown at %i\n", e.what());
                continue;
            }
        }
    }
    printf("******** DEPENDENCIES ********\n");
    // get file offset to import table
    rawOffset = (DWORD)fileData + importSection->PointerToRawData;

    // get pointer to import descriptor's file offset. Note that the formula for calculating file offset is: imageBaseAddress + pointerToRawDataOfTheSectionContainingRVAofInterest + (RVAofInterest - SectionContainingRVAofInterest.VirtualAddress)
    importDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(rawOffset + (imageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress - importSection->VirtualAddress));

    for (; importDescriptor->Name != 0; importDescriptor++) {
        printf("\t%s\n", rawOffset + (importDescriptor->Name - importSection->VirtualAddress));
        thunk = importDescriptor->OriginalFirstThunk == 0 ? importDescriptor->FirstThunk : importDescriptor->OriginalFirstThunk;
        thunkData = (PIMAGE_THUNK_DATA)(rawOffset + (thunk - importSection->VirtualAddress));
    }
    hModule=LoadLibraryEx(argv[1],NULL,DONT_RESOLVE_DLL_REFERENCES);
    printf("******** RESOURCES ********\n");
    printf("******** Accelerators ********\n");
    EnumResourceNamesA(hModule,RT_ACCELERATOR,ENUMRESPROCCALLBACK,NULL);
    printf("******** Animation cursors ********\n");
    EnumResourceNamesA(hModule,RT_ANICURSOR,ENUMRESPROCCALLBACK,NULL);
    printf("******** Animation icons ********\n");
    EnumResourceNamesA(hModule,RT_ANIICON,ENUMRESPROCCALLBACK,NULL);
    printf("******** Bitmaps ********\n");
    EnumResourceNamesA(hModule,RT_BITMAP,ENUMRESPROCCALLBACK,NULL);
    printf("******** Cursors ********\n");
    EnumResourceNamesA(hModule,RT_CURSOR,ENUMRESPROCCALLBACK,NULL);
    printf("******** Dialogs ********\n");
    EnumResourceNamesA(hModule,RT_DIALOG,ENUMRESPROCCALLBACK,NULL);
    printf("******** Dialog includes ********\n");
    EnumResourceNamesA(hModule,RT_DLGINCLUDE,ENUMRESPROCCALLBACK,NULL);
    printf("******** Fonts ********\n");
    EnumResourceNamesA(hModule,RT_FONT,ENUMRESPROCCALLBACK,NULL);
    printf("******** Font directory ********\n");
    EnumResourceNamesA(hModule,RT_FONTDIR,ENUMRESPROCCALLBACK,NULL);
    printf("******** Cursor groups ********\n");
    EnumResourceNamesA(hModule,RT_GROUP_CURSOR,ENUMRESPROCCALLBACK,NULL);
    printf("******** Group of icons ********\n");
    EnumResourceNamesA(hModule,RT_GROUP_ICON,ENUMRESPROCCALLBACK,NULL);
    printf("******** HTML documents ********\n");
    EnumResourceNamesA(hModule,RT_HTML,ENUMRESPROCCALLBACK,NULL);
    printf("******** Icons ********\n");
    EnumResourceNamesA(hModule,RT_ICON,ENUMRESPROCCALLBACK,NULL);
    printf("******** Manifest ********\n");
    EnumResourceNamesA(hModule,RT_MANIFEST,ENUMRESPROCCALLBACK,NULL);
    printf("******** Menu ********\n");
    EnumResourceNamesA(hModule,RT_MENU,ENUMRESPROCCALLBACK,NULL);
    printf("******** Message table ********\n");
    EnumResourceNamesA(hModule,RT_MESSAGETABLE,ENUMRESPROCCALLBACK,NULL);
    printf("******** Plug and Play (PnP) ********\n");
    EnumResourceNamesA(hModule,RT_PLUGPLAY,ENUMRESPROCCALLBACK,NULL);
    printf("******** Binary data ********\n");
    EnumResourceNamesA(hModule,RT_RCDATA,ENUMRESPROCCALLBACK,NULL);
    printf("******** String table ********\n");
    EnumResourceNamesA(hModule,RT_STRING,ENUMRESPROCCALLBACK,NULL);
    printf("******** Version table ********\n");
    EnumResourceNamesA(hModule,RT_VERSION,ENUMRESPROCCALLBACK,NULL);
    printf("******** VXD (Win9x) ********\n");
    EnumResourceNamesA(hModule,RT_VXD,ENUMRESPROCCALLBACK,NULL);
    printf("Nobody uses this app in Win9x except running with VC6.\n");
    if (imageNTHeaders->OptionalHeader.Magic==IMAGE_NT_OPTIONAL_HDR32_MAGIC){
        DWORD debugLocation=sizeof(imageNTHeaders->Signature)+sizeof(imageNTHeaders->FileHeader)+144;
        PIMAGE_DEBUG_DIRECTORY debugDirectory=(PIMAGE_DEBUG_DIRECTORY)((DWORD)fileData+debugLocation);
        printf("\t%i\t\tType\n",debugDirectory->Type);
    }
    else if (imageNTHeaders->OptionalHeader.Magic==IMAGE_NT_OPTIONAL_HDR64_MAGIC){
        DWORD debugLocation=sizeof(imageNTHeaders->Signature)+sizeof(imageNTHeaders->FileHeader)+160;
        PIMAGE_DEBUG_DIRECTORY debugDirectory=(PIMAGE_DEBUG_DIRECTORY)((DWORD)fileData+debugLocation);
        int n = debugDirectory->Type;
        int m = n % 256; // get the modulo 256 value
        printf("\t%d\t\tType\n",m);
    }
    return 0;
}

问题:

        4194304         Type

我做错了什么?

c++ winapi portable-executable
1个回答
0
投票

为了实际提供答案:

VOID DumpDebugDirectory(PVOID FileBuffer, PIMAGE_NT_HEADERS NtHeaders)
{
    // get the data directory, which is at a different location for 32-bit and 64-bit executables
    PIMAGE_DATA_DIRECTORY DataDirectory = NULL;

    switch (NtHeaders->OptionalHeader.Magic)
    {
    case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
        DataDirectory = ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.DataDirectory;
        break;
    case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
        DataDirectory = ((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.DataDirectory;
        break;
    }

    if (DataDirectory)
    {
        // get the debug directory entry
        PIMAGE_DATA_DIRECTORY DebugDirectoryEntry = &DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
        if (DebugDirectoryEntry->VirtualAddress)
        {
            // directory entry contains data; locate the section it resides in
            PIMAGE_SECTION_HEADER DebugSectionHeader = NULL;

            PIMAGE_SECTION_HEADER SectionHeaders = IMAGE_FIRST_SECTION(NtHeaders);
            for (WORD SectionIndex = 0; SectionIndex < NtHeaders->FileHeader.NumberOfSections; SectionIndex++)
            {
                PIMAGE_SECTION_HEADER SectionHeader = &SectionHeaders[SectionIndex];
                if ((DebugDirectoryEntry->VirtualAddress >= SectionHeader->VirtualAddress) && (DebugDirectoryEntry->VirtualAddress < (SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize)))
                {
                    DebugSectionHeader = SectionHeader;
                    break;
                }
            }

            if (DebugSectionHeader)
            {
                // found the section; determine the relative offset and get the data
                PVOID SectionData = (PVOID)((ULONG_PTR)FileBuffer + DebugSectionHeader->PointerToRawData);
                DWORD RelativeOffset = (DebugDirectoryEntry->VirtualAddress - DebugSectionHeader->VirtualAddress);
                PIMAGE_DEBUG_DIRECTORY DebugDirectory = (PIMAGE_DEBUG_DIRECTORY)((ULONG_PTR)SectionData + RelativeOffset);
                // dump the data
                printf("DebugDirectory.Type: %u\n", DebugDirectory->Type);
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.