Внедрение DLL из LoadImageNotifyRoutine, зависает на ZwMapViewOfSection - PullRequest
0 голосов
/ 25 августа 2018

Итак, я делаю крэкме, и одна из частей состоит в том, чтобы подключить определенную функцию и подождать, пока не произойдет определенная комбинация params, тогда задача выполнена.

Для этого,Я создаю драйвер для внедрения DLL в процессы, которые имеют определенную DLL и подключают определенную функцию.

Я делаю это с помощью

  1. Получение дескриптора для DLL для внедрения

    ZwCreateFile( &DeviceExtension->HookDllHandle, GENERIC_ALL, &Attributes, &StatusBlock, NULL, 0, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 )

  2. Затем, регистрация LoadImageNotifyRoutine внутри драйвера main PsSetLoadImageNotifyRoutine(ImageCBK);

Что должно произойти:

  1. Я проверяю, загружена ли необходимая DLL (которая будет экспортировать мою функцию).
  2. Находясь в контексте процесса, который вызвалВ обратном вызове я создаю раздел с ZwCreateSection, затем отображаю dll в этот раздел и вызываю точку входа DLL, создавая новый поток.
  3. После этого перехват не должен быть проблемой.

Хотя IRQL для ZwCreateSection и ZwMapViewOfSection позволяет их использоватьвнутри процедуры уведомления все еще ZwMapViewOfSection зависает каждый раз, когда я пытаюсь его использовать.

Я использую некоторый код из Beholder

status = ObOpenObjectByPointer(PsGetCurrentProcess(), OBJ_KERNEL_HANDLE, NULL, STANDARD_RIGHTS_ALL, NULL, KernelMode, &ProcessHandle);
if (!NT_SUCCESS(status))
{
    DbgPrint("Unable to get process handle\n");
    return STATUS_SEVERITY_ERROR;
}

// Create a new section for DLL mapping
InitializeObjectAttributes(&Attributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwCreateSection(&DllSectionHandle, SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_QUERY, &Attributes, NULL, PAGE_EXECUTE_READ, SEC_IMAGE, DeviceExtension->HookDllHandle);
if (!NT_SUCCESS(status))
{
    ZwClose(ProcessHandle);
    DbgPrint("Section creation failed %08X\n", status);
    return status;
}
DbgPrint("Section created %08X\n", DllSectionHandle);

// Map DLL on the section
status = ZwMapViewOfSection(DllSectionHandle, ProcessHandle, &DllBaseAddress, 0, 0, NULL, &DllViewSize, ViewUnmap, 0, PAGE_EXECUTE_READ);
if (!NT_SUCCESS(status))
{
    ZwClose(ProcessHandle);
    ZwClose(DllSectionHandle);
    DbgPrint("Unable to map section %08X\n", status);
    return status;
}
DbgPrint("Mapped DLL: %08X\n", DllBaseAddress);

К сожалению, он никогда не показывает последний DbgPrint с DllBaseAddress

1 Ответ

0 голосов
/ 26 августа 2018

просто прочитайте документацию

Операционная система вызывает процедуру уведомления загрузочного образа водителя по адресу PASSIVE_LEVEL внутри критической области с нормальными APC ядра инвалидов

и

Чтобы избежать взаимоблокировок, процедуры уведомления о загрузке изображения не должны вызывать систему подпрограммы, которые отображают , выделяют, запрашивают, освобождают или выполняют другие операции в виртуальной памяти пространства пользователя.

вы игнорируете это и вызываете подпрограмму ZwMapViewOfSection, которая map . и зашел в тупик

Решение

является простым и элегантным - вставьте обычный APC режима ядра в текущий поток внутри ImageCBK. потому что этот APC здесь отключен - он выполняется уже после того, как вы вернетесь из ImageCBK - просто выйдите из системы из критической области и включите APC. в этот момент ваш apc KernelRoutine / NormalRoutine будет вызван. и именно внутри NormalRoutine вы должны отобразить

...