簡體   English   中英

拋出未處理的異常:訪問 DLL 的 dos header 時出現讀取訪問沖突錯誤

[英]Unhandled exception thrown: read access violation error when accessing dos header of DLL

我正在嘗試訪問 DLL PE 文件的 dos header。 我從我的進程的 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;
}

而您的currentitem_InMemoryOrderModuleList只是指向LIST_ENTRY的指針。 而這個LIST_ENTRYLDR_DATA_TABLE_ENTRY中的InMemoryOrderLinks字段。 您可以在使用前調整指針以指向封閉結構。

請參閱“ PEB(進程環境塊)無效的 DllBase 地址”、“ CONTAINING_RECORD ”(它返回給定結構類型和包含結構內的字段地址的結構實例的基地址。)。

以下代碼適用於我。 你可以試試:

while (true) {
    LDR_DATA_TABLE_ENTRY inMemoryOrderModuleListItem = *(CONTAINING_RECORD(currentitem_InMemoryOrderModuleList, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks));
    if (inMemoryOrderModuleListItem.FullDllName.Buffer == NULL) {
        break;
    }
    std::wcout << inMemoryOrderModuleListItem.FullDllName.Buffer << endl;
    std::wcout << inMemoryOrderModuleListItem.DllBase << endl;
    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)inMemoryOrderModuleListItem.DllBase;
    if (!wcscmp(inMemoryOrderModuleListItem.FullDllName.Buffer, L"C:\\WINDOWS\\System32\\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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM