这在线解释是一个相当困难的问题,但是我无法弄清楚发生了什么,我真的需要帮助,所以这就行了!
基本上,我编写了一个安全软件(作为内核驱动程序),它最终会挂钩用于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),但是一次或两次,它确实会成功...任何帮助或建议都会非常感激!< / p>
答案 0 :(得分:0)
首先,您不是ZwOpenFile
而是NtOpenFile
。在第二个时,从内核 PreviousMode 调用ZwOpenFile
是内核模式而IopCreateFile
不检查参数(内核对内核的信任)。当您致电NtOpenFile
PreviousMode 时,可以使用用户模式并检查参数。并且您在调用NtOpenFile
中使用了无效参数 - 您使用FILE_SYNCHRONOUS_IO_ALERT
选项但不要求所需访问权限SYNCHRONIZE
。所以你必须得到STATUS_INVALID_PARAMETER
。