-
Notifications
You must be signed in to change notification settings - Fork 42
/
shim.c
90 lines (74 loc) · 2.26 KB
/
shim.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
/*
* Native 'shim' to assist in reversing JNI code
*
* Tim 'diff' Strazzere
*
* Debug this application with whatever debugger
* you'd prefer, pass the argument for which
* library to load then just debug as normal.
*
* This should cause the "normal" initializers to
* get hit.
*
*/
#include <stdlib.h> // avoid exit warning
#include <stdio.h>
#include <string.h> // strstr
#include <dlfcn.h> // dlopen/dlclose
#include <unistd.h> // access
#include <jni.h> // jni stuff
#include "vm.h"
#if __aarch64__
#define APEX_LIBRARY_PATH "/apex/com.android.runtime/lib64/"
#else
#define APEX_LIBRARY_PATH "/apex/com.android.runtime/lib/"
#endif
typedef int (*JNI_OnLoadFunc)(void* vm, void* reserved);
int main(int argc, char *const argv[]) {
printf("[*] native-shim - diff\n");
printf(" [+] Attempting to load : [ %s ]\n", argv[1]);
if(access(argv[1], F_OK) == -1 ) {
printf(" [!] File does not exist!\n");
return -1;
}
char* path = getenv("LD_LIBRARY_PATH");
if(path == NULL || strstr(path, "apex") == NULL) {
if(setenv("LD_LIBRARY_PATH", APEX_LIBRARY_PATH, 1) != 0) {
printf(" [!] Error setting LD_LIBRARY_PATH via setenv!");
return -1;
} else {
printf(" [+] Success setting env - reloading shim\n");
int rc = execv( "/proc/self/exe", argv);
}
}
// Should call initializers that are not JNI_OnLoad (ex. init_array)
void* handle = dlopen(argv[1], RTLD_LAZY);
if(handle == NULL) {
printf(" [!] Could not dlopen file! (%s)\n", dlerror());
return -1;
}
printf(" [+] Library Loaded!\n");
// Get function call
JNI_OnLoadFunc onLoadFunc = dlsym(handle, "JNI_OnLoad");
if(onLoadFunc == NULL) {
printf(" [!] No JNI_OnLoad found!\n");
return -1;
}
printf(" [+] Initializing JavaVM Instance\n");
JavaVM *vm = NULL;
JNIEnv *env = NULL;
int status = init_jvm(&vm, &env);
if (status == 0) {
printf(" [+] Initialization success (vm=%p, env=%p)\n", vm, env);
} else {
printf(" [!] Initialization failure (%i: %s)\n", status, dlerror());
return -1;
}
printf(" [+] Found JNI_OnLoad, attempting to call\n");
// Depending on the target you likely want to not pass null
onLoadFunc(vm, NULL);
printf(" [+] Closing library\n");
dlclose(handle);
return 0;
}