这是一个很难在网上解释的问题,但我不知道发生了什么,我真的需要帮助,所以就这样吧!
基本上,我已经编写了一个安全软件(作为内核驱动程序),它最终将挂钩 Windows XP - 32 位的 SSDT(系统服务描述符表)中的每个方法。每次进行系统调用时,我都会将其记录在一个文件中。
当我挂钩 ZwOpenFile 时出现了我的问题,因为这是我的代码也用来打开日志文件以写入它的系统调用。所以我得到了一个内核堆栈溢出错误,因为有些东西会调用 ZwOpenFile,然后我会尝试记录它,我的记录器(它是我的驱动程序的一部分)然后会调用 ZwOpenFile,然后它会调用 ZwOpenFile 等等,直到我填满堆栈足够导致蓝屏死机。
为了解决这个问题,我决定,每次调用 logger 函数时,它还将提供一个指向旧的、未挂钩的 ZwOpenFile 函数的指针,以便它可以直接调用它,而不是通过我的挂钩函数并创建一个递归混乱。但是,当记录器调用作为参数提供的 ZwOpenFile 函数指针时,它会收到 STATUS_INVALID_PARAMETER 错误。如果直接调用 ZwOpenFile(而不是通过指针),它就可以完美地工作!但是,当调用指向具有相同参数的函数的指针时,它会抛出 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),但是一两次,它确实成功了......任何帮助或建议将不胜感激!