我正在尝试访问DLL PE文件的dos标头。我从进程的PEB获取IMAGE_DOS_HEADER的地址。我通过访问PEB,然后访问LDR,然后扫描InMemoryOrderModuleList来获取地址,直到找到要访问的DLL(在本例中为kernel32.DLL),并使用dllbase将其转换为IMAGE_DOS_HEADER。获取DLL库后,出现以下错误:
Unhandled exception thrown: read access violation
我的代码:
HMODULE hNtDll = LoadLibraryA("ntdll.dll");
typedef NTSTATUS(NTAPI* pfNtQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
pfNtQueryInformationProcess ntQueryInformationProcess = (pfNtQueryInformationProcess)GetProcAddress(hNtDll, "NtQueryInformationProcess");
PROCESS_BASIC_INFORMATION pBasicInfo;
NTSTATUS status = ntQueryInformationProcess(hProcess, ProcessBasicInformation, &pBasicInfo, sizeof(pBasicInfo), 0);
PPEB peb = pBasicInfo.PebBaseAddress;
PPEB_LDR_DATA ldrData = (PPEB_LDR_DATA)peb->Ldr;
PLIST_ENTRY firstitem_InMemoryOrderModuleList = &ldrData->InMemoryOrderModuleList;
PLIST_ENTRY currentitem_InMemoryOrderModuleList = firstitem_InMemoryOrderModuleList->Flink;
while (true) {
LDR_DATA_TABLE_ENTRY inMemoryOrderModuleListItem = *(PLDR_DATA_TABLE_ENTRY)currentitem_InMemoryOrderModuleList;
if (inMemoryOrderModuleListItem.FullDllName.Buffer == NULL) {
break;
}
wcout << inMemoryOrderModuleListItem.FullDllName.Buffer << endl;
wcout << inMemoryOrderModuleListItem.DllBase << endl;
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)inMemoryOrderModuleListItem.DllBase;
if (!wcscmp(inMemoryOrderModuleListItem.FullDllName.Buffer, L"KERNEL32.DLL")) {
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)(inMemoryOrderModuleListItem.DllBase);
cout << "-------------------------" << endl;
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)dosHeader + dosHeader->e_lfanew); // error on this line because trying to access the dosHeader
}
currentitem_InMemoryOrderModuleList = currentitem_InMemoryOrderModuleList->Flink;
}
答案 0 :(得分:1)
您的
currentitem_InMemoryOrderModuleList
只是指向LIST_ENTRY
。而这个LIST_ENTRY
是InMemoryOrderLinks
。您可以调整指针以指向封闭 使用前的结构。
请参阅“ PEB (Process Environment Block) invalid DllBase address”,“ CONTAINING_RECORD”(根据结构的类型和包含结构中字段的地址,返回结构实例的基地址。)
以下代码对我有用。您可以尝试:
LDR_DATA_TABLE_ENTRY