-
Notifications
You must be signed in to change notification settings - Fork 46
/
trampoline-remote-process-with-dll-injection.cpp
87 lines (69 loc) · 2.8 KB
/
trampoline-remote-process-with-dll-injection.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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include "..\hooking_common.h"
#define TARGET_APP_NAME "B - Target With Free Function From DLL.exe"
#define PAYLOAD_DLL_NAME "13B - Trampoline Imported Func DLL Payload.dll"
#define PAYLOAD_FUNC_NAME "GetNumPayload"
void InjectPayload(HANDLE process, const char* pathToPayloadDLL)
{
//write the name of our dll to the target process' memory
size_t dllPathLen = strlen(pathToPayloadDLL);
void* dllPathRemote = VirtualAllocEx(
process,
NULL, //let the system decide where to allocate the memory
dllPathLen,
MEM_COMMIT, //actually commit the virtual memory
PAGE_READWRITE); //mem access for committed page
check(dllPathRemote);
BOOL writeSucceeded = WriteProcessMemory(
process,
dllPathRemote,
pathToPayloadDLL,
dllPathLen,
NULL);
check(writeSucceeded);
PTHREAD_START_ROUTINE loadLibraryFunc = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32.dll")), "LoadLibraryA");
check(loadLibraryFunc);
//create a thread in remote process that loads our target dll using LoadLibraryA
HANDLE remoteThread = CreateRemoteThread(
process,
NULL, //default thread security
0, //stack size for thread
loadLibraryFunc, //pointer to start of thread function (for us, LoadLibraryA)
dllPathRemote, //pointer to variable being passed to thread function
0, //0 means the thread runs immediately after creation
NULL); //we don't care about getting back the thread identifier
check(remoteThread);
// Wait for the remote thread to terminate
WaitForSingleObject(remoteThread, INFINITE);
//once we're done, free the memory we allocated in the remote process for the dllPathname, and shut down
VirtualFreeEx(process, dllPathRemote, 0, MEM_RELEASE);
CloseHandle(remoteThread);
}
//hacky way to get the path to the correct payload for
//whatever the active build config is... saves having to
//provide the path on the command line, but is otherwise
//not particularly important
void GetPathToPayloadDLL(char* outBuff)
{
char relPath[1024];
char thisAppName[1024];
GetModuleFileName(NULL, relPath, 1024);
GetModuleBaseName(GetCurrentProcess(), NULL, thisAppName, 1024);
char* replaceStart = strstr(relPath, thisAppName);
const char* payloadDLLName = PAYLOAD_DLL_NAME;
memcpy(replaceStart, payloadDLLName, strlen(payloadDLLName));
memset(replaceStart + strlen(payloadDLLName), '\0', &relPath[1024] - (replaceStart + strlen(payloadDLLName)));
_fullpath(outBuff, relPath, 1024);
}
int main(int argc, const char** argv)
{
//5 check(argc == 2);
DWORD processID = FindPidByName(TARGET_APP_NAME);
check(processID);
HANDLE remoteProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
check(remoteProcessHandle);
char fullPath[1024];
GetPathToPayloadDLL(fullPath);
HMODULE mod = FindModuleBaseAddress(remoteProcessHandle, fullPath);
InjectPayload(remoteProcessHandle, fullPath);
return 0;
}