-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathInjectDLLNative.c
More file actions
84 lines (71 loc) · 3.81 KB
/
InjectDLLNative.c
File metadata and controls
84 lines (71 loc) · 3.81 KB
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
#include <windows.h>
#include <jni.h>
#include <stdint.h>
#include <stdio.h>
typedef DWORD NTSTATUS;
typedef NTSTATUS (__stdcall *PFN_SysAllocateVirtualMemoryEx)(
HANDLE, PVOID*, SIZE_T*, DWORD, DWORD, PVOID, DWORD);
typedef NTSTATUS (__stdcall *PFN_SysWriteVirtualMemory)(
HANDLE, PVOID, PVOID, SIZE_T, SIZE_T*);
typedef NTSTATUS (__stdcall *PFN_SysCreateThreadEx)(
PHANDLE, DWORD, PVOID, HANDLE, PVOID, PVOID, DWORD,
SIZE_T, SIZE_T, SIZE_T, PVOID);
typedef NTSTATUS (__stdcall *PFN_SysClose)(HANDLE);
#define NT_SUCCESS(Status) ((int32_t)(Status) >= 0)
static jboolean inject_internal(DWORD pid, const char* dllPath) {
HMODULE hSysCaller = LoadLibraryA("SysCaller.dll");
if (!hSysCaller) {
return JNI_FALSE;
}
PFN_SysAllocateVirtualMemoryEx SysAllocateVirtualMemoryEx = (PFN_SysAllocateVirtualMemoryEx)GetProcAddress(hSysCaller, "SysAllocateVirtualMemoryEx");
PFN_SysWriteVirtualMemory SysWriteVirtualMemory = (PFN_SysWriteVirtualMemory)GetProcAddress(hSysCaller, "SysWriteVirtualMemory");
PFN_SysCreateThreadEx SysCreateThreadEx = (PFN_SysCreateThreadEx)GetProcAddress(hSysCaller, "SysCreateThreadEx");
PFN_SysClose SysClose = (PFN_SysClose)GetProcAddress(hSysCaller, "SysClose");
if (!SysAllocateVirtualMemoryEx || !SysWriteVirtualMemory || !SysCreateThreadEx || !SysClose) {
return JNI_FALSE;
}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!hProcess) return JNI_FALSE;
char absPath[MAX_PATH];
DWORD n = GetFullPathNameA(dllPath, MAX_PATH, absPath, NULL);
const char* usePath = (n > 0 && n < MAX_PATH) ? absPath : dllPath;
SIZE_T pathLen = (SIZE_T)strlen(usePath) + 1;
PVOID base = NULL; SIZE_T region = pathLen; NTSTATUS status;
status = SysAllocateVirtualMemoryEx(hProcess, &base, ®ion, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE, NULL, 0);
if (!NT_SUCCESS(status)) { CloseHandle(hProcess); return JNI_FALSE; }
SIZE_T written = 0;
status = SysWriteVirtualMemory(hProcess, base, (PVOID)usePath, pathLen, &written);
if (!NT_SUCCESS(status) || written != pathLen) { CloseHandle(hProcess); return JNI_FALSE; }
HMODULE k32 = GetModuleHandleA("kernel32.dll");
FARPROC pLoadLib = GetProcAddress(k32, "LoadLibraryA");
if (!pLoadLib) { CloseHandle(hProcess); return JNI_FALSE; }
uint8_t sc[32]; int idx = 0;
sc[idx++] = 0x48; sc[idx++] = 0x83; sc[idx++] = 0xEC; sc[idx++] = 0x28;
sc[idx++] = 0x48; sc[idx++] = 0xB9; *(uint64_t*)(sc+idx) = (uint64_t)base; idx += 8;
sc[idx++] = 0x48; sc[idx++] = 0xB8; *(uint64_t*)(sc+idx) = (uint64_t)pLoadLib; idx += 8;
sc[idx++] = 0xFF; sc[idx++] = 0xD0;
sc[idx++] = 0x48; sc[idx++] = 0x83; sc[idx++] = 0xC4; sc[idx++] = 0x28;
sc[idx++] = 0xC3;
SIZE_T scSize = (SIZE_T)idx;
PVOID scAddr = NULL; region = scSize;
status = SysAllocateVirtualMemoryEx(hProcess, &scAddr, ®ion, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE, NULL, 0);
if (!NT_SUCCESS(status)) { CloseHandle(hProcess); return JNI_FALSE; }
written = 0;
status = SysWriteVirtualMemory(hProcess, scAddr, sc, scSize, &written);
if (!NT_SUCCESS(status) || written != scSize) { CloseHandle(hProcess); return JNI_FALSE; }
HANDLE hThread = NULL;
status = SysCreateThreadEx(&hThread, 0x1FFFFF, NULL, hProcess, scAddr, NULL, 0, 0, 0, 0, NULL);
if (!NT_SUCCESS(status) || !hThread) { CloseHandle(hProcess); return JNI_FALSE; }
WaitForSingleObject(hThread, 5000);
SysClose(hThread);
CloseHandle(hProcess);
return JNI_TRUE;
}
JNIEXPORT jboolean JNICALL Java_InjectDLL_inject(JNIEnv* env, jclass cls, jint pid, jstring jpath) {
(void)cls;
const char* path = (*env)->GetStringUTFChars(env, jpath, NULL);
if (!path) return JNI_FALSE;
jboolean ok = inject_internal((DWORD)pid, path);
(*env)->ReleaseStringUTFChars(env, jpath, path);
return ok;
}