我已经钩取了ntdll.dll的NtCreateFile()函数,以允许/拒绝对某些文件的访问。与kernel32.dll的CreateFile()函数不同,后者可以轻松地为您提供有关所讨论的文件的完整路径,而ntdll.dll的NtCreateFile()函数仅提供文件的句柄。我需要从文件句柄获取文件的完整路径,以便随后允许/拒绝访问。我搜索过了,似乎没有一个可行的C#解决方案。
此解决方案是用C++编写的,并由Microsoft进行了文档化。我尝试将其移植到C#,但并没有太大的成功。这是我尝试使用C#等效于“从文件句柄获取文件名”的C++版本:
我当然拥有所有必要的DLLImports和用户定义类型。当我在句柄上使用此函数时,返回一个空字符串。这也很难调试,因为该方法位于注入到目标进程中的DLL中,不像您可以设置断点并享受Visual Studio的调试系统那样。我想我可以编写日志文件或一些跟踪系统,但我还没有那么绝望。我只需要一个成功的C#版本的“从文件句柄获取文件名”。 有什么见解、代码修复、链接吗?
public string GetFileNameFromHandle(IntPtr FileHandle)
{
string fileName = String.Empty;
IntPtr fileMap = IntPtr.Zero, fileSizeHi = IntPtr.Zero;
UInt32 fileSizeLo = 0;
fileSizeLo = GetFileSize(FileHandle, fileSizeHi);
if (fileSizeLo == 0 && fileSizeHi == IntPtr.Zero)
{
// cannot map an 0 byte file
return String.Empty;
}
fileMap = CreateFileMapping(FileHandle, IntPtr.Zero, FileMapProtection.PageReadonly, 0, 1, null);
if (fileMap != IntPtr.Zero)
{
IntPtr pMem = MapViewOfFile(fileMap, FileMapAccess.FileMapRead, 0, 0, 1);
if (pMem != IntPtr.Zero)
{
StringBuilder fn = new StringBuilder(250);
GetMappedFileName(System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle, pMem, fn, 250);
if (fileName.Length > 0)
{
UnmapViewOfFile(pMem);
CloseHandle(FileHandle);
return fn.ToString();
}
else
{
UnmapViewOfFile(pMem);
CloseHandle(FileHandle);
return String.Empty;
}
}
}
return String.Empty;
}
我当然拥有所有必要的DLLImports和用户定义类型。当我在句柄上使用此函数时,返回一个空字符串。这也很难调试,因为该方法位于注入到目标进程中的DLL中,不像您可以设置断点并享受Visual Studio的调试系统那样。我想我可以编写日志文件或一些跟踪系统,但我还没有那么绝望。我只需要一个成功的C#版本的“从文件句柄获取文件名”。 有什么见解、代码修复、链接吗?