CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

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