├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── dictionaries │ └── zhangzhongping.xml ├── encodings.xml ├── gradle.xml ├── kotlinc.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── dexposedart │ │ └── newhook │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── dexposedart │ │ │ └── newhook │ │ │ ├── App.java │ │ │ ├── CrashHandler.java │ │ │ ├── MainActivity.java │ │ │ └── TestHook │ │ │ ├── TestHookMeanager.java │ │ │ ├── TestProxy1.java │ │ │ ├── TestProxy2.java │ │ │ ├── TestProxy3.java │ │ │ ├── TestProxy4.java │ │ │ └── TestProxy41.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── dexposedart │ └── newhook │ └── ExampleUnitTest.java ├── build.gradle ├── dexposed ├── .idea │ ├── compiler.xml │ ├── copyright │ │ └── profiles_settings.xml │ ├── gradle.xml │ ├── misc.xml │ └── workspace.xml ├── NOTICE ├── build.gradle ├── build │ ├── generated │ │ └── source │ │ │ ├── buildConfig │ │ │ ├── androidTest │ │ │ │ └── debug │ │ │ │ │ └── com │ │ │ │ │ └── taobao │ │ │ │ │ └── android │ │ │ │ │ └── dexposed │ │ │ │ │ └── test │ │ │ │ │ └── BuildConfig.java │ │ │ ├── debug │ │ │ │ └── com │ │ │ │ │ └── taobao │ │ │ │ │ └── android │ │ │ │ │ └── dexposed │ │ │ │ │ └── BuildConfig.java │ │ │ └── release │ │ │ │ └── com │ │ │ │ └── taobao │ │ │ │ └── android │ │ │ │ └── dexposed │ │ │ │ └── BuildConfig.java │ │ │ └── r │ │ │ └── androidTest │ │ │ └── debug │ │ │ └── com │ │ │ └── taobao │ │ │ └── android │ │ │ └── dexposed │ │ │ └── R.java │ ├── intermediates │ │ ├── bundles │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── default │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── classes.jar │ │ │ │ └── jni │ │ │ │ ├── armeabi-v7a │ │ │ │ ├── libdexposed.so │ │ │ │ └── libdexposed_l.so │ │ │ │ └── armeabi │ │ │ │ ├── libdexposed.so │ │ │ │ └── libdexposed_l.so │ │ ├── classes │ │ │ └── release │ │ │ │ └── com │ │ │ │ └── taobao │ │ │ │ └── android │ │ │ │ └── dexposed │ │ │ │ ├── BuildConfig.class │ │ │ │ ├── ClassUtils.class │ │ │ │ ├── DalvikArt.class │ │ │ │ ├── DeviceCheck.class │ │ │ │ ├── DexposedBridge$1.class │ │ │ │ ├── DexposedBridge$AdditionalHookInfo.class │ │ │ │ ├── DexposedBridge$CopyOnWriteSortedSet.class │ │ │ │ ├── DexposedBridge.class │ │ │ │ ├── XC_MethodHook$MethodHookParam.class │ │ │ │ ├── XC_MethodHook$Unhook.class │ │ │ │ ├── XC_MethodHook$XC_MethodKeepHook.class │ │ │ │ ├── XC_MethodHook.class │ │ │ │ ├── XC_MethodReplacement$1.class │ │ │ │ ├── XC_MethodReplacement$2.class │ │ │ │ ├── XC_MethodReplacement$XC_MethodKeepReplacement.class │ │ │ │ ├── XC_MethodReplacement.class │ │ │ │ ├── XposedHelpers$ClassNotFoundError.class │ │ │ │ ├── XposedHelpers$InvocationTargetError.class │ │ │ │ ├── XposedHelpers.class │ │ │ │ └── callbacks │ │ │ │ ├── IXUnhook.class │ │ │ │ ├── XCallback$Param$SerializeWrapper.class │ │ │ │ ├── XCallback$Param.class │ │ │ │ └── XCallback.class │ │ ├── incremental-safeguard │ │ │ └── release │ │ │ │ └── tag.txt │ │ ├── incremental │ │ │ ├── compileDebugAidl │ │ │ │ └── dependency.store │ │ │ ├── compileDebugAndroidTestAidl │ │ │ │ └── dependency.store │ │ │ ├── compileReleaseAidl │ │ │ │ └── dependency.store │ │ │ ├── mergeDebugAndroidTestResources │ │ │ │ ├── compile-file-map.properties │ │ │ │ └── merger.xml │ │ │ ├── mergeDebugAssets │ │ │ │ └── merger.xml │ │ │ ├── mergeDebugShaders │ │ │ │ └── merger.xml │ │ │ ├── mergeReleaseAssets │ │ │ │ └── merger.xml │ │ │ ├── mergeReleaseJniLibFolders │ │ │ │ └── merger.xml │ │ │ ├── mergeReleaseShaders │ │ │ │ └── merger.xml │ │ │ ├── packageDebugResources │ │ │ │ ├── compile-file-map.properties │ │ │ │ └── merger.xml │ │ │ └── packageReleaseResources │ │ │ │ ├── compile-file-map.properties │ │ │ │ └── merger.xml │ │ ├── jniLibs │ │ │ └── release │ │ │ │ ├── armeabi-v7a │ │ │ │ ├── libdexposed.so │ │ │ │ └── libdexposed_l.so │ │ │ │ └── armeabi │ │ │ │ ├── libdexposed.so │ │ │ │ └── libdexposed_l.so │ │ ├── manifest │ │ │ └── androidTest │ │ │ │ └── debug │ │ │ │ └── AndroidManifest.xml │ │ ├── manifests │ │ │ └── aapt │ │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ │ └── release │ │ │ │ └── AndroidManifest.xml │ │ ├── res │ │ │ └── resources-debug-androidTest.ap_ │ │ └── transforms │ │ │ ├── mergeJniLibs │ │ │ └── release │ │ │ │ └── folders │ │ │ │ └── 2000 │ │ │ │ └── 3 │ │ │ │ └── main │ │ │ │ └── lib │ │ │ │ ├── armeabi-v7a │ │ │ │ ├── libdexposed.so │ │ │ │ └── libdexposed_l.so │ │ │ │ └── armeabi │ │ │ │ ├── libdexposed.so │ │ │ │ └── libdexposed_l.so │ │ │ └── stripDebugSymbol │ │ │ └── release │ │ │ └── folders │ │ │ └── 2000 │ │ │ └── 3 │ │ │ └── main │ │ │ └── lib │ │ │ ├── armeabi-v7a │ │ │ ├── libdexposed.so │ │ │ └── libdexposed_l.so │ │ │ └── armeabi │ │ │ ├── libdexposed.so │ │ │ └── libdexposed_l.so │ └── outputs │ │ └── aar │ │ ├── dexposed-debug.aar │ │ └── dexposed-release.aar ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── local.properties └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── taobao │ │ └── android │ │ └── dexposed │ │ ├── ClassUtils.java │ │ ├── DalvikArt.java │ │ ├── DeviceCheck.java │ │ ├── DexUtils │ │ ├── DexLoaderReplace.java │ │ └── ReplaceResult.java │ │ ├── DexposedBridge.java │ │ ├── HookArt │ │ ├── Dexposed_Art.java │ │ └── utils │ │ │ ├── ArtUnhook.java │ │ │ ├── HookInfo.java │ │ │ ├── HookLog.java │ │ │ ├── HookResult.java │ │ │ └── HookUtils.java │ │ ├── XC_MethodHook.java │ │ ├── XC_MethodReplacement.java │ │ ├── XposedHelpers.java │ │ ├── annotations │ │ ├── Hook.java │ │ ├── HookMethod.java │ │ ├── Hooks.java │ │ └── OriginalHookMethod.java │ │ └── callbacks │ │ ├── DexLoaderCallBack.java │ │ ├── IXUnhook.java │ │ └── XCallback.java │ ├── jni │ ├── Android.mk │ ├── Application.mk │ └── HookMain.c │ └── jniLibs │ ├── armeabi-v7a │ ├── libdexposed.so │ └── libdexposed_l.so │ └── armeabi │ ├── libdexposed.so │ └── libdexposed_l.so ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── hookinject ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── taobao │ └── android │ └── dexposed │ └── annotations │ ├── Hook.java │ ├── Hooks.java │ ├── NewHookProcessor.java │ ├── Utils.java │ ├── getHook.java │ └── getHooks.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/dictionaries/zhangzhongping.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Abstraction issuesJava 39 | 40 | 41 | Android 42 | 43 | 44 | Android > Lint > Accessibility 45 | 46 | 47 | Android > Lint > Correctness 48 | 49 | 50 | Android > Lint > Correctness > Messages 51 | 52 | 53 | Android > Lint > Internationalization 54 | 55 | 56 | Android > Lint > Internationalization > Bidirectional Text 57 | 58 | 59 | Android > Lint > Performance 60 | 61 | 62 | Android > Lint > Security 63 | 64 | 65 | Android > Lint > Usability 66 | 67 | 68 | Android > Lint > Usability > Icons 69 | 70 | 71 | Android > Lint > Usability > Typography 72 | 73 | 74 | Assignment issuesGroovy 75 | 76 | 77 | Assignment issuesJava 78 | 79 | 80 | C/C++ 81 | 82 | 83 | Class metricsJava 84 | 85 | 86 | Class structureJava 87 | 88 | 89 | Cloning issuesJava 90 | 91 | 92 | Code maturity issuesJava 93 | 94 | 95 | Code style issuesJava 96 | 97 | 98 | Concurrency annotation issuesJava 99 | 100 | 101 | Control FlowGroovy 102 | 103 | 104 | Control flow issuesJava 105 | 106 | 107 | CorrectnessLintAndroid 108 | 109 | 110 | Data flow analysisC/C++ 111 | 112 | 113 | Data flow issuesJava 114 | 115 | 116 | Declaration redundancyJava 117 | 118 | 119 | DeclarationGroovy 120 | 121 | 122 | Dependency issuesJava 123 | 124 | 125 | Encapsulation issuesJava 126 | 127 | 128 | Error handlingGroovy 129 | 130 | 131 | Error handlingJava 132 | 133 | 134 | FunctionsC/C++ 135 | 136 | 137 | GPath inspectionsGroovy 138 | 139 | 140 | General 141 | 142 | 143 | GeneralC/C++ 144 | 145 | 146 | GeneralJava 147 | 148 | 149 | Google Cloud Endpoints 150 | 151 | 152 | Groovy 153 | 154 | 155 | Inheritance issuesJava 156 | 157 | 158 | Initialization issuesJava 159 | 160 | 161 | Internationalization issuesJava 162 | 163 | 164 | J2ME issuesJava 165 | 166 | 167 | JSON 168 | 169 | 170 | JUnit issuesJava 171 | 172 | 173 | Java 174 | 175 | 176 | Java language level issuesJava 177 | 178 | 179 | Java language level migration aidsJava 180 | 181 | 182 | JavaBeans issuesJava 183 | 184 | 185 | Javadoc issuesJava 186 | 187 | 188 | LintAndroid 189 | 190 | 191 | Logging issuesJava 192 | 193 | 194 | Memory issuesJava 195 | 196 | 197 | Method MetricsGroovy 198 | 199 | 200 | Method metricsJava 201 | 202 | 203 | Modularization issuesJava 204 | 205 | 206 | Naming ConventionsGroovy 207 | 208 | 209 | Naming conventionsJava 210 | 211 | 212 | Numeric issuesJava 213 | 214 | 215 | OtherGroovy 216 | 217 | 218 | Packaging issuesJava 219 | 220 | 221 | Pattern Validation 222 | 223 | 224 | Performance issuesJava 225 | 226 | 227 | Portability issuesJava 228 | 229 | 230 | Potentially confusing code constructsGroovy 231 | 232 | 233 | Probable bugsGroovy 234 | 235 | 236 | Probable bugsJava 237 | 238 | 239 | Resource management issuesJava 240 | 241 | 242 | Security issuesJava 243 | 244 | 245 | Serialization issuesJava 246 | 247 | 248 | TestNGJava 249 | 250 | 251 | Threading issuesGroovy 252 | 253 | 254 | Threading issuesJava 255 | 256 | 257 | Visibility issuesJava 258 | 259 | 260 | XML 261 | 262 | 263 | toString() issuesJava 264 | 265 | 266 | 267 | 268 | Android 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 296 | 297 | 298 | 299 | 300 | 301 | 306 | 307 | 308 | 309 | 310 | 311 | 1.8 312 | 313 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 329 | 330 | 331 | 332 | 333 | 334 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NewHooks 2 | 基于YAHFA和dexposed 结合的hook框架 支持安卓4.0-7.0 3 | 4 | 注:(app目录是demo,hookinject是apt代码,dexposed是框架) 5 | 6 | 2017-7-01 10:35   1:新增非静态方法hook回调MethodHookParam.thisOnject参数为当前hook类的实例对象,静态方法hook次参数将为NULL 7 | 8 | 2017-6-30 19:34 1.对编译检查和垃圾回收做了对应的处理 9 | 10 | 2017-5-16 18:26   1.修复5.0以上 art模式某些手机hook后无法调用原方法bug 11 | 12 | 2017-5-5  18:17    1.优化安卓5.0hook 13 | 14 | 2017-4-28 00:20    1.优化art模式hook 15 | 16 | 2017-4-27 16:23    1.优化卸载hook的api: 2.新增getAllHookName; 17 | 18 | 2017-4-27 15:38    1.新增卸载指定hook的方法(Unhook); 2.新增卸载全部hook的方法(UnhookAll) 19 | 20 | 2017-4-21 23:28    1.修复hookinject代码在生成 hook非静态并且无参数方法 回调代码时的错误; 21 | 22 | 2017-4-21 00:17   1.更改注解参数名称 Type修改为Parameter 使其更加贴; 23 | 24 | 2017-4-21 00:07    1.修复art模式hook非静态方法参数错乱问题; 2.新增注解参数 isStatic 用于辅助hookinject实现生成代码(isStatic用来表示需要hook的方法是不是静态方法 是=true 不是=false); 25 | 26 | 2017-4-19 16:20    1.优化内部返回值转换逻辑;  2.优化hookinject匹配hook无返回值处理逻辑; 27 | 28 | 2017-4-18 16:35    1.优化内部hook参数处理逻辑,修复参数错乱hook失败问题;  2.新增DexLoaderReplace方法用于替换内存中的dex(实验); 3.修复细节 29 | 30 | 31 | 2017-4-17 02:48    1.优化hookinject自动匹配参数类型防止内存错乱;  2.纠正hook回调机制; 3.修复小细节 32 | 33 | 2017-4-16 16:22    1.优化hookinject,修复某些hook方法(返回值为8种基本类型的方法)无法修改返回值问题; 2.优化注解配合apt生成代码 新增returnVal参数需要手动设置需要hook方法的返回值 34 | 35 | 36 | 2017-4-15 16:21    1.优化YAHFA部分hook回调基于apt(结合dexposed回调共用一套): 2.去除HookMethod|OriginalHookMethod 注解: 3.删除原有非注解hook方式 37 | 38 | 39 | 2017-4-14 14:23   1.优化HookMethod和OriginalHookMethod注解,去除参数由框架自动获取;   2.新增多hook方法(传入多个绑定Hook或者Hooks注解的类.class即可,返回List) 40 | 41 | 42 | 2017-4-14 13:31:  1.新增支持安卓5.0Hook:  2.纠正5.0Hook判断逻辑 43 | 44 | 2017-4-14 01:09:  1.新增支持安卓7.0Hook(实验); 2.完善小细节; 45 | 46 | 2017-4-13 22:03: 1.修复某些类获取Name为null的问题; 2.完善hook返回信息; 47 | 48 | 2017-4-13 01:06: 1.纠正5.1art模式判断逻辑; 49 | 50 | 2017-4-12 23:56: 1.新增注解Hooks; 2.过时非注解hook方式; 3.优化Hook|Hooks注解type参数去除返回值参数,由框架自动获取; 51 | 52 | 2017-4-12 19:20: 1.新增注解方式Hook; 2.完善hook返回信息; 3.纠正hook过程判断逻辑; 53 | 54 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'android-apt' 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.dexposedart.newhook" 8 | minSdkVersion 15 9 | targetSdkVersion 22 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | ndk { 14 | abiFilters "armeabi", "armeabi-v7a","x86" 15 | } 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | compile fileTree(dir: 'libs', include: ['*.jar']) 27 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 28 | exclude group: 'com.android.support', module: 'support-annotations' 29 | }) 30 | compile 'com.android.support:appcompat-v7:24.2.1' 31 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 32 | testCompile 'junit:junit:4.12' 33 | compile project(path: ':dexposed') 34 | apt project(':hookinject') 35 | } 36 | 37 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/zhangzhongping/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/dexposedart/newhook/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.dexposedart.newhook; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.dexposedart.newhook", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/dexposedart/newhook/App.java: -------------------------------------------------------------------------------- 1 | package com.dexposedart.newhook; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.util.Log; 6 | 7 | import com.dexposedart.newhook.TestHook.TestHookMeanager; 8 | import com.taobao.android.dexposed.DalvikArt; 9 | import com.taobao.android.dexposed.DexUtils.ReplaceResult; 10 | import com.taobao.android.dexposed.callbacks.DexLoaderCallBack; 11 | 12 | /** 13 | * 作者:zhangzhongping on 17/4/11 01:19 14 | * 邮箱:android_dy@163.com 15 | */ 16 | public class App extends Application { 17 | 18 | private static Context context; 19 | 20 | @Override 21 | public void onCreate() { 22 | super.onCreate(); 23 | context = getApplicationContext(); 24 | CrashHandler.getInstance().init(context); 25 | Log.e("123", TestHookMeanager.getTestHookMeanager().StartFrameHook(this) + ""); 26 | boolean[] booleen = TestHookMeanager.getTestHookMeanager().StartFrameHook1(this); 27 | Log.e("123", booleen[0] + "--" + booleen[1]); 28 | Log.e("123", TestHookMeanager.getTestHookMeanager().StartFrameHook4(this) + ""); 29 | Log.e("123", TestHookMeanager.getTestHookMeanager().StartFrameHook41(this) + ""); 30 | } 31 | 32 | public static Context getContext() { 33 | return context; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/dexposedart/newhook/CrashHandler.java: -------------------------------------------------------------------------------- 1 | package com.dexposedart.newhook; 2 | 3 | import android.content.Context; 4 | import android.content.pm.PackageManager; 5 | import android.os.Environment; 6 | import android.os.Looper; 7 | import android.util.Log; 8 | import android.widget.Toast; 9 | 10 | import java.io.BufferedWriter; 11 | import java.io.File; 12 | import java.io.FileWriter; 13 | import java.io.IOException; 14 | import java.io.PrintWriter; 15 | import java.io.StringWriter; 16 | import java.io.Writer; 17 | 18 | /** 19 | * Created by zhangzhongping on 16/12/19. 20 | */ 21 | 22 | public class CrashHandler implements Thread.UncaughtExceptionHandler { 23 | private static final String TAG = "CrashHandler"; 24 | private static final boolean DEBUG = true; 25 | 26 | private static final String PATH = Environment.getExternalStorageDirectory().getAbsolutePath(); 27 | private static final String FILE_NAME = "crash"; 28 | 29 | //log文件的后缀名 30 | private static final String FILE_NAME_SUFFIX = ".crash"; 31 | 32 | private static CrashHandler sInstance = null; 33 | 34 | //系统默认的异常处理(默认情况下,系统会终止当前的异常程序) 35 | private Thread.UncaughtExceptionHandler mDefaultCrashHandler; 36 | 37 | private Context mContext; 38 | 39 | 40 | //构造方法私有,防止外部构造多个实例,即采用单例模式 41 | private CrashHandler() { 42 | } 43 | 44 | public static CrashHandler getInstance() { 45 | if (sInstance == null) { 46 | sInstance = new CrashHandler(); 47 | } 48 | return sInstance; 49 | } 50 | 51 | //这里主要完成初始化工作 52 | public void init(Context context) { 53 | //获取系统默认的异常处理器 54 | mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler(); 55 | //将当前实例设为系统默认的异常处理器 56 | Thread.setDefaultUncaughtExceptionHandler(this); 57 | //获取Context,方便内部使用 58 | mContext = context.getApplicationContext(); 59 | } 60 | 61 | 62 | /** 63 | * 这个是最关键的函数,当程序中有未被捕获的异常,系统将会自动调用#uncaughtException方法 64 | * thread为出现未捕获异常的线程,ex为未捕获的异常,有了这个ex,我们就可以得到异常信息。 65 | */ 66 | @Override 67 | public void uncaughtException(Thread thread, Throwable ex) { 68 | try { 69 | ex.printStackTrace(); 70 | //导出异常信息到SD卡中 71 | dumpExceptionToSDCard(ex); 72 | //这里可以通过网络上传异常信息到服务器,便于开发人员分析日志从而解决bug 73 | uploadExceptionToServer(ex); 74 | } catch (IOException e) { 75 | e.printStackTrace(); 76 | } 77 | new Thread(new Runnable() { 78 | @Override 79 | public void run() { 80 | Looper.prepare(); 81 | Toast.makeText(mContext, "哎呀,程序发生异常啦...", 0).show(); 82 | Looper.loop(); 83 | } 84 | }).start(); 85 | try { 86 | Thread.sleep(3000); 87 | } catch (InterruptedException e) { 88 | } 89 | mDefaultCrashHandler.uncaughtException(thread, ex); 90 | } 91 | 92 | public void dumpExceptionToSDCard(Throwable ex) throws IOException { 93 | File dir = new File(PATH); 94 | if (!dir.exists()) { 95 | dir.mkdirs(); 96 | } 97 | PrintWriter pw = null; 98 | try { 99 | File file = new File(PATH + FILE_NAME + System.nanoTime() + FILE_NAME_SUFFIX); 100 | if (!file.exists()) { 101 | file.createNewFile(); 102 | } 103 | pw = new PrintWriter(new BufferedWriter(new FileWriter(file))); 104 | pw.println(InitCrach(ex, false)); 105 | pw.println(); 106 | } catch (Exception e) { 107 | e.printStackTrace(); 108 | Log.e(TAG, "dump crash info failed"); 109 | } finally { 110 | if (pw != null) { 111 | pw.flush(); 112 | pw.close(); 113 | } 114 | } 115 | } 116 | 117 | private Object InitCrach(Throwable ex, boolean str) throws PackageManager.NameNotFoundException { 118 | 119 | Writer writer = new StringWriter(); 120 | PrintWriter printWriter = new PrintWriter(writer); 121 | ex.printStackTrace(printWriter); 122 | Throwable cause = ex.getCause(); 123 | while (cause != null) { 124 | cause.printStackTrace(printWriter); 125 | cause = cause.getCause(); 126 | } 127 | printWriter.flush(); 128 | printWriter.close(); 129 | String result = writer.toString(); 130 | Log.e("123",result); 131 | return result; 132 | } 133 | 134 | 135 | private void uploadExceptionToServer(Throwable ex) { 136 | 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /app/src/main/java/com/dexposedart/newhook/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.dexposedart.newhook; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.util.Base64; 6 | import android.util.Log; 7 | import android.view.View; 8 | import android.widget.Button; 9 | import android.widget.EditText; 10 | import android.widget.Toast; 11 | 12 | import com.dexposedart.newhook.TestHook.TestHookMeanager; 13 | import com.taobao.android.dexposed.DalvikArt; 14 | import com.taobao.android.dexposed.DeviceCheck; 15 | import com.taobao.android.dexposed.HookArt.utils.HookLog; 16 | 17 | 18 | public class MainActivity extends AppCompatActivity { 19 | EditText edit_query; 20 | 21 | @Override 22 | protected void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(R.layout.activity_main); 25 | edit_query = (EditText) findViewById(R.id.edit_query); 26 | } 27 | 28 | public void button(View view) { 29 | Log.e("123", Toasts(new Boolean[]{true}, edit_query.getText().toString(), new View[]{view})); 30 | } 31 | 32 | 33 | public void button1(View view) { 34 | test1((Button) view); 35 | } 36 | 37 | public void button2(View view) { 38 | Log.e("1234444",nimabi(new boolean[1])+""); 39 | if(nimabi(new boolean[1])){ 40 | edit_query.setText("测试3"); 41 | }else{ 42 | edit_query.setText("测试3hook"); 43 | } 44 | } 45 | 46 | public static String Toasts(Boolean[] booleen, String msg, View[] view) { 47 | Toast.makeText(App.getContext(), msg, 0).show(); 48 | HookLog.e(msg); 49 | return msg; 50 | } 51 | 52 | public void MainAct(String msg){ 53 | Toast.makeText(App.getContext(),msg, 0).show(); 54 | } 55 | 56 | public boolean nimabi(boolean[] booleen){ 57 | Log.e("123","nimabo"); 58 | return true; 59 | } 60 | 61 | 62 | public static int test1(Button button){ 63 | Toast.makeText(App.getContext(), button.getText(), 0).show(); 64 | return -1; 65 | } 66 | 67 | 68 | public void button4(View view){ 69 | Log.e("123",test4((Button) view,"测试4")+""); 70 | edit_query.setText(edit_query.getText().toString()+test4((Button) view,"测试4")); 71 | } 72 | 73 | 74 | 75 | 76 | public static int test4(Button button,String msg){ 77 | Toast.makeText(App.getContext(), button.getText()+msg, 0).show(); 78 | Log.e("123","sd1f21sdf1s61f6s5df4s65f4----"); 79 | test41(); 80 | return -1; 81 | } 82 | public static void test41(){ 83 | Toast.makeText(App.getContext(), "1123", 0).show(); 84 | } 85 | 86 | public void jiechubutton(View view){ 87 | TestHookMeanager.getTestHookMeanager().jiechuhook(); 88 | } 89 | 90 | public void jiechubuttonAll(View view){ 91 | TestHookMeanager.getTestHookMeanager().jiechuhookAll(); 92 | } 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /app/src/main/java/com/dexposedart/newhook/TestHook/TestHookMeanager.java: -------------------------------------------------------------------------------- 1 | package com.dexposedart.newhook.TestHook; 2 | 3 | import android.app.Application; 4 | 5 | import com.taobao.android.dexposed.DalvikArt; 6 | import com.taobao.android.dexposed.HookArt.utils.HookLog; 7 | import com.taobao.android.dexposed.HookArt.utils.HookResult; 8 | 9 | import java.util.List; 10 | 11 | 12 | /** 13 | * 作者:zhangzhongping on 17/4/7 13:31 14 | * 邮箱:android_dy@163.com 15 | */ 16 | public class TestHookMeanager { 17 | 18 | public static TestHookMeanager testHookMeanager; 19 | HookResult andHookMethods; 20 | 21 | public static TestHookMeanager getTestHookMeanager() { 22 | if (testHookMeanager == null) { 23 | testHookMeanager = new TestHookMeanager(); 24 | } 25 | return testHookMeanager; 26 | } 27 | 28 | public boolean StartFrameHook(Application application) { 29 | andHookMethods = DalvikArt.findAndHookMethod(application, TestProxy1.class); 30 | HookLog.e(andHookMethods.getErrormsg()); 31 | return andHookMethods.isHookSuccess(); 32 | } 33 | 34 | public void jiechuhook() { 35 | DalvikArt.Unhook(TestProxy1.class); 36 | } 37 | 38 | public void jiechuhookAll() { 39 | DalvikArt.UnhookAll(); 40 | } 41 | 42 | public boolean[] StartFrameHook1(Application application) { 43 | List andHookMethods = DalvikArt.findAndHookMethod(application, TestProxy2.class, TestProxy3.class); 44 | HookLog.e(andHookMethods.get(0).getErrormsg() + "---" + andHookMethods.get(1).getErrormsg()); 45 | return new boolean[]{andHookMethods.get(0).isHookSuccess(), andHookMethods.get(1).isHookSuccess()}; 46 | } 47 | 48 | public boolean StartFrameHook4(Application application) { 49 | HookResult andHookMethods = DalvikArt.findAndHookMethod(application, TestProxy4.class); 50 | HookLog.e(andHookMethods.getErrormsg()); 51 | return andHookMethods.isHookSuccess(); 52 | } 53 | 54 | public boolean StartFrameHook41(Application application) { 55 | HookResult andHookMethods = DalvikArt.findAndHookMethod(application, TestProxy41.class); 56 | HookLog.e(andHookMethods.getErrormsg()); 57 | return andHookMethods.isHookSuccess(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/dexposedart/newhook/TestHook/TestProxy1.java: -------------------------------------------------------------------------------- 1 | package com.dexposedart.newhook.TestHook; 2 | 3 | import android.view.View; 4 | 5 | import com.taobao.android.dexposed.HookArt.utils.HookLog; 6 | import com.taobao.android.dexposed.XC_MethodHook; 7 | import com.taobao.android.dexposed.annotations.Hook; 8 | 9 | 10 | /** 11 | * 作者:zhangzhongping on 17/4/3 23:29 12 | * 邮箱:android_dy@163.com 13 | * extends XC_MethodReplacement 是用来兼容dalvik虚拟机hook 实现方法是直接替换原方法的 14 | * extends XC_MethodHook 也是用来兼容dalvik虚拟机hook 两个实现方法是 一个是被hook方法执行前执行 一个是被hook方法执行后执行 15 | */ 16 | @Hook(Class = "com.dexposedart.newhook.MainActivity", Name = "Toasts", 17 | Parameter = {Boolean[].class, String.class, View[].class}, returnVal = String.class ,isStatic = true) 18 | public class TestProxy1 extends XC_MethodHook { 19 | @Override 20 | public MethodHookParam beforeHookedMethod(MethodHookParam param) throws Throwable { 21 | 22 | HookLog.e("beforeHookedMethod"); 23 | param.args[1] = param.args[1] + "hook---"; 24 | return param; 25 | } 26 | 27 | @Override 28 | public MethodHookParam afterHookedMethod(MethodHookParam param) throws Throwable { 29 | param.setResult(param.getResult() + "hook"); 30 | HookLog.e(param.getResult() + ""); 31 | return param; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/dexposedart/newhook/TestHook/TestProxy2.java: -------------------------------------------------------------------------------- 1 | package com.dexposedart.newhook.TestHook; 2 | 3 | import android.widget.Button; 4 | import android.widget.Toast; 5 | 6 | import com.dexposedart.newhook.App; 7 | import com.taobao.android.dexposed.XC_MethodHook; 8 | import com.taobao.android.dexposed.XC_MethodReplacement; 9 | import com.taobao.android.dexposed.annotations.Hook; 10 | import com.taobao.android.dexposed.annotations.HookMethod; 11 | import com.taobao.android.dexposed.annotations.OriginalHookMethod; 12 | 13 | 14 | /** 15 | * 作者:zhangzhongping on 17/4/3 23:29 16 | * 邮箱:android_dy@163.com 17 | * extends XC_MethodReplacement 是用来兼容dalvik虚拟机hook 实现方法是直接替换原方法的 18 | * extends XC_MethodHook 也是用来兼容dalvik虚拟机hook 两个实现方法是 一个是被hook方法执行前执行 一个是被hook方法执行后执行 19 | */ 20 | @Hook(Class = "com.dexposedart.newhook.MainActivity", Name = "test1", Parameter = {Button.class}, returnVal = int.class, isStatic = true) 21 | public class TestProxy2 extends XC_MethodReplacement { 22 | @Override 23 | public MethodHookParam replaceHookedMethod(MethodHookParam param) throws Throwable { 24 | Toast.makeText(App.getContext(), ((Button) param.args[0]).getText() + "->hook", 0).show(); 25 | //设置方法返回值 有返回值方法在继承XC_MethodReplacement的是否必须设置返回值 26 | param.setResult(123); 27 | return param; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/dexposedart/newhook/TestHook/TestProxy3.java: -------------------------------------------------------------------------------- 1 | package com.dexposedart.newhook.TestHook; 2 | 3 | import com.dexposedart.newhook.MainActivity; 4 | import com.taobao.android.dexposed.XC_MethodReplacement; 5 | import com.taobao.android.dexposed.annotations.Hooks; 6 | 7 | 8 | /** 9 | * 作者:zhangzhongping on 17/4/3 23:29 10 | * 邮箱:android_dy@163.com 11 | * extends XC_MethodReplacement 是用来兼容dalvik虚拟机hook 实现方法是直接替换原方法的 12 | * extends XC_MethodHook 也是用来兼容dalvik虚拟机hook 两个实现方法是 一个是被hook方法执行前执行 一个是被hook方法执行后执行 13 | */ 14 | 15 | @Hooks(Class = "com.dexposedart.newhook.MainActivity", Name = "nimabi", 16 | Parameter = {"boolean[]"}, returnVal = "boolean", isStatic = false) 17 | public class TestProxy3 extends XC_MethodReplacement { 18 | 19 | @Override 20 | public MethodHookParam replaceHookedMethod(MethodHookParam param) throws Throwable { 21 | MainActivity mainActivity = (MainActivity) param.thisObject; 22 | mainActivity.MainAct("MainActhook"); 23 | //设置方法返回值 有返回值方法在继承XC_MethodReplacement的时候必须设置返回值 24 | param.setResult(false); 25 | return param; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/dexposedart/newhook/TestHook/TestProxy4.java: -------------------------------------------------------------------------------- 1 | package com.dexposedart.newhook.TestHook; 2 | 3 | import android.widget.Button; 4 | 5 | import com.taobao.android.dexposed.HookArt.utils.HookLog; 6 | import com.taobao.android.dexposed.XC_MethodHook; 7 | import com.taobao.android.dexposed.annotations.Hook; 8 | 9 | 10 | /** 11 | * 作者:zhangzhongping on 17/4/3 23:29 12 | * 邮箱:android_dy@163.com 13 | * extends XC_MethodReplacement 是用来兼容dalvik虚拟机hook 实现方法是直接替换原方法的 14 | * extends XC_MethodHook 也是用来兼容dalvik虚拟机hook 两个实现方法是 一个是被hook方法执行前执行 一个是被hook方法执行后执行 15 | */ 16 | @Hook(Class = "com.dexposedart.newhook.MainActivity", Name = "test4", 17 | Parameter = {Button.class, String.class}, returnVal = int.class, isStatic = true) 18 | public class TestProxy4 extends XC_MethodHook { 19 | 20 | @Override 21 | public MethodHookParam beforeHookedMethod(MethodHookParam param) throws Throwable { 22 | HookLog.e("beforeHookedMethod"); 23 | param.args[1] = ((Button) param.args[0]).getText().toString() + "hook---"; 24 | return param; 25 | } 26 | 27 | @Override 28 | public MethodHookParam afterHookedMethod(MethodHookParam param) throws Throwable { 29 | HookLog.e("afterHookedMethod"); 30 | param.setResult(3636363); 31 | return param; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/dexposedart/newhook/TestHook/TestProxy41.java: -------------------------------------------------------------------------------- 1 | package com.dexposedart.newhook.TestHook; 2 | 3 | 4 | import com.taobao.android.dexposed.HookArt.utils.HookLog; 5 | import com.taobao.android.dexposed.XC_MethodHook; 6 | import com.taobao.android.dexposed.annotations.Hook; 7 | 8 | 9 | /** 10 | * 作者:zhangzhongping on 17/4/3 23:29 11 | * 邮箱:android_dy@163.com 12 | * extends XC_MethodReplacement 是用来兼容dalvik虚拟机hook 实现方法是直接替换原方法的 13 | * extends XC_MethodHook 也是用来兼容dalvik虚拟机hook 两个实现方法是 一个是被hook方法执行前执行 一个是被hook方法执行后执行 14 | */ 15 | @Hook(Class = "com.dexposedart.newhook.MainActivity", Name = "test41", returnVal = void.class, isStatic = true) 16 | public class TestProxy41 extends XC_MethodHook { 17 | 18 | @Override 19 | public MethodHookParam beforeHookedMethod(MethodHookParam param) throws Throwable { 20 | HookLog.e("test41 beforeHookedMethod"); 21 | return param; 22 | } 23 | 24 | @Override 25 | public MethodHookParam afterHookedMethod(MethodHookParam param) throws Throwable { 26 | HookLog.e("test41 afterHookedMethod"); 27 | return param; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 |