Skip to content

Commit 7f3f6ee

Browse files
committed
feat: major changes
1 parent 5ccd915 commit 7f3f6ee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1320
-469
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# ShadowHook
22

33
![](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)
4-
![](https://img.shields.io/badge/release-1.0.10-red.svg?style=flat)
4+
![](https://img.shields.io/badge/release-1.1.1-red.svg?style=flat)
55
![](https://img.shields.io/badge/Android-4.1%20--%2015-blue.svg?style=flat)
66
![](https://img.shields.io/badge/arch-armeabi--v7a%20%7C%20arm64--v8a-blue.svg?style=flat)
77

@@ -49,7 +49,7 @@ android {
4949
}
5050
5151
dependencies {
52-
implementation 'com.bytedance.android:shadowhook:1.0.10'
52+
implementation 'com.bytedance.android:shadowhook:1.1.1'
5353
}
5454
```
5555

@@ -102,6 +102,7 @@ If you are using ShadowHook in an SDK project, you may need to avoid packaging l
102102
android {
103103
packagingOptions {
104104
exclude '**/libshadowhook.so'
105+
exclude '**/libshadowhook_nothing.so'
105106
}
106107
}
107108
```
@@ -112,6 +113,7 @@ On the other hand, if you are using ShadowHook in an APP project, you may need t
112113
android {
113114
packagingOptions {
114115
pickFirst '**/libshadowhook.so'
116+
pickFirst '**/libshadowhook_nothing.so'
115117
}
116118
}
117119
```

README.zh-CN.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# ShadowHook
22

33
![](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)
4-
![](https://img.shields.io/badge/release-1.0.10-red.svg?style=flat)
4+
![](https://img.shields.io/badge/release-1.1.1-red.svg?style=flat)
55
![](https://img.shields.io/badge/Android-4.1%20--%2015-blue.svg?style=flat)
66
![](https://img.shields.io/badge/arch-armeabi--v7a%20%7C%20arm64--v8a-blue.svg?style=flat)
77

@@ -49,7 +49,7 @@ android {
4949
}
5050
5151
dependencies {
52-
implementation 'com.bytedance.android:shadowhook:1.0.10'
52+
implementation 'com.bytedance.android:shadowhook:1.1.1'
5353
}
5454
```
5555

@@ -102,6 +102,7 @@ android {
102102
android {
103103
packagingOptions {
104104
exclude '**/libshadowhook.so'
105+
exclude '**/libshadowhook_nothing.so'
105106
}
106107
}
107108
```
@@ -112,6 +113,7 @@ android {
112113
android {
113114
packagingOptions {
114115
pickFirst '**/libshadowhook.so'
116+
pickFirst '**/libshadowhook_nothing.so'
115117
}
116118
}
117119
```

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ android {
4545
}
4646
packagingOptions {
4747
jniLibs {
48-
pickFirsts += ['**/libshadowhook.so']
48+
pickFirsts += ['**/libshadowhook.so', '**/libshadowhook_nothing.so']
4949
}
5050
if (rootProject.ext.useASAN) {
5151
doNotStrip "**/*.so"

app/src/main/cpp/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cmake_minimum_required(VERSION 3.22.1)
1+
cmake_minimum_required(VERSION 3.30.5)
22
project(app)
33
enable_language(ASM)
44

app/src/main/cpp/hookee/arch/arm/t16.S

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,16 @@ ENTRY_GLOBAL_THUMB(test_t16_it_t1_case2)
209209
bx lr
210210
END(test_t16_it_t1_case2)
211211

212+
ENTRY_GLOBAL_THUMB(test_t16_it_t1_case3)
213+
cmp r0, r0 // Compare r0 with 0
214+
itete ne // If-Then-Else-Then-Else block for Not Equal
215+
addne r1, r1, #1 // If r0 != 0, add 1 to r1
216+
addeq r2, r2, #2 // If r0 == 0, add 2 to r2
217+
subne r3, r3, #3 // If r0 != 0, subtract 3 from r3
218+
moveq r4, #4 // If r0 == 0, move 4 to r4
219+
b test_t16_helper_global
220+
END(test_t16_it_t1_case3)
221+
212222

213223
ENTRY_HIDDEN_THUMB(test_t16_helper_hidden_tail)
214224
add r0, r0, r1

app/src/main/cpp/hookee/hookee.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ int test_t16_cbnz_t1(int a, int b);
4141
int test_t16_cbnz_t1_fixaddr(int a, int b);
4242
int test_t16_it_t1_case1(int a, int b);
4343
int test_t16_it_t1_case2(int a, int b);
44+
int test_t16_it_t1_case3(int a, int b);
4445

4546
int test_t32_helper_global(int a, int b);
4647
int test_t32_b_t3(int a, int b);

app/src/main/cpp/unittest/unittest.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,55 @@ static int hook_dlopen(int api_level) {
223223
return result;
224224
}
225225

226+
#define SH_LINKER_SYM_CALL_CONSTRUCTORS_L "__dl__ZN6soinfo16CallConstructorsEv"
227+
#define SH_LINKER_SYM_CALL_DESTRUCTORS_L "__dl__ZN6soinfo15CallDestructorsEv"
228+
#define SH_LINKER_SYM_CALL_CONSTRUCTORS_M "__dl__ZN6soinfo17call_constructorsEv"
229+
#define SH_LINKER_SYM_CALL_DESTRUCTORS_M "__dl__ZN6soinfo16call_destructorsEv"
230+
231+
typedef void (*linker_proxy_soinfo_call_ctors_t)(void *);
232+
static linker_proxy_soinfo_call_ctors_t linker_orig_soinfo_call_ctors;
233+
static void linker_proxy_soinfo_call_ctors(void *soinfo) {
234+
if (SHADOWHOOK_IS_SHARED_MODE)
235+
SHADOWHOOK_CALL_PREV(linker_proxy_soinfo_call_ctors, linker_proxy_soinfo_call_ctors_t, soinfo);
236+
else
237+
linker_orig_soinfo_call_ctors(soinfo);
238+
239+
if (SHADOWHOOK_IS_SHARED_MODE) SHADOWHOOK_POP_STACK();
240+
}
241+
242+
typedef void (*linker_proxy_soinfo_call_dtors_t)(void *);
243+
static linker_proxy_soinfo_call_dtors_t linker_orig_soinfo_call_dtors;
244+
static void linker_proxy_soinfo_call_dtors(void *soinfo) {
245+
if (SHADOWHOOK_IS_SHARED_MODE)
246+
SHADOWHOOK_CALL_PREV(linker_proxy_soinfo_call_dtors, linker_proxy_soinfo_call_dtors_t, soinfo);
247+
else
248+
linker_orig_soinfo_call_dtors(soinfo);
249+
250+
if (SHADOWHOOK_IS_SHARED_MODE) SHADOWHOOK_POP_STACK();
251+
}
252+
253+
static int hook_call_ctors_dtors(int api_level) {
254+
static int result = -1;
255+
static bool hooked = false;
256+
257+
if (hooked) return result;
258+
hooked = true;
259+
260+
void *stub_ctors = shadowhook_hook_sym_name(
261+
LINKER_BASENAME,
262+
api_level >= __ANDROID_API_M__ ? SH_LINKER_SYM_CALL_CONSTRUCTORS_M : SH_LINKER_SYM_CALL_CONSTRUCTORS_L,
263+
(void *)linker_proxy_soinfo_call_ctors, (void **)&linker_orig_soinfo_call_ctors);
264+
int errno_ctors = shadowhook_get_errno();
265+
void *stub_dtors = shadowhook_hook_sym_name(
266+
LINKER_BASENAME,
267+
api_level >= __ANDROID_API_M__ ? SH_LINKER_SYM_CALL_DESTRUCTORS_M : SH_LINKER_SYM_CALL_DESTRUCTORS_L,
268+
(void *)linker_proxy_soinfo_call_dtors, (void **)&linker_orig_soinfo_call_dtors);
269+
int errno_dtors = shadowhook_get_errno();
270+
271+
result = (NULL != stub_ctors && NULL != stub_dtors && 0 == errno_ctors && 0 == errno_dtors) ? 0 : -1;
272+
return result;
273+
}
274+
226275
// end of - hooking dlopen() or do_dlopen()
227276
///////////////////////////////////////////////////////////////////////////
228277

@@ -270,6 +319,7 @@ PROXY(t16_cbnz_t1)
270319
PROXY(t16_cbnz_t1_fixaddr)
271320
PROXY(t16_it_t1_case1)
272321
PROXY(t16_it_t1_case2)
322+
PROXY(t16_it_t1_case3)
273323

274324
PROXY(t32_b_t3)
275325
PROXY(t32_b_t4)
@@ -398,6 +448,13 @@ static int unittest_hook(int api_level) {
398448
return -1;
399449
}
400450

451+
if (api_level >= __ANDROID_API_L__) {
452+
if (0 != hook_call_ctors_dtors(api_level)) {
453+
LOG("hook soinfo::call_constructors() and get soinfo::call_destructors() FAILED");
454+
return -1;
455+
}
456+
}
457+
401458
#if defined(__arm__)
402459

403460
HOOK(t16_b_t1);
@@ -454,6 +511,7 @@ static int unittest_hook(int api_level) {
454511
HOOK(a32_ldr_lit_a1_case2);
455512
HOOK(a32_ldr_reg_a1_case1);
456513
HOOK(a32_ldr_reg_a1_case2);
514+
HOOK(t16_it_t1_case3);
457515

458516
#elif defined(__aarch64__)
459517

@@ -538,6 +596,7 @@ int unittest_unhook(void) {
538596
UNHOOK(t16_cbnz_t1_fixaddr);
539597
UNHOOK(t16_it_t1_case1);
540598
UNHOOK(t16_it_t1_case2);
599+
UNHOOK(t16_it_t1_case3);
541600

542601
UNHOOK(t32_b_t3);
543602
UNHOOK(t32_b_t4);
@@ -644,6 +703,7 @@ int unittest_run(bool hookee2_loaded) {
644703
RUN(t16_cbnz_t1_fixaddr);
645704
RUN(t16_it_t1_case1);
646705
RUN(t16_it_t1_case2);
706+
RUN(t16_it_t1_case3);
647707

648708
LOG(DELIMITER, "TEST INST T32");
649709
RUN(t32_b_t3);
@@ -731,6 +791,12 @@ int unittest_run(bool hookee2_loaded) {
731791
RUN_WITH_DLSYM(libhookee2.so, hook_before_dlopen_2);
732792
}
733793

794+
LOG(DELIMITER, "TEST - dlopen");
795+
void *handle = dlopen("libc.so", RTLD_NOW);
796+
dlclose(handle);
797+
handle = dlopen("libshadowhook_nothing.so", RTLD_NOW);
798+
dlclose(handle);
799+
734800
return 0;
735801
}
736802

app/src/main/cpp/unittest/unittest_jni.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
// Created by Kelun Cai (caikelun@bytedance.com) on 2021-04-11.
2323

24+
#include <dlfcn.h>
2425
#include <fcntl.h>
2526
#include <jni.h>
2627
#include <stdarg.h>
@@ -34,6 +35,8 @@
3435
#define HACKER_JNI_VERSION JNI_VERSION_1_6
3536
#define HACKER_JNI_CLASS_NAME "com/bytedance/shadowhook/sample/NativeHandler"
3637

38+
static void *hookee2_handle = NULL;
39+
3740
static int unittest_jni_hook_sym_addr(JNIEnv *env, jobject thiz, jint api_level) {
3841
(void)env;
3942
(void)thiz;
@@ -55,11 +58,28 @@ static int unittest_jni_unhook(JNIEnv *env, jobject thiz) {
5558
return unittest_unhook();
5659
}
5760

58-
static int unittest_jni_run(JNIEnv *env, jobject thiz, jboolean hookee2_loaded) {
61+
static int unittest_jni_run(JNIEnv *env, jobject thiz) {
62+
(void)env;
63+
(void)thiz;
64+
65+
return unittest_run(NULL != hookee2_handle);
66+
}
67+
68+
static void unittest_jni_dlopen(JNIEnv *env, jobject thiz) {
5969
(void)env;
6070
(void)thiz;
6171

62-
return unittest_run(hookee2_loaded);
72+
if (NULL == hookee2_handle) hookee2_handle = dlopen("libhookee2.so", RTLD_NOW);
73+
}
74+
75+
static void unittest_jni_dlclose(JNIEnv *env, jobject thiz) {
76+
(void)env;
77+
(void)thiz;
78+
79+
if (NULL != hookee2_handle) {
80+
dlclose(hookee2_handle);
81+
hookee2_handle = NULL;
82+
}
6383
}
6484

6585
static void unittest_jni_dump_records(JNIEnv *env, jobject thiz, jstring pathname) {
@@ -95,7 +115,9 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
95115
JNINativeMethod m[] = {{"nativeHookSymAddr", "(I)I", (void *)unittest_jni_hook_sym_addr},
96116
{"nativeHookSymName", "(I)I", (void *)unittest_jni_hook_sym_name},
97117
{"nativeUnhook", "()I", (void *)unittest_jni_unhook},
98-
{"nativeRun", "(Z)I", (void *)unittest_jni_run},
118+
{"nativeDlopen", "()V", (void *)unittest_jni_dlopen},
119+
{"nativeDlclose", "()V", (void *)unittest_jni_dlclose},
120+
{"nativeRun", "()I", (void *)unittest_jni_run},
99121
{"nativeDumpRecords", "(Ljava/lang/String;)V", (void *)unittest_jni_dump_records}};
100122
if (0 != (*env)->RegisterNatives(env, cls, m, sizeof(m) / sizeof(m[0]))) return JNI_ERR;
101123

app/src/main/java/com/bytedance/shadowhook/sample/MainActivity.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,19 @@ public void onClick(View v) {
6868

6969
findViewById(R.id.unitTestLoad).setOnClickListener(new View.OnClickListener() {
7070
public void onClick(View v) {
71-
if(!hookee2Loaded) {
72-
hookee2Loaded = true;
73-
System.loadLibrary("hookee2");
74-
}
71+
NativeHandler.nativeDlopen();
72+
}
73+
});
74+
75+
findViewById(R.id.unitTestUnload).setOnClickListener(new View.OnClickListener() {
76+
public void onClick(View v) {
77+
NativeHandler.nativeDlclose();
7578
}
7679
});
7780

7881
findViewById(R.id.unitTestRun).setOnClickListener(new View.OnClickListener() {
7982
public void onClick(View v) {
80-
NativeHandler.nativeRun(hookee2Loaded);
83+
NativeHandler.nativeRun();
8184
}
8285
});
8386

app/src/main/java/com/bytedance/shadowhook/sample/NativeHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public class NativeHandler {
2727
public static native int nativeHookSymAddr(int apiLevel);
2828
public static native int nativeHookSymName(int apiLevel);
2929
public static native int nativeUnhook();
30-
public static native int nativeRun(boolean hookee2Loaded);
30+
public static native void nativeDlopen();
31+
public static native void nativeDlclose();
32+
public static native int nativeRun();
3133
public static native void nativeDumpRecords(String pathname);
3234
}

0 commit comments

Comments
 (0)