-2

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?

  • Why are you trying to inject a dll into another program? And why is the question tagged `reverse-engineering`? –  Jul 29 '20 at 08:32
  • i want to inject my dll to implement the reversed version of that program inside that program – yami sukehiro Jul 29 '20 at 08:38
  • Reversed version? How and what program exactly? –  Jul 29 '20 at 09:44
  • for what you need **add** `PROCESS_QUERY_INFORMATION` ? if this access is need - just open handle with this access. *returns 0x6 errorcode* - mean invalid handle at all. you not show any code and your question\problem is unclear in current form – RbMm Jul 29 '20 at 09:45
  • i need it to get the pid from retrieved handle, zwqueryinformationprocess doesnot work, however it will work if i use openprocess all access to the handle that i want the information to be retrieved, is there anyway to not use openprocess? – yami sukehiro Jul 29 '20 at 10:32
  • XY problem. Why not show code, intstead your proposed solution – user2120666 Jul 29 '20 at 10:41
  • *zwqueryinformationprocess doesnot work* what is mean *doesnot work* ? – RbMm Jul 29 '20 at 11:20
  • How do you get the array of handle? Maybe you are using `NtQuerySystemInformation` with `SYSTEM_INFORMATION_CLASS.SystemHandleInformation`(16). It will return an array size and a `SYSTEM_HANDLE_INFORMATION` array , which contains both `ProcessId` and `Handle` in each `SYSTEM_HANDLE_INFORMATION`. – Drake Wu Jul 30 '20 at 02:48
  • @DrakeWu-MSFT yes indeed, but my target process is a child process which it's parent have multiple processes so i do need to specify the target pid while SYSTEM_HANDLE_INFORMATION processid is pointing to the parent :( please help me i want to hack a game so i can spent my holiday with fun, and i hope u guys having fun looking me fun – yami sukehiro Jul 30 '20 at 09:51

2 Answers2

2

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
Drake Wu
  • 6,927
  • 1
  • 7
  • 30
  • Hi,@yami sukehiro, does the answer help to you? please feel free to let me know if you have any question, or you could [accept](https://stackoverflow.com/help/someone-answers) it if it does help. – Drake Wu Aug 03 '20 at 02:11
  • Yes this is exactly what i already done couple days ago, but my question is is there another way to do this without openprocess? Like simply by changing security context of a process or etc. If no then this answer was helpful thanks for that, case closed – yami sukehiro Aug 11 '20 at 01:17
  • Error 6 has nothing to do with whether you have process_query_information access permission. As I metioned, you need to copy the process handle to current process,otherwise it will not be recognized. – Drake Wu Aug 11 '20 at 01:44
  • what is wrong with error 6 as it said that it was invalid handle error, but why i can open or duplicate that handle if it was an invalid handle? – yami sukehiro Aug 14 '20 at 08:05
  • Invalid handle is relative to the current process,`DuplicateHandle` will specify `hProcess`, this handle is valid for `hProcess`, and then duplicated it to current process. – Drake Wu Aug 14 '20 at 08:10
  • and sorry for additional your code is actualy didn't work for my case because you didn't specify process_query_limited information on your duplicatehandle function but use duplicate_same_access instead, so i just changed the dwdesiredaccess parameter with process_query_limited_information so u can getprocessid on the duplicated handle – yami sukehiro Aug 14 '20 at 08:11
  • So you mean, the target original handle obtained by `NtQuerySystemInformation` does not have process_query_information permission in the target process as well? – Drake Wu Aug 14 '20 at 08:16
  • Honestly, I have no idea about NtQuerySystemInformation.SystemHandleInformation needs process_query_information access right if it does, the handle that i retrieved from that handle is correct according to process hacker(i am using this application for handle check) – yami sukehiro Aug 14 '20 at 08:31
  • so yes, that's what i'm trying to do is to gain process_query_information access rights to that handle without openprocess if it's possible – yami sukehiro Aug 14 '20 at 08:34
  • *your code is actualy didn't work for my case* Can you describe some details? I tested to specify PROCESS_QUERY_LIMITED_INFORMATION, but GetProcessId can still be executed successfully, do you get any errorcode? – Drake Wu Aug 14 '20 at 08:47
  • For what I mean “the target original handle” is, process A open a handle to process B with an access(xxx), then process C call NtQuerySystemInformation, does the xxx contains process_query_information when A open B? Anyway, I can get the process id by C, even the xxx doesn't contains `PROCESS_QUERY_LIMITED_INFORMATION` or `PROCESS_QUERY_INFORMATION`. – Drake Wu Aug 14 '20 at 08:51
  • it still execute indeed but it returns 0 according to msdn getprocessid returns 0 if function fails and it throws errorcode 5 from getlasterror function – yami sukehiro Aug 14 '20 at 08:56
  • 1
    More complicated, as you ask, add access to a handle(still need to duplicate from the source process),use [`SetSecurityInfo`](https://learn.microsoft.com/en-us/windows/win32/api/aclapi/nf-aclapi-setsecurityinfo), refer to [this sample](https://stackoverflow.com/a/6808899/10611792) with `AddAccessAllowedAce` instead of `AddAccessDeniedAce`. – Drake Wu Aug 14 '20 at 08:57
  • Man this helped me a lot thanks for your time, maybe should diving more into access control Model thing godbless u have a nice day sir o7 – yami sukehiro Aug 14 '20 at 09:07
0
    for (SYSTEM_HANDLE a : getAllProcessesHandle()) {
        if ((HANDLE)a.wValue == isthehandleiwant) {
            owner = OpenProcess(PROCESS_DUP_HANDLE, false, a.dwProcessId);
            bool duplicatestatus = DuplicateHandle(owner, (HANDLE)a.wValue, GetCurrentProcess(), &duplicatedHandle, DUPLICATE_SAME_ACCESS, false, 0);
            
        }                       
    }

std::cout << std::dec << GetProcessId(duplicatedHandle) << " TEST " << std::endl;
return duplicatedHandle;