TTPwire Vol. 1 · MITRE ATT&CK·Tagged

← All stories

Google Project Zero

A Deep Dive into the GetProcessHandleFromHwnd API

James Forshaw · 2026-02-26 · Read original ↗

ATT&CK techniques detected

26 predictions
T1055.001Dynamic-link Library Injection
99%
"being opened by a different user. of course if the target process was running as an administrator, like in the uac case, it almost certainly will have access to both the caller process as well as the shared memory making this a moot point. one minor change was made in windows 7, …"
T1055.001Dynamic-link Library Injection
98%
"win _ thread - > authid! = curr _ thread - > authid ) { goto access _ denied ; } if ( win _ thread - > tif _ flags & ( tif _ systemthread | tif _ csrssthread ) ) { goto access _ denied ; } kprocess process = null ; dword process _ id = psgetthreadprocessid ( win _ thread - > kthr…"
T1055.001Dynamic-link Library Injection
98%
"versions of windows 11 to access a protected process, not only do you need to disable uipi, and the uipialwayson feature flag but also the responsiblepid feature flag to access the old implementation. the responsiblepid feature flag id is 56032228 if you want to disable it with v…"
T1055.001Dynamic-link Library Injection
97%
"##dle ( hwnd hwnd, access _ mask desiredaccess ) { wnd * wnd = validatehwnd ( wnd ) ; if (! wnd ) { return null ; } threadinfo * curr _ thread = w32getthreadwin32thread ( kegetcurrentthread ( ) ) ; threadinfo * win _ thread = wnd - > thread ; ; if ( curr _ thread - > desktop! = w…"
T1055.001Dynamic-link Library Injection
97%
"_ vm _ read, process _ vm _ write, process _ query _ limited _ information access. typically with this access i ’ d duplicate a copy of the current process pseudo handle to get a full access handle. however due to the way protected processes work this will fail, as the protection…"
T1055.001Dynamic-link Library Injection
96%
"a deep dive into the getprocesshandlefromhwnd api in my previous blog post i mentioned the getprocesshandlefromhwnd api. this was an api i didn ’ t know existed until i found a publicly disclosed uac bypass using the quick assist ui access application. this api looked interesting…"
T1055.001Dynamic-link Library Injection
96%
"it was supported back in windows xp, but that makes little sense for what the api was designed for. checking a copy of the library from xp sp3 doesn ’ t show the api, so we can assume the documentation is incorrect. the api first tries to open the process directly, but if that fa…"
T1055.001Dynamic-link Library Injection
95%
"processes nothing has changed. the second, less important change is that the desired access is now restricted to a limited set of access rights matching the original hook based implementation. the caller can only pass the following access to the function, process _ dup _ handle, …"
T1055.001Dynamic-link Library Injection
95%
"other, that isn ’ t always the case. for example chromium doesn ’ t allow renderers to open each other, and some renderers have more privilege that others for example if they ’ re rendering webui content. fortunately at least in this case renderers run under win32k lockdown meani…"
T1055.001Dynamic-link Library Injection
95%
"hooks was actually secure against accessing protected processes as you can ’ t duplicate a process handle with access rights such as process _ vm _ read from a protected process to a non - protected process. however it was decided it ’ d be better to do it all in kernel mode, but…"
T1548.002Bypass User Account Control
90%
"reporter was the same researcher sascha mayer who found the quick assist ui access bypass that i mentioned earlier. the third version this version ’ s goal was to fix cve - 2023 - 41772 and there are two major changes. first and most importantly, if the uipi check fails, the func…"
T1055.001Dynamic-link Library Injection
86%
"##p, 0, 0, duplicate _ same _ access ) ; interlockedexchange ( buffer, ( dword ) dup ) ; / / cleanup handles etc. } the message parameters are the process id of the caller, who wants to open the process handle and an incrementing counter. these parameters are used to open a named…"
T1134Access Token Manipulation
85%
"reporter was the same researcher sascha mayer who found the quick assist ui access bypass that i mentioned earlier. the third version this version ’ s goal was to fix cve - 2023 - 41772 and there are two major changes. first and most importantly, if the uipi check fails, the func…"
T1055.001Dynamic-link Library Injection
82%
"and target process are running as the same user. the interesting thing about these statements is none of them are completely true. firstly as the previous blog post outlined it ’ s not sufficient to have ui access enabled to use windows hooks, you need to have the same or greater…"
T1055.001Dynamic-link Library Injection
82%
"was a fixed value. the window handle is validated and used to lookup the win32k threadinfo structure for the associated thread and a check is made to ensure both the caller ’ s thread and the target window are on the same desktop. we then get to the uipi enforcement checks, first…"
T1055.001Dynamic-link Library Injection
71%
"i ’ ve already described how to do this in a previous blog post back in 2018 on hijacking a protected process through the use of the com irundown interface. specifically it was possible to force werfaultsecure. exe running at protected tcb level to initialize a com single - threa…"
T1134.004Parent PID Spoofing
70%
"reporter was the same researcher sascha mayer who found the quick assist ui access bypass that i mentioned earlier. the third version this version ’ s goal was to fix cve - 2023 - 41772 and there are two major changes. first and most importantly, if the uipi check fails, the func…"
T1055.001Dynamic-link Library Injection
69%
"session, which would mean if uipi was disabled this wouldn ’ t permit accessing elevated uac processes. the final check is whether the target thread is in the system ( i. e. kernel ) process or a csrss process. if they are then access is denied. finally, the target process is ope…"
T1055.001Dynamic-link Library Injection
51%
"to debug, parent _ pid with your current process id and section _ handle is a handle to a shared memory section containing the following 32 bit integers, 0xf8, pid and tid where pid and tid are the process id and thread id of the dummy debug process. this section handle must be i…"
T1055.001Dynamic-link Library Injection
46%
"cwp - > wparam ; stringcchprintf ( name, _ countof ( name ), l " oleacc _ hook _ shmem _ % d _ % d ", wparam, cwp - > lparam ) ; handle mapping = openfilemapping ( file _ map _ read | file _ map _ write, false, name ) ; dword * buffer = ( dword * ) mapviewoffile ( mapping, file _…"
T1055.012Process Hollowing
46%
"to debug, parent _ pid with your current process id and section _ handle is a handle to a shared memory section containing the following 32 bit integers, 0xf8, pid and tid where pid and tid are the process id and thread id of the dummy debug process. this section handle must be i…"
T1055.001Dynamic-link Library Injection
40%
"change is in ntusergetwindowprocesshandle. the function now has two paths controlled by a feature flag responsiblepid. if the feature flag is disabled it takes the old path, but if it ’ s enabled it calls a new function getwindowprocesshandleunsafe. ironically, contrary to the na…"
T1106Native API
38%
"change is in ntusergetwindowprocesshandle. the function now has two paths controlled by a feature flag responsiblepid. if the feature flag is disabled it takes the old path, but if it ’ s enabled it calls a new function getwindowprocesshandleunsafe. ironically, contrary to the na…"
T1055.001Dynamic-link Library Injection
37%
"= target - > appcontainerno & & current - > appcontainerno! = - 1 & & target - > appcontainerno! = - 1 ) { return false ; } return true : } if the caller ’ s integrity level is greater than the target ’ s, the check is passed immediately. if it ’ s less than the target ’ s then i…"
T1546.008Accessibility Features
34%
"s designed so that other processes at the same level can ’ t open one another. this behavior is presumably because the ppl app level was designed to be used by third party applications from the windows store. the implemented check would allow one ppl app process to open another, …"
T1548.002Bypass User Account Control
31%
"s designed so that other processes at the same level can ’ t open one another. this behavior is presumably because the ppl app level was designed to be used by third party applications from the windows store. the implemented check would allow one ppl app process to open another, …"

Summary

In my previous blog post I mentioned the GetProcessHandleFromHwnd API. This was an API I didn’t know existed until I found a publicly disclosed UAC bypass using the Quick Assist UI Access application. This API looked interesting so I thought I should take a closer look. I typically start by reading the documentation for an API I don’t know about, assuming it’s documented at all. It can give you an idea of how long the API has existed as well as its security properties. The documentation’s remarks contain the following three statements that I thought were interesting: If the caller has UIAccess, however, they can use a windows hook to inject code into the target process, and from within the target process, send a handle back to the caller. GetProcessHandleFromHwnd is a convenience function that uses this technique to obtain the handle of the process that owns the specified HWND. Note that it only succeeds in cases where the caller and target process are running as the same user.