GetFinalPathByHandle возвращает один и тот же путь для всех дескрипторов, возвращаемых NtQuerySystemInformation

Я хочу получить все пути к файлам, к которым обращаются процессы в моей ОС.
Список процессов извлекается, и те имеют правильные значения дескриптора. Так что теперь я хочу использовать GetFinalPathNameByHandle функция для получения пути к этим файлам, но переменная Path одинакова для всех записей. Мне нужна помощь, ребята.

Исходный код здесь: http://pastebin.com/nU26Vcsd или здесь, если пастин не доступен 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

Решение

Благодаря комментариям @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);
}
0

Другие решения


По вопросам рекламы [email protected]