簡體   English   中英

Windows內核驅動程序:ZwAllocateVirtualMemory導致線程終止

[英]Windows Kernel Driver: ZwAllocateVirtualMemory causing thread to terminate

我正在嘗試編寫一個APC dll注入驅動程序,我找到了這個示例,並想根據自己的需要對其進行修改。

我使用PcreateProcessNotifyRoutineEx來獲取我定位的特定應用程序的ProcessId,在這種情況下為“ iexplore.exe”,然后使用PloadImageNotifyRoutine檢查是否已加載和初始化ntdll.dll(根據此建議 ),以及是否已加載ntdll.dll。 ,我稱之為“我的” InjectDLL函數。

這是調用InjectDll的PloadImageNotifyRoutine函數:

VOID PloadImageNotifyRoutine(
    _In_ PUNICODE_STRING FullImageName,
    _In_ HANDLE ProcessId,
    _In_ PIMAGE_INFO ImageInfo
)
{
    PEPROCESS Process = NULL;
    PETHREAD Thread = NULL;
    PCHAR pTeb = nullptr;
    DWORD ArbitraryUserPointer = 0;
    PCHAR pszProcessNameA = nullptr;

    pTeb = (PCHAR)__readfsdword(0x18);
    ArbitraryUserPointer = *(DWORD*)(pTeb + 0x014);

    // If ArbitraryUserPointer points to kernel32.dll it means ntdll.dll is done loading.
    if (FALSE == IsStringEndWith((wchar_t*)ArbitraryUserPointer, L"\\kernel32.dll"))
    {
        return;
    }

    if (!NT_SUCCESS(PsLookupProcessByProcessId(ProcessId, &Process)))
    {
        return;
    }

    pszProcessNameA = (PCHAR)PsGetProcessImageFileName(Process);
    if (FALSE == StringNCompare(pszProcessNameA, "iexplore.exe", GetStringLength("iexplore.exe")))
    {
        return;
    }

    Thread = KeGetCurrentThread();
    InjectDll(MODULE_PATH, Process, Thread);
    ObDereferenceObject(Process);
}

這是InjectDll函數:

BOOLEAN InjectDll(PWCHAR pModulePath, PEPROCESS Process, PETHREAD Thread)
{
    PKINJECT mem;
    ULONG size;

    mem = NULL;
    size = 4096;

    if (!NT_SUCCESS(ZwAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&mem, 0, &size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)))
    {
        return FALSE;
    }

    //more code ...
}

我在這里刪除了一些檢查,這樣會更清楚。

我嘗試對其進行一些調試,但是ZwAllocateVirtualMemory似乎正在嘗試分配內存,有時會失敗並終止線程。

在調用ExAllocatePoolWithTag之后,它開始釋放內存,取消映射節並終止線程(<=我在調試時在堆棧中看到的調用-並未真正跟蹤每個調用,而是在一般視圖中進行了查看)。

線程終止之前的堆棧:

nt!ExAllocatePoolWithTag+0x195
nt!NtAllocateVirtualMemory+0x1066
nt!KiSystemServicePostCall
nt!ZwAllocateVirtualMemory+0x11
kernel_apc_dll_injector!InjectDll+0x54
kernel_apc_dll_injector!PloadImageNotifyRoutine+0x2b0
nt!PsCallImageNotifyRoutines+0x62

從任務管理器中仍然可以看到該進程,但是該進程的內存為92k,沒有CPU使用率,可能是因為未正確“清理”該進程。

我不知道我的分析是否正確,也許對於這個問題甚至是不必要的。

首先注意-不要從圖像通知例程調用PsLookupProcessByProcessId 根本不需要。 檢查ProcessId == PsGetCurrentProcessId() 如果是,請使用當前進程指針(如您所用,並在調用ZwAllocateVirtualMemory - NtCurrentProcess() ),否則將僅存在。

現在有關主-“ ZwAllocateVirtualMemory導致線程終止”-當然沒有。 線程未終止 掛了 首先,如果線程終止,則-由於此線程在此階段處於進程中-所有進程均終止。 但是您自己說, 該過程仍然可以從任務管理器中看到 還如何查看終止線程的調用堆棧? 這也表示線程沒有終止,而是在ExAllocatePoolWithTag內部ExAllocatePoolWithTag

問題是在某些關鍵區域執行回調,並且您在此例程中可以執行的操作受到限制 (操作系統在禁用了常規內核APC的關鍵區域內的PASSIVE_LEVEL內調用驅動程序的進程通知例程)。 限制之一-稱為ZwAllocateVirtualMemory它掛在回調中,您可以看到。

因此您不能調用ZwAllocateVirtualMemory並直接從回調中進行注入。 但存在解決方案。 將普通內核apc插入當前線程。 它不會就地執行,因為-回調中禁用了常規內核APC。 但在您退出回調並啟用apc之后,您的apc已執行。 在這里(按常規),您已經可以調用ZwAllocateVirtualMemory並進行dll注入

暫無
暫無

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

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