问题描述
几天前,我开始使用 C++ 进行 Windows 系统编程。因此,考虑构建一个实用程序来获取 exe 文件的 PE 标头。 现在我坚持使用 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;
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,PAGE_READONLY,NULL);
LPVOID basepointer = (char*)MapViewOfFile(hMapObject,FILE_MAP_READ,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);