Вызвано необработанное исключение: ошибка нарушения прав доступа на чтение при доступе к заголовку dos библиотеки DLL - PullRequest
0 голосов
/ 06 мая 2020

Я пытаюсь получить доступ к заголовку dos файла DLL PE. Я получаю адрес IMAGE_DOS_HEADER из PEB моего процесса. Я получаю адрес, обращаясь к PEB, затем обращаюсь к LDR, а затем просматриваю InMemoryOrderModuleList, пока не найду DLL, к которой я хочу получить доступ (в данном случае kernel32.DLL), и использую базу dll, чтобы преобразовать ее в 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;
}

1 Ответ

1 голос
/ 07 мая 2020

А ваш currentitem_InMemoryOrderModuleList - это просто указатель на LIST_ENTRY. И это LIST_ENTRY - это поле InMemoryOrderLinks в LDR_DATA_TABLE_ENTRY. Вы можете настроить указатель так, чтобы он указывал на включающую структуру перед использованием.

См. « 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...