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

时间:2014-10-21 13:18:35

标签: c++ windows kernel ntdll

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

源代码在此处:http://pastebin.com/nU26Vcsd或此处,如果无法访问pastebin http://hastebin.com/wahudogawa.avrasm

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

我将其运行为:testprogram.exe | grep 5231其中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);
}

进一步挖掘并不时查看评论。也许这段代码对其他人有用。

1 个答案:

答案 0 :(得分:0)

感谢@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);
}