You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows内核驱动:ZwAllocateVirtualMemory引发线程终止问题

Troubleshooting APC DLL Injection Crash in Kernel Driver

Let's break down your problem and walk through targeted fixes to get your injection working reliably:

First, Context on the Crash

Your stack trace points to a failure originating in nt!ExAllocatePoolWithTag during the ZwAllocateVirtualMemory call in your InjectDll function. The target iexplore.exe ends up in a zombie state (92KB memory, no CPU activity) because the thread handling the image load crashed without proper cleanup. Let's dig into the most likely causes:


Likely Root Causes & Fixes

1. You're Operating in the Wrong Process Context

PsLoadImageNotifyRoutine doesn't always run in the context of the target process. If you're using NtCurrentProcess() assuming it points to iexplore.exe, you're probably modifying the wrong process (or running in a system thread context, which will trigger access violations).

Fix:

  • Verify you're in the target process context by comparing PsGetCurrentProcessId() to the ProcessId passed to the notify routine.
  • If not, explicitly attach to the target process before any memory operations:
    PEPROCESS targetProcess;
    NTSTATUS status = PsLookupProcessByProcessId(targetPid, &targetProcess);
    if (!NT_SUCCESS(status)) { /* handle error and exit */ }
    
    KAPC_STATE apcState;
    KeStackAttachProcess(targetProcess, &apcState);
    
    // Your ZwAllocateVirtualMemory and injection logic here
    
    KeUnstackDetachProcess(&apcState);
    ObDereferenceObject(targetProcess);
    

2. Invalid Parameters to ZwAllocateVirtualMemory

Bad flags, insufficient process permissions, or invalid handles are common culprits here.

Checklist:

  • Open the target process with explicit privileges: Use ZwOpenProcess with PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD access rights—don't rely on implicit context.
  • Validate your allocation parameters:
    • AllocationType: Use MEM_COMMIT | MEM_RESERVE to properly reserve and commit memory.
    • Protect: Start with PAGE_READWRITE (you can change it to PAGE_EXECUTE_READWRITE later if needed for APC execution).
    • Size: Allocate at least MAX_PATH bytes to fit your DLL path (plus a null terminator).
  • Always check the NTSTATUS return value of ZwAllocateVirtualMemory—don't proceed if allocation fails.

3. Misuse of ExAllocatePoolWithTag

If your InjectDll function calls ExAllocatePoolWithTag directly (e.g., for buffer allocation), invalid parameters here can cause pool corruption or allocation failures.

Fix:

  • Use modern, safe pool types like NonPagedPoolNx (avoid deprecated types like NonPagedPool).
  • Validate the requested size—ensure it's not 0 or excessively large.
  • Check if the allocation returns NULL and handle that case gracefully (don't dereference a null pointer).
  • Always free pool memory with ExFreePoolWithTag when done to avoid leaks.

4. Premature Injection Timing

Even if ArbitraryUserPointer points to kernel32.dll, the process might not be fully initialized. ntdll.dll loads early, but kernel32's initialization routines may still be running, making the process unstable for memory operations.

Fix:

  • Delay injection until the process reaches a stable state:
    • Check the process's PEB to confirm LdrInitializeThunk has completed (verify PEB->Ldr->InInitializationOrderModuleList includes critical modules).
    • Use a kernel timer (KeSetTimer) to wait a short interval (e.g., 500ms) after detecting the image load before triggering injection.
    • Alternatively, track process creation via PsSetCreateProcessNotifyRoutineEx and wait for the main thread to start executing user-mode code.

5. Unhandled Errors Leading to Crashes

Skipping error checks for kernel API calls (like PsLookupProcessByProcessId or ZwOpenProcess) can lead to invalid memory accesses or pool corruption.

Fix:

  • Add robust error handling to every kernel call. For example:
    NTSTATUS status = ZwAllocateVirtualMemory(processHandle, &baseAddress, 0, &size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (!NT_SUCCESS(status)) {
        DbgPrint("ZwAllocateVirtualMemory failed: 0x%X\n", status);
        // Clean up resources and return early
        return status;
    }
    

Debugging Tips

  • Set a breakpoint on ExAllocatePoolWithTag and inspect the parameters (pool type, size) when the crash occurs—this will reveal if you're requesting an invalid allocation.
  • Use !process <targetPid> 2 in WinDbg to check the process's state—look for signs of pending termination or invalid thread states.
  • Enable pool tagging (!pooltag in WinDbg) to detect if your allocations are causing pool corruption.

内容的提问来源于stack exchange,提问作者Oriel Cochavi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:23:33