-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathjvm_dumper.c
114 lines (101 loc) · 2.84 KB
/
jvm_dumper.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
#include "jvm_dumper.h"
#include "MinHook.h"
#include <stdio.h>
const char* folderName = "C:\\JavaClassDump\\";
/* Convert java string to UTF char*. Use local buffer if possible,
otherwise malloc new memory. Returns null IFF malloc failed. */
static char* getUTF(JNIEnv* env, jstring str, char* localBuf, int bufSize)
{
char* utfStr = NULL;
int len = (*env)->GetStringUTFLength(env, str);
int unicode_len = (*env)->GetStringLength(env, str);
if (len >= bufSize) {
utfStr = malloc(len + 1);
if (utfStr == NULL) {
return NULL;
}
}
else {
utfStr = localBuf;
}
(*env)->GetStringUTFRegion(env, str, 0, unicode_len, utfStr);
return utfStr;
}
#define SKIP_JAVA_CLASSES = true;
jclass JNICALL hookedDefineClass(JNIEnv* env, jobject loader, jstring name, jbyteArray data, jint offset, jint length, jobject pd, jstring source) {
if (data == NULL || length < 0) {
return defineClassV_(env, loader, name, data, offset, length, pd, source);
}
jbyte* body = (jbyte*)malloc(length);
if (body == NULL) {
perror("Malloc failed, OutOfMemory exception!");
return;
}
(*env)->GetByteArrayRegion(env, data, offset, length, body);
if ((*env)->ExceptionOccurred(env)) {
goto free_mem;
}
const char* utfName;
char buf[128];
if (name != NULL) {
utfName = getUTF(env, name, buf, sizeof(buf));
if (utfName == NULL) {
goto free_mem;
}
}
else {
goto free_mem;
}
printf("Class name %s\n", utfName);
#ifdef SKIP_JAVA_CLASSES
if (strstr(utfName, "java.lang")) {
goto free_mem;
}
#endif
char finalName[128];
snprintf(finalName, 128, "%s.class", utfName);
char fullPath[1024];
snprintf(fullPath, 1024, "%s%s", folderName, finalName);
FILE* out = fopen(fullPath, "wb");
fwrite(body, 1, (*env)->GetArrayLength(env, data), out);
fclose(out);
goto free_mem;
free_mem:
free(body);
return defineClassV_(env, loader, name, data, offset, length, pd, source);
}
boolean started = 0;
void hookSetup(void) {
if (started) return;
started = 1;
AllocConsole();
FILE* fIn;
FILE* fOut;
freopen_s(&fIn, "conin$", "r", stdin);
freopen_s(&fOut, "conout$", "w", stdout);
freopen_s(&fOut, "conout$", "w", stderr);
if (MH_Initialize() != MH_OK) {
puts("Error while initializing hooks!");
return;
}
HMODULE module = GetModuleHandleA("java.dll");
if (!module) {
puts("java.dll module not found!");
return;
}
void* defineClass = (void*)GetProcAddress(module, "Java_java_lang_ClassLoader_defineClass1");
if (!defineClass) {
puts("defineClass function not found!");
return;
}
if (MH_CreateHook((void*)defineClass, (void*)hookedDefineClass, (void**)(&defineClassV_)) != MH_OK) {
puts("Creating hook failed!");
return;
}
if (MH_EnableHook((void*)defineClass) != MH_OK) {
puts("Enabling hook failed!");
return;
}
CreateDirectoryA(folderName, NULL);
puts("Java Runtime Class Dumper created by TheEasyPeasy (https://github.com/TheEasyPeasy)");
}