├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.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 │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── drawable │ │ │ │ ├── log_bg.xml │ │ │ │ └── ic_launcher_background.xml │ │ │ ├── layout │ │ │ │ └── activity_main.xml │ │ │ └── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── zaze │ │ │ └── hook │ │ │ └── checker │ │ │ ├── App.kt │ │ │ ├── MainActivity.kt │ │ │ ├── DeviceChecker.kt │ │ │ └── MyLogClient.kt │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── zaze │ │ │ └── hook │ │ │ └── checker │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── zaze │ │ └── hook │ │ └── checker │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── checker ├── consumer-rules.pro ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ └── values │ │ │ │ └── strings.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── zaze │ │ │ └── hook │ │ │ └── checker │ │ │ ├── log │ │ │ ├── CheckerLogClient.kt │ │ │ └── CheckerLog.kt │ │ │ ├── DebuggerChecker.kt │ │ │ ├── CheckResult.kt │ │ │ ├── RootChecker.kt │ │ │ ├── CheckerUtil.kt │ │ │ ├── ExecUtil.kt │ │ │ ├── XposedChecker.kt │ │ │ └── QemuChecker.kt │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── zaze │ │ │ └── hook │ │ │ └── checker │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── zaze │ │ └── hook │ │ └── checker │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── xposed ├── .gitignore ├── consumer-rules.pro ├── src │ ├── main │ │ ├── assets │ │ │ └── xposed_init │ │ ├── res │ │ │ ├── values │ │ │ │ └── strings.xml │ │ │ └── layout │ │ │ │ └── device_hook_act.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── zaze │ │ │ │ └── hook │ │ │ │ └── xposed │ │ │ │ ├── devices │ │ │ │ ├── DeviceInfo.kt │ │ │ │ ├── DeviceHookActivity.kt │ │ │ │ ├── DeviceInfoHooker.kt │ │ │ │ └── DeviceUtil.kt │ │ │ │ ├── core │ │ │ │ ├── HookCore.kt │ │ │ │ ├── ApplicationHook.kt │ │ │ │ ├── XC_ResultHook.kt │ │ │ │ ├── TelephonyManagerHook.kt │ │ │ │ ├── StackTraceElementHook.kt │ │ │ │ ├── SettingsHook.kt │ │ │ │ └── BuildHook.kt │ │ │ │ ├── view │ │ │ │ └── ViewHooker.kt │ │ │ │ ├── MyXposedHookLoadPackage.kt │ │ │ │ ├── HookFilter.kt │ │ │ │ ├── Utils.kt │ │ │ │ ├── data │ │ │ │ ├── PropertiesHelper.kt │ │ │ │ ├── XposedSharedPreferencesHelper.kt │ │ │ │ └── HookProvider.kt │ │ │ │ └── XposedTest.kt │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── zaze │ │ │ └── hook │ │ │ └── xposed │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── zaze │ │ └── hook │ │ └── xposed │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── gradle.properties ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /checker/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xposed/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /xposed/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /checker/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':checker', ':xposed' 2 | rootProject.name='HookChecker' 3 | -------------------------------------------------------------------------------- /xposed/src/main/assets/xposed_init: -------------------------------------------------------------------------------- 1 | com.zaze.hook.xposed.XposedTest 2 | com.zaze.hook.xposed.devices.DeviceInfoHooker -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | HookChecker 3 | 4 | -------------------------------------------------------------------------------- /checker/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | checker 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaze359/HookChecker/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /xposed/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | xposed 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaze359/HookChecker/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaze359/HookChecker/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | .cxx 10 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaze359/HookChecker/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaze359/HookChecker/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaze359/HookChecker/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /checker/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaze359/HookChecker/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaze359/HookChecker/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaze359/HookChecker/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaze359/HookChecker/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaze359/HookChecker/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Dec 13 14:08:08 CST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/log_bg.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/zaze/hook/checker/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.checker 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /xposed/src/test/java/com/zaze/hook/xposed/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /checker/src/test/java/com/zaze/hook/checker/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.checker 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /xposed/src/main/java/com/zaze/hook/xposed/devices/DeviceInfo.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed.devices 2 | 3 | /** 4 | * Description : 5 | * @author : ZAZE 6 | * @version : 2019-12-13 - 16:33 7 | */ 8 | data class DeviceInfo(val deviceId: String? = null, val deviceModel: String? = null) { 9 | 10 | // fun copy(deviceInfo: DeviceInfo?) { 11 | // deviceInfo?.let { 12 | // deviceId = it.deviceId 13 | // deviceModel = it.deviceModel 14 | // } ?: DeviceInfo() 15 | // 16 | // } 17 | 18 | } -------------------------------------------------------------------------------- /xposed/src/main/java/com/zaze/hook/xposed/core/HookCore.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed.core 2 | 3 | import de.robv.android.xposed.callbacks.XC_LoadPackage 4 | 5 | /** 6 | * Description : 7 | * @author : ZAZE 8 | * @version : 2019-12-16 - 15:07 9 | */ 10 | class HookCore(lpparam: XC_LoadPackage.LoadPackageParam) { 11 | val TelephonyManager = TelephonyManagerHook(lpparam) 12 | val Settings = SettingsHook(lpparam) 13 | val Build = BuildHook(lpparam) 14 | val Application = ApplicationHook() 15 | val StackTraceElement = StackTraceElementHook() 16 | } -------------------------------------------------------------------------------- /xposed/src/main/java/com/zaze/hook/xposed/view/ViewHooker.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed.view 2 | 3 | import com.zaze.hook.xposed.MyXposedHookLoadPackage 4 | import de.robv.android.xposed.IXposedHookLoadPackage 5 | import de.robv.android.xposed.callbacks.XC_LoadPackage 6 | 7 | /** 8 | * Description : 9 | * 10 | * @author : ZAZE 11 | * @version : 2020-02-09 - 21:09 12 | */ 13 | class ViewHooker: MyXposedHookLoadPackage() { 14 | 15 | 16 | override fun actualHandleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) { 17 | } 18 | 19 | 20 | private fun hookTextView() { 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /checker/src/main/java/com/zaze/hook/checker/log/CheckerLogClient.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.checker.log 2 | 3 | /** 4 | * Description : 5 | * 6 | * @author : ZAZE 7 | * @version : 2019-05-24 - 15:33 8 | */ 9 | open class CheckerLogClient { 10 | 11 | open fun v(tag: String, msg: String) {} 12 | open fun d(tag: String, msg: String) {} 13 | open fun i(tag: String, msg: String) {} 14 | open fun w(tag: String, msg: String) {} 15 | open fun w(tag: String, msg: String, tr: Throwable) {} 16 | open fun e(tag: String, msg: String) {} 17 | open fun e(tag: String, msg: String, tr: Throwable) {} 18 | } 19 | -------------------------------------------------------------------------------- /xposed/src/main/java/com/zaze/hook/xposed/core/ApplicationHook.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed.core 2 | 3 | import android.app.Application 4 | import android.content.Context 5 | import de.robv.android.xposed.XC_MethodHook 6 | import de.robv.android.xposed.XposedHelpers 7 | 8 | /** 9 | * Description : 10 | * @author : ZAZE 11 | * @version : 2019-12-17 - 14:40 12 | */ 13 | class ApplicationHook internal constructor() { 14 | 15 | fun getContext(methodHook: XC_MethodHook) { 16 | XposedHelpers.findAndHookMethod( 17 | Application::class.java, 18 | "attach", 19 | Context::class.java, 20 | methodHook 21 | ) 22 | } 23 | } -------------------------------------------------------------------------------- /xposed/src/main/java/com/zaze/hook/xposed/core/XC_ResultHook.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed.core 2 | 3 | import de.robv.android.xposed.XC_MethodHook 4 | import de.robv.android.xposed.XposedBridge 5 | 6 | /** 7 | * Description : 8 | * @author : ZAZE 9 | * @version : 2019-12-16 - 15:33 10 | */ 11 | class XC_ResultHook(private val result: Any) : XC_MethodHook() { 12 | override fun afterHookedMethod(param: MethodHookParam?) { 13 | if (param != null) { 14 | XposedBridge.log("${param.method.declaringClass.name} ${param.method.name} result: ${param.result}; hooked : ${result}") 15 | param.result = result 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /xposed/src/main/java/com/zaze/hook/xposed/core/TelephonyManagerHook.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed.core 2 | 3 | import android.telephony.TelephonyManager 4 | import de.robv.android.xposed.XposedHelpers 5 | import de.robv.android.xposed.callbacks.XC_LoadPackage 6 | 7 | /** 8 | * Description : 9 | * @author : ZAZE 10 | * @version : 2019-12-16 - 15:12 11 | */ 12 | class TelephonyManagerHook internal constructor(lpparam: XC_LoadPackage.LoadPackageParam) { 13 | companion object { 14 | const val TAG = "TelephonyManagerHook" 15 | val clazz = TelephonyManager::class.java 16 | } 17 | 18 | fun getDeviceId(result: String) { 19 | XposedHelpers.findAndHookMethod(clazz, "getDeviceId", XC_ResultHook(result)) 20 | } 21 | } -------------------------------------------------------------------------------- /checker/src/main/java/com/zaze/hook/checker/DebuggerChecker.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.checker 2 | 3 | import android.content.Context 4 | import android.content.pm.ApplicationInfo 5 | import android.os.Debug 6 | 7 | /** 8 | * Description : 9 | * @author : ZAZE 10 | * @version : 2019-11-27 - 14:07 11 | */ 12 | object DebuggerChecker { 13 | private const val TAG = "DebuggerChecker" 14 | fun detectDebugger(context: Context): Boolean { 15 | return context.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE > 0 || Debug.isDebuggerConnected() 16 | // CheckerLog.i( 17 | // TAG, 18 | // "FLAG_DEBUGGABLE : ${}" 19 | // ) 20 | // CheckerLog.i(TAG, "isDebuggerConnected : ${Debug.isDebuggerConnected()}") 21 | } 22 | } -------------------------------------------------------------------------------- /checker/src/main/java/com/zaze/hook/checker/CheckResult.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.checker 2 | 3 | /** 4 | * Description : 5 | * @author : ZAZE 6 | * @version : 2020-02-19 - 14:33 7 | */ 8 | class CheckResult { 9 | 10 | /** 11 | * flag > 0 表示存在问题 12 | */ 13 | private var flags = 0 14 | /** 15 | * 16 | */ 17 | var messageBuilder = StringBuilder() 18 | 19 | fun addError(message: String) { 20 | flags++ 21 | addMessageNoError(message) 22 | } 23 | 24 | fun addMessageNoError(message: String) { 25 | messageBuilder.append("$message \n") 26 | } 27 | 28 | fun isError(): Boolean { 29 | return flags > 0 30 | } 31 | 32 | fun clear() { 33 | flags = 0 34 | messageBuilder.clear() 35 | } 36 | 37 | 38 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/com/zaze/hook/checker/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.checker 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.zaze.hook.checker", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /checker/src/androidTest/java/com/zaze/hook/checker/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.checker 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.zaze.hook.checker.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /xposed/src/androidTest/java/com/zaze/hook/xposed/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.zaze.hook.xposed.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /xposed/src/main/java/com/zaze/hook/xposed/MyXposedHookLoadPackage.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed 2 | 3 | import de.robv.android.xposed.IXposedHookLoadPackage 4 | import de.robv.android.xposed.callbacks.XC_LoadPackage 5 | 6 | /** 7 | * Description : 8 | * 9 | * @author : ZAZE 10 | * @version : 2020-02-09 - 21:10 11 | */ 12 | abstract class MyXposedHookLoadPackage : IXposedHookLoadPackage { 13 | 14 | override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) { 15 | if (HookFilter.handleLoadPackage(lpparam)) { 16 | return 17 | } 18 | try { 19 | actualHandleLoadPackage(lpparam) 20 | } catch (e: Throwable) { 21 | e.printStackTrace() 22 | } 23 | } 24 | 25 | abstract fun actualHandleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) 26 | 27 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /checker/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /xposed/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /xposed/src/main/java/com/zaze/hook/xposed/HookFilter.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed 2 | 3 | import android.content.pm.ApplicationInfo 4 | import de.robv.android.xposed.XposedBridge 5 | import de.robv.android.xposed.callbacks.XC_LoadPackage 6 | 7 | /** 8 | * Description : 9 | * @author : ZAZE 10 | * @version : 2019-12-16 - 10:51 11 | */ 12 | object HookFilter { 13 | 14 | val pkgSet = setOf("android", "com.topjohnwu.magisk", "de.robv.android.xposed.installer") 15 | 16 | fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam): Boolean { 17 | if (pkgSet.contains(lpparam.packageName)) { 18 | XposedBridge.log("过滤重要应用不hook: ${lpparam.packageName}") 19 | return true 20 | } 21 | if (lpparam.appInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0) { 22 | return true 23 | } 24 | return false 25 | } 26 | } -------------------------------------------------------------------------------- /xposed/src/main/java/com/zaze/hook/xposed/Utils.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed 2 | 3 | import com.google.gson.GsonBuilder 4 | 5 | /** 6 | * Description : 7 | * @author : ZAZE 8 | * @version : 2019-12-17 - 14:13 9 | */ 10 | object Utils { 11 | private val gsonBuilder = GsonBuilder() 12 | 13 | fun objToJson(any: Any?): String? { 14 | return try { 15 | gsonBuilder.create().toJson(any) 16 | } catch (e: Exception) { 17 | null 18 | } 19 | } 20 | 21 | fun parseJson(json: String?, classOfT: Class?): T? { 22 | if (json == null || classOfT == null) { 23 | return null 24 | } 25 | return try { 26 | gsonBuilder.create().fromJson(json, classOfT) 27 | } catch (e: Throwable) { 28 | e.printStackTrace() 29 | null 30 | } 31 | 32 | } 33 | } -------------------------------------------------------------------------------- /xposed/src/main/java/com/zaze/hook/xposed/core/StackTraceElementHook.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed.core 2 | 3 | import de.robv.android.xposed.XC_MethodHook 4 | import de.robv.android.xposed.XposedHelpers 5 | 6 | /** 7 | * Description : 8 | * @author : ZAZE 9 | * @version : 2019-12-17 - 17:50 10 | */ 11 | class StackTraceElementHook internal constructor() { 12 | init { 13 | XposedHelpers.findAndHookMethod( 14 | StackTraceElement::class.java, 15 | "getClassName", 16 | object : XC_MethodHook() { 17 | override fun afterHookedMethod(param: MethodHookParam?) { 18 | param?.result?.toString()?.let { 19 | if (it.contains("de.robv.android.xposed.")) { 20 | param.result = "hooked" 21 | } 22 | } 23 | } 24 | }) 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/zaze/hook/checker/App.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.checker 2 | 3 | import android.app.Application 4 | import com.zaze.hook.checker.log.CheckerLog 5 | 6 | /** 7 | * Description : 8 | * @author : ZAZE 9 | * @version : 2019-12-18 - 13:52 10 | */ 11 | class App : Application() { 12 | 13 | private lateinit var mdmLogClient: MyLogClient 14 | 15 | fun getMdmLogClient(): MyLogClient { 16 | return mdmLogClient 17 | } 18 | 19 | companion object { 20 | private lateinit var INSTANCE: Application 21 | 22 | fun getInstance(): App { 23 | return INSTANCE as App 24 | } 25 | } 26 | 27 | override fun onCreate() { 28 | super.onCreate() 29 | INSTANCE = this 30 | mdmLogClient = MyLogClient() 31 | CheckerLog.setLogClient(mdmLogClient) 32 | } 33 | 34 | 35 | fun getLogDir(): String { 36 | return this.externalCacheDir!!.absolutePath 37 | } 38 | } -------------------------------------------------------------------------------- /checker/src/main/java/com/zaze/hook/checker/RootChecker.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.checker 2 | 3 | import java.io.File 4 | 5 | /** 6 | * Description : 7 | * @author : ZAZE 8 | * @version : 2019-12-19 - 13:46 9 | */ 10 | class RootChecker { 11 | 12 | companion object { 13 | const val TAG = "RootChecker" 14 | } 15 | 16 | val result = CheckResult() 17 | 18 | fun detectRoot() { 19 | detectByFile() 20 | detectByCmd() 21 | } 22 | 23 | private fun detectByCmd() { 24 | val cmdResult = ExecUtil.exec(arrayOf("su")) 25 | if (cmdResult.first == ExecUtil.SUCCESS) { 26 | result.addError("$TAG hit detectByCmd: su ${cmdResult.second} ") 27 | 28 | } 29 | // return !TextUtils.isEmpty().toString()) 30 | } 31 | 32 | private fun detectByFile() { 33 | arrayOf( 34 | "/system/bin/", 35 | "/system/xbin/", 36 | "/system/sbin/", 37 | "/sbin/", 38 | "/vendor/bin/" 39 | ).forEach { 40 | if (File("${it}su").exists()) { 41 | result.addError("$TAG hit detectByFile: ${it}su") 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /xposed/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 15 | 18 | 19 | 20 | 21 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /checker/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | android { 5 | compileSdkVersion 29 6 | buildToolsVersion "29.0.2" 7 | 8 | 9 | defaultConfig { 10 | minSdkVersion 15 11 | targetSdkVersion 29 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | consumerProguardFiles 'consumer-rules.pro' 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(dir: 'libs', include: ['*.jar']) 30 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 31 | implementation 'androidx.appcompat:appcompat:1.1.0' 32 | implementation 'androidx.core:core-ktx:1.0.2' 33 | testImplementation 'junit:junit:4.12' 34 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 35 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 36 | } 37 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/zaze/hook/checker/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.checker 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.text.method.ScrollingMovementMethod 6 | import androidx.appcompat.app.AppCompatActivity 7 | import com.zaze.common.thread.ThreadPlugins 8 | import com.zaze.hook.xposed.devices.DeviceHookActivity 9 | import kotlinx.android.synthetic.main.activity_main.* 10 | 11 | class MainActivity : AppCompatActivity() { 12 | 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | setContentView(R.layout.activity_main) 16 | debugLogContent.movementMethod = ScrollingMovementMethod.getInstance() 17 | App.getInstance().getMdmLogClient().bind(debugLogContent) 18 | 19 | checkDeviceBtn.setOnClickListener { 20 | ThreadPlugins.runInUIThread(Runnable { 21 | DeviceChecker.detectSafely() 22 | }, 0) 23 | } 24 | changedDeviceInfo.setOnClickListener { 25 | startActivity(Intent(this, DeviceHookActivity::class.java)) 26 | } 27 | } 28 | 29 | override fun onDestroy() { 30 | super.onDestroy() 31 | App.getInstance().getMdmLogClient().unBind() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /xposed/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | android { 5 | compileSdkVersion 29 6 | buildToolsVersion "29.0.2" 7 | 8 | 9 | defaultConfig { 10 | minSdkVersion 15 11 | targetSdkVersion 29 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | consumerProguardFiles 'consumer-rules.pro' 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(dir: 'libs', include: ['*.jar']) 30 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 31 | implementation 'androidx.appcompat:appcompat:1.1.0' 32 | implementation 'androidx.core:core-ktx:1.1.0' 33 | implementation 'com.google.code.gson:gson:2.8.5' 34 | testImplementation 'junit:junit:4.12' 35 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 36 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 37 | // implementation 'com.squareup.okhttp3:okhttp:3.11.0' 38 | 39 | compileOnly 'de.robv.android.xposed:api:82' 40 | compileOnly 'de.robv.android.xposed:api:82:sources' 41 | } 42 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | android { 8 | compileSdkVersion 29 9 | buildToolsVersion "29.0.2" 10 | defaultConfig { 11 | applicationId "com.zaze.hook.checker" 12 | minSdkVersion 16 13 | targetSdkVersion 29 14 | versionCode 1 15 | versionName "1.0" 16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | } 25 | 26 | configurations.all { 27 | // check for updates every build 28 | resolutionStrategy.cacheChangingModulesFor 1, 'seconds' 29 | resolutionStrategy.cacheDynamicVersionsFor 1, 'seconds' 30 | } 31 | 32 | dependencies { 33 | implementation fileTree(dir: 'libs', include: ['*.jar']) 34 | implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 35 | implementation 'androidx.appcompat:appcompat:1.1.0' 36 | implementation 'androidx.core:core-ktx:1.0.2' 37 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 38 | // implementation 'com.github.zaze359.test:zazeutil:1.0.5' 39 | implementation 'com.github.zaze359:test:master-SNAPSHOT' 40 | 41 | testImplementation 'junit:junit:4.12' 42 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 43 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 44 | 45 | implementation project(':checker') 46 | implementation project(':xposed') 47 | 48 | } 49 | -------------------------------------------------------------------------------- /checker/src/main/java/com/zaze/hook/checker/log/CheckerLog.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.checker.log 2 | 3 | import android.util.Log 4 | 5 | /** 6 | * Description : 7 | * @author : ZAZE 8 | * @version : 2019-04-02 - 16:08 9 | */ 10 | object CheckerLog { 11 | 12 | private var logClient: CheckerLogClient? = null 13 | 14 | private fun getLogClient(): CheckerLogClient? { 15 | return logClient 16 | } 17 | 18 | @JvmStatic 19 | fun setLogClient(logClient: CheckerLogClient) { 20 | CheckerLog.logClient = logClient 21 | } 22 | 23 | @JvmStatic 24 | fun v(tag: String, msg: String) { 25 | getLogClient()?.v(tag, msg) ?: Log.v(tag, msg) 26 | } 27 | 28 | @JvmStatic 29 | fun d(tag: String, msg: String) { 30 | getLogClient()?.d(tag, msg) ?: Log.d(tag, msg) 31 | } 32 | 33 | @JvmStatic 34 | fun i(tag: String, msg: String) { 35 | getLogClient()?.i(tag, msg) ?: Log.i(tag, msg) 36 | } 37 | 38 | @JvmStatic 39 | fun w(tag: String, msg: String) { 40 | getLogClient()?.w(tag, msg) ?: Log.w(tag, msg) 41 | } 42 | 43 | @JvmStatic 44 | fun w(tag: String, msg: String, tr: Throwable) { 45 | getLogClient()?.w(tag, msg, tr) ?: Log.w(tag, msg, tr) 46 | } 47 | 48 | @JvmStatic 49 | fun e(tag: String, msg: String) { 50 | getLogClient()?.e(tag, msg) ?: Log.e(tag, msg) 51 | } 52 | 53 | @JvmStatic 54 | fun e(tag: String, msg: String, tr: Throwable) { 55 | getLogClient()?.e(tag, msg, tr) ?: Log.e(tag, msg, tr) 56 | } 57 | 58 | @JvmStatic 59 | fun log(tag: String, msg: String, isImportant: Boolean? = null) { 60 | when { 61 | isImportant == null -> v(tag, msg) 62 | isImportant -> e(tag, msg) 63 | else -> d(tag, msg) 64 | } 65 | 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /checker/src/main/java/com/zaze/hook/checker/CheckerUtil.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.checker 2 | 3 | import java.io.BufferedReader 4 | import java.io.IOException 5 | import java.io.InputStream 6 | import java.io.Reader 7 | 8 | /** 9 | * Description : 10 | * @author : ZAZE 11 | * @version : 2019-12-19 - 13:28 12 | */ 13 | object CheckerUtil { 14 | 15 | @JvmStatic 16 | fun readByBytes(inputStream: InputStream, bufferSize: Int = 1024): StringBuilder { 17 | val results = StringBuilder() 18 | try { 19 | val bytes = ByteArray(bufferSize) 20 | var byteLength = inputStream.read(bytes) 21 | while (byteLength != -1) { 22 | results.append(String(bytes, 0, byteLength)) 23 | byteLength = inputStream.read(bytes) 24 | } 25 | } catch (e: Exception) { 26 | e.printStackTrace() 27 | } finally { 28 | try { 29 | inputStream.close() 30 | } catch (e: IOException) { 31 | e.printStackTrace() 32 | } 33 | } 34 | return results 35 | } 36 | 37 | @JvmStatic 38 | fun readLine(reader: Reader): StringBuilder { 39 | var bfReader: BufferedReader? = null 40 | val results = StringBuilder() 41 | try { 42 | bfReader = BufferedReader(reader) 43 | var line = bfReader.readLine() 44 | while (line != null) { 45 | results.append(line) 46 | line = bfReader.readLine() 47 | } 48 | } catch (e: Exception) { 49 | e.printStackTrace() 50 | } finally { 51 | try { 52 | bfReader?.close() 53 | } catch (e: IOException) { 54 | e.printStackTrace() 55 | } 56 | } 57 | return results 58 | } 59 | } -------------------------------------------------------------------------------- /xposed/src/main/java/com/zaze/hook/xposed/data/PropertiesHelper.kt: -------------------------------------------------------------------------------- 1 | package com.zaze.hook.xposed.data 2 | 3 | import android.util.Log 4 | import java.io.File 5 | import java.io.FileInputStream 6 | import java.io.FileOutputStream 7 | import java.io.IOException 8 | import java.util.* 9 | 10 | /** 11 | * Description : 12 | * @author : ZAZE 13 | * @version : 2019-12-13 - 16:24 14 | */ 15 | internal object PropertiesHelper { 16 | 17 | /** 18 | * 加载 19 | * 20 | * @param file 21 | * @return 22 | */ 23 | fun load(file: File): Properties { 24 | val properties = Properties() 25 | if (file.exists()) { 26 | var inputStream: FileInputStream? = null 27 | try { 28 | inputStream = FileInputStream(file) 29 | properties.load(inputStream) 30 | } catch (e: Exception) { 31 | Log.e("DeviceInfoLoader", "load error", e) 32 | } finally { 33 | try { 34 | inputStream?.close() 35 | } catch (e: Exception) { 36 | // ignore 37 | } 38 | } 39 | } 40 | return properties 41 | } 42 | 43 | fun store(file: File, properties: Properties) { 44 | if (!file.exists()) { 45 | file.parentFile?.mkdirs() 46 | file.createNewFile() 47 | } 48 | 49 | var outputStream: FileOutputStream? = null 50 | try { 51 | outputStream = FileOutputStream(file, false) 52 | properties.store(outputStream, "") 53 | } catch (e: Exception) { 54 | Log.e("DeviceInfoLoader", "store error", e) 55 | } finally { 56 | try { 57 | outputStream?.close() 58 | } catch (e: IOException) { 59 | // ignore 60 | } 61 | } 62 | } 63 | 64 | 65 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 24 | 25 |