当在堆栈上定义std::wstring时,挂接的NtOpenFile失败



我已经使用mhook library编写了一个挂钩dll。在特殊情况下,当std::wstring被定义为stack var时,NtOpenFile()失败。在heap上定义它,代码为working

除了当某个win32 application(让我们称之为noublish.exe(试图打开现有的测试文件(如c:\temp\anyfile.log(access fails时,代码运行没有问题。然后返回STATUS_INVALID_ACL(0xC0000077(。

我有一行接一行的reduced my code,最后发现当在被调用的函数中定义std::wstring时会发生错误(下面的例子(。每次在不同操作系统的上发生错误

NTSTATUS NtOpenFileApiHook::NtOpenFileHook(PHANDLE              FileHandle,
                                  ACCESS_MASK           DesiredAccess,
                                  POBJECT_ATTRIBUTES    ObjectAttributes,
                                  PIO_STATUS_BLOCK      IoStatusBlock,
                                  ULONG                 ShareAccess,
                                  ULONG                 OpenOptions 
                                  )
{
    NTSTATUS Status = STATUS_SUCCESS;
    // using this function the call will fail
    AfterThis_NtOpenFile_WillFail();
    // using this function INSTEAD the call will work
    AfterThis_NtOpenFile_WillWork();
    // calling the real NtOpenFile using a pointer
    // nothing was changed hier, the original parameters are passed
    Status = RealNtOpenFile(FileHandle, ...);
    return Status;
}
int AfterThis_NtOpenFile_WillFail()
{
    std::wstring String = L"";
    return 0;
}
int AfterThis_NtOpenFile_WillWork()
{
    std::wstring * pString = new std::wstring();
    pString->assign(L"");
    delete pString;
    return 0;
}

我已经为这个电话把它修好了。但我担心其他情况下的其他功能可能会失败,所以我正在寻找原因,(可能(寻找解决方案。

Nuisance.exe是一个带有默认stacksize的C#应用程序,它调用一个win32 dll,对此我一无所知。

如果Nuisance.exe是一个C++应用程序,我可以想象它以类似的方式调用NtOpenFile,在覆盖的堆栈上分配一个指针参数:

   POBJECT_ATTRIBUTES    MakeObjectAttributes()
   {
      POBJECT_ATTRIBUTES oa = {...};
      return &oa; // Pointer to stack variable - UB
   }
   ...
   NtOpenFile(..., MakeObjectAttributes(), ...)

CCD_ 10错误可能表明CCD_ 12中的CCD_。

那么,AfterThis_NtOpenFile_WillFail使用了多少堆栈就很重要了,而且它比AfterThis_NtOpenFile_WillWork多,因为由于小字符串优化,std::wstring将大于几个指针。

如果调用链始终相同,则损坏可能是确定的。

我不知道在C#中是否可以使用与返回临时地址等效的代码。但是DLL可以是C/C++或类似的语言,允许对指针进行数据处理。

要证明/反驳堆栈的作用,请尝试在具有std::wstring大小的堆栈上分配其他数据。更精确的证明可以是检查传递的指针,看看它们是否指向即将被覆盖的堆栈区域。

相关内容

  • 没有找到相关文章

最新更新