C++ GetFinalPathByHandle为NtQuerySystemInformation返回的所有句柄返回相同的路径

C++ GetFinalPathByHandle为NtQuerySystemInformation返回的所有句柄返回相同的路径,c++,windows,kernel,ntdll,C++,Windows,Kernel,Ntdll,我想检索操作系统中进程访问的所有文件路径。 将检索具有正确句柄值的进程列表。所以现在我想使用GetFinalPathNameByHandle函数来获取这些文件的路径,但是路径变量对于所有记录都是相同的。伙计们,我需要帮忙 源代码在此处:如果无法访问pastebin,则在此处 第66行是我需要帮助的地方。路径对于被测试进程的每个文件处理程序都是相同的,并且等于执行此程序的路径(而不是进程开始文件夹) 我将其作为:testprogram.exe | grep5231运行,其中5231是我需要的进程的

我想检索操作系统中进程访问的所有文件路径。 将检索具有正确句柄值的进程列表。所以现在我想使用
GetFinalPathNameByHandle
函数来获取这些文件的路径,但是路径变量对于所有记录都是相同的。伙计们,我需要帮忙

源代码在此处:如果无法访问pastebin,则在此处

第66行是我需要帮助的地方。路径对于被测试进程的每个文件处理程序都是相同的,并且等于执行此程序的路径(而不是进程开始文件夹)

我将其作为:
testprogram.exe | grep5231
运行,其中5231是我需要的进程的PID

结果如下:

PID: 5231        FileHandlePid: 44       The final path is: \Device\HarddiskVolume4\KillFileHandle\C++\Debug
而这些应该是:

PID: 5231        FileHandlePid: 44       The final path is: \Device\HarddiskVolume2\Users\username\AppData\Roaming\testapp
如果我的预期结果有误,请纠正我


最新增加:

感谢@Raymond Chen的评论,我正努力向前迈进,并使用DuplicateHandle()函数。到目前为止,我已经更新了代码(抱歉,现在是硬编码的pid),添加了HandleValueTemp,试图将其传递给DuplicateHandle。输出更改为不可打印字符

