从LoadImageNotifyRoutine注入DLL,挂在ZwMapViewOfSection

时间:2018-08-25 18:10:16

标签: wdk dll-injection windows-kernel kernel-mode

因此,我正在做一个破解,其中一部分是挂钩某个功能,并等待参数组合的发生,然后挑战就解决了。

为此,我正在创建一个驱动程序,以将DLL注入具有特定DLL并具有特定功能的进程中。

我正在这样做

  1. 获取要注入的DLL的句柄

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

  2. 然后,在驱动程序主内部注册一个LoadImageNotifyRoutine PsSetLoadImageNotifyRoutine(ImageCBK);

应该发生什么:

  1. 我检查是否已加载所需的DLL(将导出我的函数)。
  2. 通过位于调用回调的进程的上下文中,我用ZwCreateSection创建了一个节,然后将dll映射到该节中并通过创建新线程来调用DLL的入口点。
  3. 之后,挂接应该没问题。

即使ZwCreateSectionZwMapViewOfSection的IRQL允许它们在通知例程中使用,但每次我尝试使用它时,ZwMapViewOfSection仍然挂起。 < / p>

我一直在使用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);

可悲的是,它永远不会显示带有DllBaseAddress

的最后一个DbgPrint

1 个答案:

答案 0 :(得分:1)

只需阅读documentation

  

操作系统在以下位置调用驱动程序的加载映像通知例程   PASSIVE_LEVEL始终位于具有正常内核APC的关键区域内   禁用

  

为避免死锁,加载映像通知例程不得调用系统   映射,分配,查询,释放或执行其他操作的例程   在用户空间虚拟内存上。

您忽略此设置,并调用 map 的例程ZwMapViewOfSection。陷入僵局

解决方案简单优雅-将普通内核模式APC插入ImageCBK中的当前线程。因为此APC在此处已禁用-从ImageCBK返回后已执行-只需从关键区域退出系统并启用APC。此时,将调用您的apc KernelRoutine / NormalRoutine。并且必须在NormalRoutine内进行映射