這是一個相當難解的問題,但我無法弄清楚發生了什麼,我真的需要幫助,所以在這裏!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),但一次或兩次,它不知何故成功...任何幫助或建議將深受讚賞!
firsty,謝謝,非常感謝!你爲我節省了很多時間!你是對的!我實際上已經掛鉤了NtOpenFile,因此不檢查參數!我已經解決了同步問題,所以現在我打電話:'ZwOpenFile(&handle,SYNCHRONIZE,&objAttr,&ioStatusBlock,FILE_SHARE_READ | FILE_SHARE_WRITE,FILE_SYNCHRONOUS_IO_ALERT);' 現在我收到了一個不同的錯誤意味着我正在前進),我得到STATUS_ACCESS_VIOLATION。你有什麼想法爲什麼這可能會發生? 我通過在末尾添加'\ 0'來爲我的Unicode字符串添加空終止符。 – Prince
@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
那麼有沒有辦法解決這個錯誤? – Prince