for (i = 0; i < hCount; ++i)
if ((hFirstEntry[i].ObjectType == 28))
{
    HANDLE TargetHandleValueTemp = (HANDLE)hFirstEntry[i].HandleValue;
    HANDLE SourceProcHandleTemp = OpenProcess(PROCESS_DUP_HANDLE, FALSE, hFirstEntry[i].OwnerPid);

    if (!DuplicateHandle(SourceProcHandleTemp, (HANDLE)hFirstEntry[i].HandleValue, GetCurrentProcess(), &TargetHandleValueTemp, 0, FALSE, DUPLICATE_SAME_ACCESS))
    {
        cout << "Error in DuplicateHandle"
    }

    CloseHandle(SourceProcHandleTemp);
    TCHAR Path[MAX_PATH];
    DWORD dwret = GetFinalPathNameByHandle(TargetHandleValueTemp, Path, MAX_PATH, 0);
    _tprintf(TEXT("PID: %d\tFileHandle: %d\tThe final path is: %s\n"), hFirstEntry[i].OwnerPid, TargetHandleValueTemp, Path);
    CloseHandle(TargetHandleValueTemp);
}
for(i=0;icout多亏了@RaymondChen和@HarryJohnston的评论,我才能够得到工作结果。我把它放在这里,以备其他人需要。代码有点糟糕,但进一步的格式取决于你。请记住在测试时将循环中的OwnerPid更新为你自己的

#include <Windows.h>
#include <stdio.h>
#include <string.h>
#include <tchar.h>
#include <iostream>

#define START_ALLOC                 0x1000
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
#define SystemHandleInformation     0x10

typedef long(__stdcall *NtQSI)(
ULONG  SystemInformationClass,
PVOID  SystemInformation,
ULONG  SystemInformationLength,
PULONG ReturnLength
);

typedef struct _SYSTEM_HANDLE_ENTRY {
ULONG  OwnerPid;
BYTE   ObjectType;
BYTE   HandleFlags;
USHORT HandleValue;
PVOID  ObjectPointer;
ACCESS_MASK  AccessMask;
} SYSTEM_HANDLE_ENTRY, *PSYSTEM_HANDLE_ENTRY;

int main()
{
HMODULE hNtDll = NULL;
NtQSI   pNtQSI = NULL;
PVOID   pMem = NULL;
ULONG   allocSize = START_ALLOC;
ULONG   retVal = 0;
// --------------------------------
ULONG   hCount = 0;
PSYSTEM_HANDLE_ENTRY hFirstEntry = NULL;
// --------------------------------
ULONG   i;

hNtDll = LoadLibraryA("NTDLL.dll");

if (!hNtDll)
    return 1;

pNtQSI = (NtQSI)GetProcAddress(hNtDll, "NtQuerySystemInformation");

if (!pNtQSI) {
    FreeLibrary(hNtDll);
    return 2;
}

pMem = malloc(allocSize);

while (pNtQSI(SystemHandleInformation, pMem, allocSize, &retVal)
    == STATUS_INFO_LENGTH_MISMATCH) {
    pMem = realloc(pMem, allocSize *= 2);
}

hCount = *(ULONG*)pMem;
hFirstEntry = (PSYSTEM_HANDLE_ENTRY)((PBYTE)pMem + 4);

for (i = 0; i < hCount; ++i)
if ((hFirstEntry[i].ObjectType == 30) && (hFirstEntry[i].OwnerPid == 5628))
{
    HANDLE TargetHandleValueTemp = (HANDLE)hFirstEntry[i].HandleValue;
    HANDLE SourceProcHandleTemp = OpenProcess(PROCESS_DUP_HANDLE, FALSE, hFirstEntry[i].OwnerPid);

    if (!DuplicateHandle(SourceProcHandleTemp, (HANDLE)hFirstEntry[i].HandleValue, GetCurrentProcess(), &TargetHandleValueTemp, 0, FALSE, DUPLICATE_SAME_ACCESS))
    {
        TargetHandleValueTemp = (HANDLE)hFirstEntry[i].HandleValue;
    }

    CloseHandle(SourceProcHandleTemp);
    TCHAR Path[MAX_PATH];
    DWORD dwret = GetFinalPathNameByHandle(TargetHandleValueTemp, Path, MAX_PATH, 0);
    _tprintf(TEXT("PID: %d\tFileHandle: %d\tThe final path is: %s\n"), hFirstEntry[i].OwnerPid, TargetHandleValueTemp, Path);
    CloseHandle(TargetHandleValueTemp);
}

free(pMem);
FreeLibrary(hNtDll);
}
#包括
#包括
#包括
#包括
#包括
#定义开始分配0x1000
#定义状态信息长度不匹配0xC0000004
#定义系统句柄信息0x10
typedef long(u stdcall*NtQSI)(
ULONG系统信息类,
PVOID系统信息,
ULONG系统长度,
普隆回程长度
);
typedef结构_系统_句柄_条目{
乌龙属;
字节对象类型;
字节句柄;
USHORT HandleValue;
pvoidobjectpointer;
访问掩码访问掩码;
}系统句柄条目,*p系统句柄条目;
int main()
{
HMODULE hNtDll=NULL;
NtQSI pNtQSI=NULL;
PVOID pMem=NULL;
ULONG allocSize=开始\分配;
ULONG retVal=0;
// --------------------------------
ULONG hCount=0;
PSYSTEM\u HANDLE\u ENTRY hFirstEntry=NULL;
// --------------------------------
乌隆一世;
hNtDll=LoadLibraryA(“NTDLL.dll”);
如果(!hNtDll)
返回1;
pNtQSI=(NtQSI)GetProcAddress(HNTDL,“NtQuerySystemInformation”);
如果(!pNtQSI){
免费图书馆;
返回2;
}
pMem=malloc(allocSize);
while(pNtQSI(系统处理信息、pMem、allocSize和retVal)
==状态信息长度不匹配){
pMem=realloc(pMem,allocSize*=2);
}
hCount=*(ULONG*)pMem;
hFirstEntry=(PSYSTEM\u HANDLE\u ENTRY)((PBYTE)pMem+4);
对于(i=0;i
Undocumented API是Undocumented。此外,句柄不是这样工作的。“这是假设您需要删除的所有文件都属于执行删除的进程。”此外,强制关闭句柄可能会导致数据损坏和其他“不可能”的情况Bug。您正在以长期痛苦为代价创建短期缓解。此外,请在此处而不是在外部站点上包含代码。“如果任何文件属于另一个进程,则需要使用DuplicateHandle()执行额外步骤。”但是在这种情况下,您并不是试图强制关闭句柄。另外,您最好有一个调试或单元测试挂钩,这样被测试的应用程序可以显式地提供句柄,而不是让您去寻找它。这样,您就可以避免使用未记录的API。您不必检查GetFinalPathByName中的错误。很快就会发现原因是。在Windows 8.1中,文件的SystemHandleInformation对象类型应为30,而不是以前版本中的28。现在可以工作了