使用 PE 查找导入的 DLL 的名称 Headers

Find the name of the Imported DLLs using PE Headers

几天前,我开始使用 C++ 进行 Windows 系统编程。因此,想到构建一个实用程序来获取 exe 文件的 PE Headers。 现在我坚持使用 Image_Import_descriptor 结构。

我想要的是获取exe导入的DLL文件(模块)的名称。下面是我用来获取这些名称的代码:

        DWORD Image_Import_Descriptor_addr = (DWORD)ntHeader + (DWORD)sizeof(ntHeader->FileHeader) + (DWORD)ntHeader->FileHeader.SizeOfOptionalHeader + (DWORD)ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
        importImageDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)Image_Import_Descriptor_addr;

获取 name 的 RVA:

        DWORD name = importImageDescriptor->Name;
        printf("\n\n\n\t\t (((Module Name)): %X", name);

给出输出: 4778B00

希望到现在为止技术上一切都很好。

然而,我的动机是打印 DLL 名称(如 kernel32.dll)。 任何人都可以帮助我如何获取 DLL 的名称?

我的解决方法:

            LPCSTR snames = (LPCSTR)name;          
            printf("\n\n\n\t\t (((Module Name)): %s", *snames);

但这给我一个错误:访问冲突

我对指针和数据类型转换感到困惑。非常感谢您的帮助。

从 'ired' 安全博客中获取技术。下面是工作代码。

HANDLE h_File = CreateFile(L"testing.exe", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (!h_File) {
    printf("\nERROR : Could not open the file specified\n");
}

//Mapping Given EXE file to Memory
HANDLE hMapObject = CreateFileMapping(h_File, NULL, PAGE_READONLY, 0, 0, NULL);
LPVOID basepointer = (char*)MapViewOfFile(hMapObject, FILE_MAP_READ, 0, 0, 0);

//PIMAGE_DOS_HEADER dos_header;        
PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)basepointer;
printf("Magic number - %X\n", dos_header->e_magic); 

printf("DOS HEADER: IMAGE NT HEADER offset(Relative Address) - %X\n", dos_header->e_lfanew);  //DOS header working fine...

//PIMAGE_NT_HEADERS ntHeader;         
PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)((DWORD)basepointer + dos_header->e_lfanew);
printf("NT HEADER: Signature %x\n", nt_header->Signature);

PIMAGE_FILE_HEADER file_header = (PIMAGE_FILE_HEADER)((DWORD)basepointer + dos_header->e_lfanew + sizeof(nt_header->Signature));
printf("FILE HEADER: Machine %x\n", file_header->Machine);

PIMAGE_OPTIONAL_HEADER optional_header = (PIMAGE_OPTIONAL_HEADER)((DWORD)basepointer + dos_header->e_lfanew + sizeof(nt_header->Signature) + sizeof(nt_header->FileHeader));
printf("OPTIONAL HEADER: Image Base %x\n", optional_header->ImageBase);

PIMAGE_SECTION_HEADER section_header = (PIMAGE_SECTION_HEADER)((DWORD)basepointer + dos_header->e_lfanew + sizeof(nt_header->Signature) + sizeof(nt_header->FileHeader) + sizeof(nt_header->OptionalHeader));
DWORD numberofsections = file_header->NumberOfSections;
printf("Section Header: Number of Sections %x\n", file_header->NumberOfSections);


    
for (int j = 0; j < optional_header->NumberOfRvaAndSizes;j++) {
    printf("Data Directory: Virtual Address: %x\t\n", optional_header->DataDirectory[j].VirtualAddress);
}

DWORD RVAimport_directory = nt_header->OptionalHeader.DataDirectory[1].VirtualAddress;
//printf("RVAimport_directory %x", RVAimport_directory);

PIMAGE_SECTION_HEADER import_section = {};
for (int i = 1; i <= numberofsections; i++, section_header++) {
    printf("Section Header: Section Name %s\n", section_header->Name);

    if (RVAimport_directory >= section_header->VirtualAddress && RVAimport_directory < section_header->VirtualAddress + section_header->Misc.VirtualSize) {

        import_section = section_header;
    }
    //section_header += (DWORD)sizeof(PIMAGE_SECTION_HEADER);
}

DWORD import_table_offset = (DWORD)basepointer + import_section->PointerToRawData;
//imageBaseAddress + pointerToRawDataOfTheSectionContainingRVAofInterest + (RVAofInterest - SectionContainingRVAofInterest.VirtualAddress

importImageDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(import_table_offset + (nt_header->OptionalHeader.DataDirectory[1].VirtualAddress - import_section->VirtualAddress));

//DLL Imports
for (;importImageDescriptor->Name != 0 ; importImageDescriptor++) {
    DWORD Imported_DLL = import_table_offset + (importImageDescriptor->Name - import_section->VirtualAddress);
    printf("Imported DLLs: %s\n", Imported_DLL);