i'm absolute beginner to this, i've been trying to collect handle on my system using ntquerysysteminformation and now i get the handle that i want(i know this by using processhacker) but the problem coming when i try to collect the pid from that handle in order to determine which handle that is correct to inject my dll(my function returns array of handle), i know it can be simply use getprocessid() from msdn but it returns 0x6 errorcode.
is there another graceful way to do this without using openprocess? *duplicatehandle() doesn't seems to work as well
or is there a way to simply add process_query_information access right to this handle?
Since we are in an external process, so it makes no sense to distribute the handle provided by NtQuerySystemInformation
, you need to copy the handle into our own process.
source process for testing:
#include <Windows.h>
#include <iostream>
#include <fstream>
int main()
{
HANDLE hprocess = OpenProcess(PROCESS_VM_READ,false,10924);//any access without PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION
printf("pid: %d\n", GetCurrentProcessId());
printf("handle: 0x%x\nwait...\n", hprocess);
getchar();
CloseHandle(hprocess);
return 0;
}
Result:
pid: 11972
handle: 0x108
wait...
main process:
#include <Windows.h>
#include <iostream>
using namespace std;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
}SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;
typedef struct _SYSTEM_HANDLE_INFORMATION_EX
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_INFORMATION Information[655360];//This is the size I defined myself
}SYSTEM_HANDLE_INFORMATION_EX, * PSYSTEM_HANDLE_INFORMATION_EX;
#define SystemHandleInformation 0x10
typedef NTSTATUS(WINAPI* NTQUERYSYSTEMINFORMATION)(DWORD, PVOID, DWORD, PDWORD);
int main()
{
HMODULE hNtDll = LoadLibraryW(L"ntdll.dll");
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll, "NtQuerySystemInformation");
ULONG cbBuffer = sizeof(SYSTEM_HANDLE_INFORMATION_EX);
LPVOID pBuffer = (LPVOID)malloc(cbBuffer);
if (pBuffer)
{
NTSTATUS status = NtQuerySystemInformation(SystemHandleInformation, pBuffer, cbBuffer, NULL);
PSYSTEM_HANDLE_INFORMATION_EX pInfo = (PSYSTEM_HANDLE_INFORMATION_EX)pBuffer;
DWORD pid = 0;
int err = 0;
for (ULONG r = 0; r < pInfo->NumberOfHandles; r++)
{
if (pInfo->Information[r].ProcessId == 11972 && pInfo->Information[r].Handle == 0x108)//hard code to test
{
if ((pid = GetProcessId((HANDLE)pInfo->Information[r].Handle)) == 0)
{
err = GetLastError();
cout << "The 1st GetProcessId error : " << err << endl;
}
HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, false, pInfo->Information[r].ProcessId);
HANDLE hTarget;
if (!DuplicateHandle(hProcess, (HANDLE)pInfo->Information[r].Handle, ::GetCurrentProcess(), &hTarget, PROCESS_QUERY_LIMITED_INFORMATION, FALSE, 0))
{
err = GetLastError();
cout << "DuplicateHandle error : " << err << endl;
return -1;
}
if ((pid = GetProcessId(hTarget)) == 0)
{
err = GetLastError();
cout << "GetProcessId error : " << err << endl;
return -1;
}
cout << "The 2nd GetProcessId succeed, " << "ProcessId = " << pid << endl;
}
}
free(pBuffer);
}
FreeModule(hNtDll);
getchar();
}
Result:
The 1st GetProcessId error : 6
The 2nd GetProcessId succeed, ProcessId = 10924