Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/HostingCLR_inject/HostingCLR/ReflectiveFree.cpp
19812 views
1
#include "stdafx.h"
2
#include "ReflectiveFree.h"
3
#include <Windows.h>
4
5
typedef NTSTATUS
6
(NTAPI *NtQueueApcThread)(
7
HANDLE ThreadHandle,
8
PVOID ApcRoutine,
9
ULONG_PTR SystemArgument1,
10
ULONG_PTR SystemArgument2,
11
ULONG_PTR SystemArgument3
12
);
13
14
VOID ReflectiveFree(HINSTANCE hAppInstance) {
15
NtQueueApcThread pNtQueueApcThread = (NtQueueApcThread)GetProcAddress(GetModuleHandle(TEXT("ntdll")), "NtQueueApcThread");
16
HANDLE hThread = NULL;
17
HANDLE hThisThread = NULL;
18
do {
19
if (!pNtQueueApcThread)
20
break;
21
22
// create a suspended thread that will just exit once the APCs have executed
23
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ExitThread, 0, CREATE_SUSPENDED, NULL);
24
if (!hThread)
25
break;
26
27
// open a real handle to this thread to pass in the APC so it operates on this thread and not itself
28
hThisThread = OpenThread(THREAD_QUERY_INFORMATION | SYNCHRONIZE, FALSE, GetCurrentThreadId());
29
if (!hThisThread)
30
{
31
break;
32
}
33
34
35
// The other thread will:
36
// - Wait for us: WaitForSingleObjectEx(hThisThread, INFINITE, FALSE);
37
// - Close the handle we opened: CloseHandle(hThisThread);
38
// - Free the memory: VirtualFree(hAppInstance, 0, MEM_RELEASE);
39
40
// tell that thread to wait on this thread, ensures VirtualFree isn't called until this thread has exited
41
NTSTATUS status = pNtQueueApcThread(hThread, WaitForSingleObjectEx, (ULONG_PTR)hThisThread, INFINITE, FALSE);
42
43
// then close the handle so it's not leaked
44
QueueUserAPC((PAPCFUNC)CloseHandle, hThread, (ULONG_PTR)hThisThread);
45
// then free the memory
46
status = pNtQueueApcThread(hThread, VirtualFree, (ULONG_PTR)hAppInstance, 0, MEM_RELEASE);
47
ResumeThread(hThread);
48
} while (FALSE);
49
50
if (hThread)
51
{
52
CloseHandle(hThread);
53
}
54
}
55
56
VOID ReflectiveFreeAndExitThread(HINSTANCE hAppInstance, DWORD dwExitCode) {
57
ReflectiveFree(hAppInstance);
58
59
ExitThread(dwExitCode);
60
return;
61
}
62