-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathcheck_alertable.cpp
57 lines (49 loc) · 1.97 KB
/
check_alertable.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include "check_alertable.h"
#include <iostream>
// based on Tal Liberman's method and: https://modexp.wordpress.com/2019/08/27/process-injection-apc/
HANDLE find_alertable_by_event(HANDLE hProcess, std::vector<DWORD>& threads)
{
size_t cnt = 0;
HANDLE threadHandles[MAXIMUM_WAIT_OBJECTS] = { 0 };
HANDLE eventHandlesL[MAXIMUM_WAIT_OBJECTS] = { 0 };
HANDLE eventHandlesR[MAXIMUM_WAIT_OBJECTS] = { 0 };
for (auto itr = threads.begin(); itr != threads.end(); ++itr) {
if (cnt == MAXIMUM_WAIT_OBJECTS) break;
DWORD threadId = *itr;
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, threadId);
if (!hThread || hThread == INVALID_HANDLE_VALUE) {
continue;
}
threadHandles[cnt++] = hThread;
}
for (size_t i = 0; i < cnt; i++) {
// 2. create event and duplicate in target process
eventHandlesL[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
DuplicateHandle(
GetCurrentProcess(), // source process
eventHandlesL[i], // source handle to duplicate
hProcess, // target process
&eventHandlesR[i], // target handle
0,
FALSE,
DUPLICATE_SAME_ACCESS);
FARPROC _SetEvent = GetProcAddress(GetModuleHandleA("kernel32.dll"), "SetEvent");
// 3. Queue APC for thread passing target event handle
QueueUserAPC((PAPCFUNC)_SetEvent, threadHandles[i], (ULONG_PTR)eventHandlesR[i]);
}
HANDLE signaledThread = NULL;
// 4. Wait for event to become signalled
DWORD i = WaitForMultipleObjects(cnt, eventHandlesL, FALSE, 1000);
if (i != WAIT_TIMEOUT) {
// 5. save thread handle
signaledThread = threadHandles[i];
}
// 6. Close handles
for (i = 0; i < cnt; i++) {
CloseHandle(eventHandlesL[i]);
if (threadHandles[i] != signaledThread) {
CloseHandle(threadHandles[i]);
}
}
return signaledThread;
}