2017-04-19 79 views
0

這是一個相當難解的問題,但我無法弄清楚發生了什麼,我真的需要幫助,所以在這裏!Windows驅動程序/ Rootkit開發 - 函數指針 - STATUS_INVALID_PARAMETER

基本上,我已經編寫了一個安全軟件(作爲內核驅動程序),它將最終掛鉤用於Windows XP的32位SSDT(系統服務描述符表)中的每個方法。每次進行系統調用時,我都將其記錄在一個文件中。

我掛鉤ZwOpenFile時出現了我的問題,因爲這是一個系統調用,我的代碼也打開日誌文件寫入它。所以我得到了一個內核堆棧溢出錯誤,因爲某些東西會調用ZwOpenFile,然後我會嘗試記錄它,然後我的記錄器(這是我的驅動程序的一部分)將調用ZwOpenFile,然後調用ZwOpenFile等等,直到我填滿足以導致藍屏死機。

爲了解決這個問題,我決定,每次調用記錄器函數時,它都會被提供一個指向舊的未解開的ZwOpenFile函數的指針,以便它可以直接調用它,而不是通過我的鉤子函數並創建一個遞歸混亂。但是,當記錄器調用它作爲參數提供的ZwOpenFile函數指針時,它會收到STATUS_INVALID_PARAMETER錯誤。如果直接調用ZwOpenFile(而不是通過指針),它完美地工作!但是當調用指向與SAME參數相同的函數的指針時,它會拋出STATUS_INVALID_PARAMETER錯誤代碼!但是,指針必須指向正確的函數,否則它不會拋出此Windows錯誤消息。這裏的小和(希望)我的代碼更有意義易消化的片段:

*mydriver.h* 
    #define UNICODE 
    #define _UNICODE 
    #include <ntddk.h> 
    #include <ntstrsafe.h> 

    #define OPEN_FILE_INDEX 0x74 

    NTSTATUS newZwOpenFile(
     PHANDLE FileHandle, 
     ACCESS_MASK DesiredAccess, 
     POBJECT_ATTRIBUTES ObjectAttributes, 
     PIO_STATUS_BLOCK IoStatusBlock, 
     ULONG ShareAccess, 
     ULONG OpenOptions); 

    typedef NTSTATUS (*ZwOpenFilePtr)(
     PHANDLE FileHandle, 
     ACCESS_MASK DesiredAccess, 
     POBJECT_ATTRIBUTES ObjectAttributes, 
     PIO_STATUS_BLOCK IoStatusBlock, 
     ULONG ShareAccess, 
     ULONG OpenOptions); 

*mydriver.c* 
    #include "mydriver.h" 
    #include "filehandling.c"   

    //global definition of pointer at top of mydriver.c file  
    ZwOpenFilePtr oldZwOpenFile; 

    NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath){ 
     ... 
     ... 
     //hooks the SSDT using the index of ZwOpenFile in the SSDT 
     oldZwOpenFile = (ZwOpenFilePtr)hookSSDTWithIndex(OPEN_FILE_INDEX, (BYTE*)newZwOpenFile, (DWORD*)systemCallTable); 
     ... 
     ... 
    } 

    //inside the method body of every hooked function, there is, at some point, the a call to the logger. 
    //This is shown in the context of newZwOpenFile 
    NTSTATUS newZwOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions){ 
     ...   
     driverWriteFile(&uFullString, &uProcess, *oldZwOpenFile); 
     ... 
    } 

*filehandling.c* 
    #include <ntstrsafe.h> 

    //the logger file 
    //the function doing the opening and writing 
    NTSTATUS driverWriteFile(PUNICODE_STRING stringToLog, PUNICODE_STRING filename, NTSTATUS (*fileOpenFunction)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,ULONG,ULONG)) { 
     ... 
     //the failing call that returns c000000d 
     ntstatus = fileOpenFunction(&handle, FILE_APPEND_DATA, &objAttr, &ioStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT); 
     ... 
    } 

更重要的是,所有的鉤功能噴涌而出的c000000d錯誤(使用DbgPrint),但一次或兩次,它不知何故成功...任何幫助或建議將深受讚賞!

回答

0

起初您不打電話ZwOpenFile而是NtOpenFile。在第二次從內核調用ZwOpenFile時PreviousMode是內核模式,IopCreateFile不檢查參數(內核的內核信任)。當您撥打NtOpenFilePreviousMode可以是用戶模式並且檢查參數。並且您在呼叫NtOpenFile中使用無效參數 - 您使用FILE_SYNCHRONOUS_IO_ALERT選項,但不要求SYNCHRONIZE處於所需的訪問權限。所以你必須得到STATUS_INVALID_PARAMETER

+0

firsty,謝謝,非常感謝!你爲我節省了很多時間!你是對的!我實際上已經掛鉤了NtOpenFile,因此不檢查參數!我已經解決了同步問題,所以現在我打電話:'ZwOpenFile(&handle,SYNCHRONIZE,&objAttr,&ioStatusBlock,FILE_SHARE_READ | FILE_SHARE_WRITE,FILE_SYNCHRONOUS_IO_ALERT);' 現在我收到了一個不同的錯誤意味着我正在前進),我得到STATUS_ACCESS_VIOLATION。你有什麼想法爲什麼這可能會發生? 我通過在末尾添加'\ 0'來爲我的Unicode字符串添加空終止符。 – Prince

+0

@Prince - 當然你必須得到'STATUS_ACCESS_VIOLATION'因爲你調用**而不是**'ZwOpenFile' **,但是**'NtOpenFile'和[** PreviousMode **](https://msdn.microsoft.com/ en-us/library/windows/hardware/ff559860(v = vs.85).aspx) - 是** UserMode **。從另一邊說'&ioStatusBlock'在你的堆棧中 - 所以內核地址。因爲當檢查參數時 - 如果緩衝區分配在系統內存而不是用戶模式內存中,則ProbeForXxx例程會引發異常,並且NtXxx例程返回STATUS_ACCESS_VIOLATION錯誤代碼。「 - 這是非常基本的事情。」 – RbMm

+0

那麼有沒有辦法解決這個錯誤? – Prince