├── jni ├── Application.mk ├── .DS_Store ├── libhookzz.a ├── hook.h ├── Android.mk ├── hook.c ├── myHook.c └── hookzz.h └── README.md /jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := armeabi armeabi-v7a 2 | APP_PIE:= true 3 | -------------------------------------------------------------------------------- /jni/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefan00lpf/AndroidHook/HEAD/jni/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AndroidHook 2 | 利用android_inject和hookZz框架写的一个Android zygote注入andorid程序,进行中 3 | -------------------------------------------------------------------------------- /jni/libhookzz.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefan00lpf/AndroidHook/HEAD/jni/libhookzz.a -------------------------------------------------------------------------------- /jni/hook.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | 8 | 9 | #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "kkkHook", __VA_ARGS__)) 10 | #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, "kkkHook", __VA_ARGS__)) 11 | #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "kkkHook", __VA_ARGS__)) 12 | 13 | uint32_t get_module_base(pid_t pid, const char *module_path); -------------------------------------------------------------------------------- /jni/Android.mk: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2009 The Android Open Source Project 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # 16 | # 17 | LOCAL_PATH := $(call my-dir) 18 | 19 | include $(CLEAR_VARS) 20 | LOCAL_MODULE := libhookzz 21 | LOCAL_SRC_FILES := $(LOCAL_PATH)/libhookzz.a 22 | include $(PREBUILT_STATIC_LIBRARY) 23 | 24 | 25 | 26 | 27 | include $(CLEAR_VARS) 28 | LOCAL_MODULE := myhook 29 | LOCAL_LDLIBS := -llog 30 | LOCAL_SRC_FILES := myHook.c hook.c 31 | LOCAL_STATIC_LIBRARIES := libhookzz 32 | LOCAL_CFLAGS = -std=c99 33 | include $(BUILD_SHARED_LIBRARY) -------------------------------------------------------------------------------- /jni/hook.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "hook.h" 12 | 13 | 14 | 15 | uint32_t get_module_base(pid_t pid, const char *module_path) 16 | { 17 | FILE *fp = NULL; 18 | char *pch = NULL; 19 | char filename[32]; 20 | char line[512]; 21 | uint32_t addr = 0; 22 | 23 | if ( pid < 0 ) 24 | snprintf(filename, sizeof(filename), "/proc/self/maps"); 25 | else 26 | snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); 27 | 28 | if ( (fp = fopen(filename, "r")) == NULL ) 29 | { 30 | LOGE("open %s failed!", filename); 31 | return 0; 32 | } 33 | 34 | while ( fgets(line, sizeof(line), fp) ) 35 | { 36 | if ( strstr(line, module_path) ) 37 | { 38 | pch = strtok(line, "-"); 39 | addr = strtoul(pch, NULL, 16); 40 | break; 41 | } 42 | } 43 | 44 | fclose(fp); 45 | 46 | return addr; 47 | } -------------------------------------------------------------------------------- /jni/myHook.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "hook.h" 9 | #include "hookzz.h" 10 | 11 | #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "kkkHook", __VA_ARGS__)) 12 | #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "kkkHook", __VA_ARGS__)) 13 | 14 | #define INVALID_FUNC_ADDR NULL 15 | 16 | void _init(char *args) 17 | { 18 | LOGI("kkk hook is start"); 19 | } 20 | 21 | 22 | uint32_t (*lua_loadx_ori)(void *, void *, void *, const char *, const char *) = NULL; 23 | uint32_t lua_loadx_replace(void *L, void* reader, void *dt, 24 | const char *chunkname, const char *mode) 25 | { 26 | LOGI("%s:%s", __FUNCTION__, chunkname); 27 | 28 | 29 | return lua_loadx_ori(L, reader, dt, chunkname, mode); 30 | } 31 | 32 | uint32_t (*dvmLoadNativeCode_ori)(const char*, uint32_t, uint32_t) = NULL; 33 | uint32_t dvmLoadNativeCode_replace(const char* a1, uint32_t a2, uint32_t a3) 34 | { 35 | // LOGI("%s:%s", __FUNCTION__, a1); 36 | 37 | static int xx_isDone = 1; 38 | //判断是否是该package 39 | char* target_package = "com.bilibili.azurlane"; 40 | if(strstr(a1, target_package) && xx_isDone) 41 | { 42 | LOGI("find the target_package:%s", target_package); 43 | char* libpath = "/data/data/com.bilibili.azurlane/lib/libtolua.so"; 44 | 45 | void *handler = dlopen(libpath, RTLD_NOW); 46 | 47 | char *err = (char *)dlerror(); 48 | if(err != NULL) 49 | LOGI("dlopen error is:%s\n",err); 50 | if(handler) 51 | { 52 | LOGI("hook is start"); 53 | pid_t pid = getpid(); 54 | LOGI("pid is %d", pid); 55 | uint32_t module_base = get_module_base(pid, "/data/app-lib/com.bilibili.azurlane-1/libtolua.so"); 56 | if(module_base) 57 | { 58 | LOGI("module_base:%x", module_base); 59 | uint32_t lua_loadx_target = module_base + 0x3BCB4; 60 | ZzHook((void *)lua_loadx_target, (void *)&lua_loadx_replace, (void **)&lua_loadx_ori, NULL, NULL, false); 61 | } 62 | 63 | xx_isDone = 0; 64 | } 65 | } 66 | 67 | return dvmLoadNativeCode_ori(a1, a2, a3); 68 | } 69 | 70 | 71 | void so_entry(char *p) 72 | { 73 | char *module_path = "/system/lib/libdvm.so"; 74 | 75 | void *handler1 = dlopen("/system/lib/libsubstrate.so", RTLD_NOW); 76 | char *err = (char *)dlerror(); 77 | if(err != NULL) 78 | LOGI("dlopen error is:%s\n",err); 79 | 80 | void (*MSHookFunction)(void *symbol, void *replace, void **result) = INVALID_FUNC_ADDR; 81 | MSHookFunction = dlsym(handler1, "MSHookFunction"); 82 | if(MSHookFunction == INVALID_FUNC_ADDR) { 83 | LOGD("can't find MSHookFunction"); 84 | } 85 | 86 | pid_t pid = getpid(); 87 | LOGI("the target pid is %d", pid); 88 | uint32_t module_base = get_module_base(pid, module_path); 89 | 90 | LOGI("the module_base is %x", module_base); 91 | if(module_base) 92 | { 93 | uint32_t dvmLoadNativeCode_target = module_base + 0x4FE30 + 1;//一定要注意是ARM指令还是Thumb指令 94 | // MSHookFunction((void*)dvmLoadNativeCode_target, (void *)&dvmLoadNativeCode_replace, (void **)&dvmLoadNativeCode_ori); 95 | 96 | 97 | ZzHook((void *)dvmLoadNativeCode_target, (void *)&dvmLoadNativeCode_replace, (void **)&dvmLoadNativeCode_ori, NULL, NULL, false); 98 | LOGI("hook done!"); 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /jni/hookzz.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 jmpews 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef hookzz_h 18 | #define hookzz_h 19 | 20 | // clang-format off 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif //__cplusplus 24 | 25 | #include 26 | #include 27 | 28 | #if defined(__arm64__) || defined(__aarch64__) 29 | typedef union FPReg_ { 30 | __int128_t q; 31 | struct { 32 | double d1; 33 | double d2; 34 | } d; 35 | struct { 36 | float f1; 37 | float f2; 38 | float f3; 39 | float f4; 40 | } f; 41 | } FPReg; 42 | 43 | typedef struct _RegState { 44 | uint64_t sp; 45 | 46 | union { 47 | uint64_t x[29]; 48 | struct { 49 | uint64_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, 50 | x22, x23, x24, x25, x26, x27, x28; 51 | } regs; 52 | } general; 53 | 54 | uint64_t fp; 55 | uint64_t lr; 56 | 57 | union { 58 | FPReg q[8]; 59 | struct { 60 | FPReg q0, q1, q2, q3, q4, q5, q6, q7; 61 | } regs; 62 | } floating; 63 | } RegState; 64 | #elif defined(__arm__) 65 | typedef struct _RegState { 66 | uint32_t sp; 67 | 68 | union { 69 | uint32_t r[13]; 70 | struct { 71 | uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12; 72 | } regs; 73 | } general; 74 | 75 | uint32_t lr; 76 | } RegState; 77 | #elif defined(__i386__) 78 | typedef struct _RegState { 79 | } RegState; 80 | #elif defined(__x86_64__) 81 | typedef struct _RegState { 82 | } RegState; 83 | #endif 84 | 85 | typedef enum _ZZSTATUS { 86 | ZZ_UNKOWN = -1, 87 | ZZ_DONE = 0, 88 | ZZ_SUCCESS, 89 | ZZ_FAILED, 90 | ZZ_DONE_HOOK, 91 | ZZ_DONE_INIT, 92 | ZZ_DONE_ENABLE, 93 | ZZ_ALREADY_HOOK, 94 | ZZ_ALREADY_INIT, 95 | ZZ_ALREADY_ENABLED, 96 | ZZ_NEED_INIT, 97 | ZZ_NO_BUILD_HOOK 98 | } ZZSTATUS; 99 | 100 | typedef enum _ZZHOOKTYPE { 101 | HOOK_TYPE_ONE_INSTRUCTION = 0, 102 | HOOK_TYPE_FUNCTION_via_PRE_POST, 103 | HOOK_TYPE_FUNCTION_via_REPLACE, 104 | HOOK_TYPE_FUNCTION_via_GOT, 105 | HOOK_TYPE_DBI 106 | }ZZHOOKTYPE; 107 | 108 | typedef struct _CallStack { 109 | unsigned long call_id; 110 | struct _ThreadStack *ts; 111 | } CallStack; 112 | 113 | typedef struct _ThreadStack { 114 | unsigned long thread_id; 115 | unsigned long size; 116 | } ThreadStack; 117 | 118 | typedef struct _HookEntryInfo { 119 | unsigned long hook_id; 120 | void *hook_address; 121 | } HookEntryInfo; 122 | 123 | 124 | /* ------- example ------- 125 | void common_pre_call(RegState *rs, ThreadStack *ts, CallStack *cs, const HookEntryInfo *info) 126 | { 127 | puts((char *)rs->general.regs.r0); 128 | STACK_SET(cs, "format", rs->general.regs.r0, char *); 129 | } 130 | 131 | void printf_post_call(RegState *rs, ThreadStack *ts, CallStack *cs, const HookEntryInfo *info) 132 | { 133 | if (STACK_CHECK_KEY(cs, "format")) 134 | { 135 | char *format = STACK_GET(cs, "format", char *); 136 | puts(format); 137 | } 138 | } 139 | ------- example end ------- */ 140 | 141 | typedef void (*PRECALL)(RegState *rs, ThreadStack *ts, CallStack *cs, const HookEntryInfo *info); 142 | typedef void (*POSTCALL)(RegState *rs, ThreadStack *ts, CallStack *cs, const HookEntryInfo *info); 143 | 144 | typedef void (*STUBCALL)(RegState *rs, const HookEntryInfo *info); 145 | 146 | // ------- export API ------- 147 | 148 | #define STACK_CHECK_KEY(cs, key) (bool)ZzGetCallStackData(cs, key) 149 | #define STACK_GET(cs, key, type) *(type *)ZzGetCallStackData(cs, key) 150 | #define STACK_SET(cs, key, value, type) ZzSetCallStackData(cs, key, &(value), sizeof(type)) 151 | 152 | /* ------- example ------- 153 | void common_pre_call(RegState *rs, ThreadStack *ts, CallStack *cs, const HookEntryInfo *info) 154 | { 155 | puts((char *)rs->general.regs.r0); 156 | STACK_SET(cs, "format", rs->general.regs.r0, char *); 157 | } 158 | 159 | void printf_post_call(RegState *rs, ThreadStack *ts, CallStack *cs, const HookEntryInfo *info) 160 | { 161 | if (STACK_CHECK_KEY(cs, "format")) 162 | { 163 | char *format = STACK_GET(cs, "format", char *); 164 | puts(format); 165 | } 166 | } 167 | ------- example end ------- */ 168 | 169 | void *ZzGetCallStackData(CallStack *callstack_ptr, char *key_str); 170 | bool ZzSetCallStackData(CallStack *callstack_ptr, char *key_str, void *value_ptr, unsigned long value_size); 171 | 172 | ZZSTATUS ZzBuildHook(void *target_ptr, void *replace_call_ptr, void **origin_ptr, PRECALL pre_call_ptr, POSTCALL post_call_ptr, bool try_near_jump, ZZHOOKTYPE hook_type); 173 | ZZSTATUS ZzEnableHook(void *target_ptr); 174 | 175 | ZZSTATUS ZzHook(void *target_ptr, void *replace_ptr, void **origin_ptr, PRECALL pre_call_ptr, POSTCALL post_call_ptr, bool try_near_jump); 176 | ZZSTATUS ZzHookPrePost(void *target_ptr, PRECALL pre_call_ptr, POSTCALL post_call_ptr); 177 | ZZSTATUS ZzHookReplace(void *target_ptr, void *replace_ptr, void **origin_ptr); 178 | 179 | // hook only one instruciton with instruction address 180 | ZZSTATUS ZzHookOneInstruction(void *insn_address, PRECALL pre_call_ptr, POSTCALL post_call_ptr, bool try_near_jump); 181 | 182 | // got hook (only support macho) 183 | ZZSTATUS ZzHookGOT(const char *name, void *replace_ptr, void **origin_ptr, PRECALL pre_call_ptr, POSTCALL post_call_ptr); 184 | 185 | // runtime code patch 186 | ZZSTATUS ZzRuntimeCodePatch(void *address, void *code_data, unsigned long code_length); 187 | 188 | ZZSTATUS ZzDynamicBinaryInstrumentation(void *address, STUBCALL stub_call_ptr); 189 | 190 | // enable debug info 191 | void HookZzDebugInfoEnable(void); 192 | 193 | // disable hook 194 | ZZSTATUS ZzDisableHook(void *target_ptr); 195 | 196 | // ------- export API end ------- 197 | 198 | #if defined(__arm64__) || defined(__aarch64__) 199 | #if defined(__APPLE__) && defined(__MACH__) 200 | #include 201 | #if TARGET_OS_IPHONE 202 | #define TARGET_IS_IOS 1 203 | #endif 204 | #endif 205 | #endif 206 | #ifdef TARGET_IS_IOS 207 | ZZSTATUS StaticBinaryInstrumentation(void *target_fileoff, void *replace_call_ptr, void **origin_ptr, PRECALL pre_call_ptr, 208 | POSTCALL post_call_ptr); 209 | #endif 210 | 211 | #ifdef __cplusplus 212 | } 213 | #endif //__cplusplus 214 | #endif 215 | --------------------------------------------------------------------------------