0

这是一个很难在网上解释的问题,但我不知道发生了什么,我真的需要帮助,所以就这样吧!

基本上,我已经编写了一个安全软件(作为内核驱动程序),它最终将挂钩 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),但是一两次,它确实成功了......任何帮助或建议将不胜感激!

4

1 回答 1

0

起初你叫 not ZwOpenFilebut NtOpenFile。第二次ZwOpenFile从内核调用PreviousMode是内核模式并且IopCreateFile不检查参数(内核信任内核)。当您调用NtOpenFile PreviousMode时可以是用户模式并检查参数。并且您在调用中使用了无效参数NtOpenFile-您使用FILE_SYNCHRONOUS_IO_ALERT选项但没有要求获得SYNCHRONIZE所需的访问权限。所以你必须得到STATUS_INVALID_PARAMETER

于 2017-04-28T22:41:23.267 回答