Skip to content

Commit

Permalink
feat: major changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Colibrow committed Oct 31, 2024
1 parent 5ccd915 commit 7f3f6ee
Show file tree
Hide file tree
Showing 50 changed files with 1,320 additions and 469 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ShadowHook

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

Expand Down Expand Up @@ -49,7 +49,7 @@ android {
}
dependencies {
implementation 'com.bytedance.android:shadowhook:1.0.10'
implementation 'com.bytedance.android:shadowhook:1.1.1'
}
```

Expand Down Expand Up @@ -102,6 +102,7 @@ If you are using ShadowHook in an SDK project, you may need to avoid packaging l
android {
packagingOptions {
exclude '**/libshadowhook.so'
exclude '**/libshadowhook_nothing.so'
}
}
```
Expand All @@ -112,6 +113,7 @@ On the other hand, if you are using ShadowHook in an APP project, you may need t
android {
packagingOptions {
pickFirst '**/libshadowhook.so'
pickFirst '**/libshadowhook_nothing.so'
}
}
```
Expand Down
6 changes: 4 additions & 2 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ShadowHook

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

Expand Down Expand Up @@ -49,7 +49,7 @@ android {
}
dependencies {
implementation 'com.bytedance.android:shadowhook:1.0.10'
implementation 'com.bytedance.android:shadowhook:1.1.1'
}
```

Expand Down Expand Up @@ -102,6 +102,7 @@ android {
android {
packagingOptions {
exclude '**/libshadowhook.so'
exclude '**/libshadowhook_nothing.so'
}
}
```
Expand All @@ -112,6 +113,7 @@ android {
android {
packagingOptions {
pickFirst '**/libshadowhook.so'
pickFirst '**/libshadowhook_nothing.so'
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ android {
}
packagingOptions {
jniLibs {
pickFirsts += ['**/libshadowhook.so']
pickFirsts += ['**/libshadowhook.so', '**/libshadowhook_nothing.so']
}
if (rootProject.ext.useASAN) {
doNotStrip "**/*.so"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.22.1)
cmake_minimum_required(VERSION 3.30.5)
project(app)
enable_language(ASM)

Expand Down
10 changes: 10 additions & 0 deletions app/src/main/cpp/hookee/arch/arm/t16.S
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,16 @@ ENTRY_GLOBAL_THUMB(test_t16_it_t1_case2)
bx lr
END(test_t16_it_t1_case2)

ENTRY_GLOBAL_THUMB(test_t16_it_t1_case3)
cmp r0, r0 // Compare r0 with 0
itete ne // If-Then-Else-Then-Else block for Not Equal
addne r1, r1, #1 // If r0 != 0, add 1 to r1
addeq r2, r2, #2 // If r0 == 0, add 2 to r2
subne r3, r3, #3 // If r0 != 0, subtract 3 from r3
moveq r4, #4 // If r0 == 0, move 4 to r4
b test_t16_helper_global
END(test_t16_it_t1_case3)


ENTRY_HIDDEN_THUMB(test_t16_helper_hidden_tail)
add r0, r0, r1
Expand Down
1 change: 1 addition & 0 deletions app/src/main/cpp/hookee/hookee.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ int test_t16_cbnz_t1(int a, int b);
int test_t16_cbnz_t1_fixaddr(int a, int b);
int test_t16_it_t1_case1(int a, int b);
int test_t16_it_t1_case2(int a, int b);
int test_t16_it_t1_case3(int a, int b);

int test_t32_helper_global(int a, int b);
int test_t32_b_t3(int a, int b);
Expand Down
66 changes: 66 additions & 0 deletions app/src/main/cpp/unittest/unittest.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,55 @@ static int hook_dlopen(int api_level) {
return result;
}

#define SH_LINKER_SYM_CALL_CONSTRUCTORS_L "__dl__ZN6soinfo16CallConstructorsEv"
#define SH_LINKER_SYM_CALL_DESTRUCTORS_L "__dl__ZN6soinfo15CallDestructorsEv"
#define SH_LINKER_SYM_CALL_CONSTRUCTORS_M "__dl__ZN6soinfo17call_constructorsEv"
#define SH_LINKER_SYM_CALL_DESTRUCTORS_M "__dl__ZN6soinfo16call_destructorsEv"

typedef void (*linker_proxy_soinfo_call_ctors_t)(void *);
static linker_proxy_soinfo_call_ctors_t linker_orig_soinfo_call_ctors;
static void linker_proxy_soinfo_call_ctors(void *soinfo) {
if (SHADOWHOOK_IS_SHARED_MODE)
SHADOWHOOK_CALL_PREV(linker_proxy_soinfo_call_ctors, linker_proxy_soinfo_call_ctors_t, soinfo);
else
linker_orig_soinfo_call_ctors(soinfo);

if (SHADOWHOOK_IS_SHARED_MODE) SHADOWHOOK_POP_STACK();
}

typedef void (*linker_proxy_soinfo_call_dtors_t)(void *);
static linker_proxy_soinfo_call_dtors_t linker_orig_soinfo_call_dtors;
static void linker_proxy_soinfo_call_dtors(void *soinfo) {
if (SHADOWHOOK_IS_SHARED_MODE)
SHADOWHOOK_CALL_PREV(linker_proxy_soinfo_call_dtors, linker_proxy_soinfo_call_dtors_t, soinfo);
else
linker_orig_soinfo_call_dtors(soinfo);

if (SHADOWHOOK_IS_SHARED_MODE) SHADOWHOOK_POP_STACK();
}

static int hook_call_ctors_dtors(int api_level) {
static int result = -1;
static bool hooked = false;

if (hooked) return result;
hooked = true;

void *stub_ctors = shadowhook_hook_sym_name(
LINKER_BASENAME,
api_level >= __ANDROID_API_M__ ? SH_LINKER_SYM_CALL_CONSTRUCTORS_M : SH_LINKER_SYM_CALL_CONSTRUCTORS_L,
(void *)linker_proxy_soinfo_call_ctors, (void **)&linker_orig_soinfo_call_ctors);
int errno_ctors = shadowhook_get_errno();
void *stub_dtors = shadowhook_hook_sym_name(
LINKER_BASENAME,
api_level >= __ANDROID_API_M__ ? SH_LINKER_SYM_CALL_DESTRUCTORS_M : SH_LINKER_SYM_CALL_DESTRUCTORS_L,
(void *)linker_proxy_soinfo_call_dtors, (void **)&linker_orig_soinfo_call_dtors);
int errno_dtors = shadowhook_get_errno();

result = (NULL != stub_ctors && NULL != stub_dtors && 0 == errno_ctors && 0 == errno_dtors) ? 0 : -1;
return result;
}

// end of - hooking dlopen() or do_dlopen()
///////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -270,6 +319,7 @@ PROXY(t16_cbnz_t1)
PROXY(t16_cbnz_t1_fixaddr)
PROXY(t16_it_t1_case1)
PROXY(t16_it_t1_case2)
PROXY(t16_it_t1_case3)

PROXY(t32_b_t3)
PROXY(t32_b_t4)
Expand Down Expand Up @@ -398,6 +448,13 @@ static int unittest_hook(int api_level) {
return -1;
}

if (api_level >= __ANDROID_API_L__) {
if (0 != hook_call_ctors_dtors(api_level)) {
LOG("hook soinfo::call_constructors() and get soinfo::call_destructors() FAILED");
return -1;
}
}

#if defined(__arm__)

HOOK(t16_b_t1);
Expand Down Expand Up @@ -454,6 +511,7 @@ static int unittest_hook(int api_level) {
HOOK(a32_ldr_lit_a1_case2);
HOOK(a32_ldr_reg_a1_case1);
HOOK(a32_ldr_reg_a1_case2);
HOOK(t16_it_t1_case3);

#elif defined(__aarch64__)

Expand Down Expand Up @@ -538,6 +596,7 @@ int unittest_unhook(void) {
UNHOOK(t16_cbnz_t1_fixaddr);
UNHOOK(t16_it_t1_case1);
UNHOOK(t16_it_t1_case2);
UNHOOK(t16_it_t1_case3);

UNHOOK(t32_b_t3);
UNHOOK(t32_b_t4);
Expand Down Expand Up @@ -644,6 +703,7 @@ int unittest_run(bool hookee2_loaded) {
RUN(t16_cbnz_t1_fixaddr);
RUN(t16_it_t1_case1);
RUN(t16_it_t1_case2);
RUN(t16_it_t1_case3);

LOG(DELIMITER, "TEST INST T32");
RUN(t32_b_t3);
Expand Down Expand Up @@ -731,6 +791,12 @@ int unittest_run(bool hookee2_loaded) {
RUN_WITH_DLSYM(libhookee2.so, hook_before_dlopen_2);
}

LOG(DELIMITER, "TEST - dlopen");
void *handle = dlopen("libc.so", RTLD_NOW);
dlclose(handle);
handle = dlopen("libshadowhook_nothing.so", RTLD_NOW);
dlclose(handle);

return 0;
}

Expand Down
28 changes: 25 additions & 3 deletions app/src/main/cpp/unittest/unittest_jni.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

// Created by Kelun Cai ([email protected]) on 2021-04-11.

#include <dlfcn.h>
#include <fcntl.h>
#include <jni.h>
#include <stdarg.h>
Expand All @@ -34,6 +35,8 @@
#define HACKER_JNI_VERSION JNI_VERSION_1_6
#define HACKER_JNI_CLASS_NAME "com/bytedance/shadowhook/sample/NativeHandler"

static void *hookee2_handle = NULL;

static int unittest_jni_hook_sym_addr(JNIEnv *env, jobject thiz, jint api_level) {
(void)env;
(void)thiz;
Expand All @@ -55,11 +58,28 @@ static int unittest_jni_unhook(JNIEnv *env, jobject thiz) {
return unittest_unhook();
}

static int unittest_jni_run(JNIEnv *env, jobject thiz, jboolean hookee2_loaded) {
static int unittest_jni_run(JNIEnv *env, jobject thiz) {
(void)env;
(void)thiz;

return unittest_run(NULL != hookee2_handle);
}

static void unittest_jni_dlopen(JNIEnv *env, jobject thiz) {
(void)env;
(void)thiz;

return unittest_run(hookee2_loaded);
if (NULL == hookee2_handle) hookee2_handle = dlopen("libhookee2.so", RTLD_NOW);
}

static void unittest_jni_dlclose(JNIEnv *env, jobject thiz) {
(void)env;
(void)thiz;

if (NULL != hookee2_handle) {
dlclose(hookee2_handle);
hookee2_handle = NULL;
}
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,19 @@ public void onClick(View v) {

findViewById(R.id.unitTestLoad).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(!hookee2Loaded) {
hookee2Loaded = true;
System.loadLibrary("hookee2");
}
NativeHandler.nativeDlopen();
}
});

findViewById(R.id.unitTestUnload).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
NativeHandler.nativeDlclose();
}
});

findViewById(R.id.unitTestRun).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
NativeHandler.nativeRun(hookee2Loaded);
NativeHandler.nativeRun();
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public class NativeHandler {
public static native int nativeHookSymAddr(int apiLevel);
public static native int nativeHookSymName(int apiLevel);
public static native int nativeUnhook();
public static native int nativeRun(boolean hookee2Loaded);
public static native void nativeDlopen();
public static native void nativeDlclose();
public static native int nativeRun();
public static native void nativeDumpRecords(String pathname);
}
6 changes: 5 additions & 1 deletion app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@

<Button style="@style/Theme.Button.Red"
android:id="@+id/unitTestLoad"
android:text="load libhookee2.so (automatically hook)" />
android:text="dlopen libhookee2.so" />

<Button style="@style/Theme.Button.Red"
android:id="@+id/unitTestUnload"
android:text="dlclose libhookee2.so" />

<Button style="@style/Theme.Button.Red"
android:id="@+id/unitTestRun"
Expand Down
12 changes: 6 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
plugins {
id 'com.android.application' version '8.5.2' apply false
id 'com.android.library' version '8.5.2' apply false
id 'com.android.application' version '8.7.1' apply false
id 'com.android.library' version '8.7.1' apply false
}

tasks.register('clean', Delete) {
delete rootProject.getLayout.getBuildDirectory
delete getBuildDir()
}

ext {
Expand All @@ -14,15 +14,15 @@ ext {
buildToolsVersion = '35.0.0'
javaVersion = JavaVersion.VERSION_1_7
ndkVersion = "23.2.8568313"
cmakeVersion = "3.22.1"
cmakeVersion = "3.30.5"
abiFilters = "armeabi-v7a,arm64-v8a"
useASAN = false
dependencyOnLocalLibrary = true
shadowhookVersion = "1.0.10"
shadowhookVersion = "1.1.1"

POM_GROUP_ID = "com.bytedance.android"
POM_ARTIFACT_ID = "shadowhook"
POM_VERSION_NAME = "1.0.10"
POM_VERSION_NAME = "1.1.1"

POM_NAME = "shadowhook"
POM_DESCRIPTION = "ShadowHook is an Android inline hook library which supports thumb, arm32 and arm64."
Expand Down
Loading

0 comments on commit 7f3f6ee

Please sign in to comment.