GithubHelp home page GithubHelp logo

hookmethod's Introduction

hookmethod

编译阶段替换被调用方法的工具,可用于隐私合规检测与整改

  • 注解 + ASM 修改字节码以替换被调用方法
  • 基于 com.didiglobal.booster

使用

在 app 的 build.gradle 中添加

buildscript {
    repositories {
        google()
        mavenCentral()
        maven { url "https://gitee.com/ezy/repo/raw/cosmo/"}
    }

    dependencies {
        classpath "com.didiglobal.booster:booster-gradle-plugin:4.16.3"
        classpath "me.reezy.gradle:hookmethod-booster:1.0.0"
    }
} 

apply plugin: 'com.didiglobal.booster'

hookMethod {
    // 在这些类中获取被hook的方法
    classes = ["com.demo.app.PrivacyManager"]
}

HookMethod, 将clazz类的method方法替换成被其注解的方法

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.BINARY)
annotation class HookMethod(
    val clazz: KClass<*>,           
    val method: String = "",
    val isField: Boolean = false,
    val isStatic: Boolean = false
)

使用示例

@Suppress("DEPRECATION")
@SuppressLint("MissingPermission", "NewApi", "HardwareIds")
object PrivacyManager {
    @JvmStatic
    var isUserGranted: () -> Boolean = { false }


    //<editor-fold desc="android.os.Build">
    private var brand: String = ""
    @HookMethod(Build::class, "BRAND", isField = true, isStatic = true)
    @JvmStatic
    fun getBrand(): String {
        return delegate("Build.BRAND") {
            if (isUserGranted() && brand.isNotEmpty()) {
                brand = Build.BRAND
            }
            brand
        }
    }

    @HookMethod(Build::class, isStatic = true)
    @JvmStatic
    fun getSerial(): String {
        return delegate("BUILD.getSerial()") { if (isUserGranted()) Build.getSerial() else "" }
    }
    //</editor-fold>

    //<editor-fold desc="ActivityManager">
    @HookMethod(ActivityManager::class)
    @JvmStatic
    fun getRunningTasks(manager: ActivityManager, maxNum: Int): List<RunningTaskInfo> { 
        return delegate("getRunningTasks") { if (isUserGranted()) manager.getRunningTasks(maxNum) else emptyList() }
    }
    //</editor-fold>
 
 

    //<editor-fold desc="Settings">  
    @HookMethod(clazz = Settings.Secure::class, method = "getString", isStatic = true)
    @JvmStatic
    fun getSecureString(resolver: ContentResolver, name: String): String? {
        return delegate("getSecureString($name)") {
            if (Settings.Secure.ANDROID_ID != name || isUserGranted()) Settings.Secure.getString(resolver, name) else ""
        }
    }
    //</editor-fold>
 
}

处理过程分为两步:

  1. onPreTransform 中收集待hook的方法,结束后生成日志 build/reports/HookMethodTransformer/xx/methods.txt
android/os/Build.{BRAND -> getBrand} : Ljava/lang/String; -> ()Ljava/lang/String;
android/os/Build.getSerial : ()Ljava/lang/String; -> ()Ljava/lang/String;
android/app/ActivityManager.getRunningTasks : (I)Ljava/util/List; -> (Landroid/app/ActivityManager;I)Ljava/util/List;
android/telephony/TelephonyManager.getDeviceId : ()Ljava/lang/String; -> (Landroid/telephony/TelephonyManager;)Ljava/lang/String;
android/telephony/TelephonyManager.getImei : ()Ljava/lang/String; -> (Landroid/telephony/TelephonyManager;)Ljava/lang/String;
android/telephony/TelephonyManager.getMeid : ()Ljava/lang/String; -> (Landroid/telephony/TelephonyManager;)Ljava/lang/String;
android/telephony/TelephonyManager.getSimSerialNumber : ()Ljava/lang/String; -> (Landroid/telephony/TelephonyManager;)Ljava/lang/String;
android/telephony/TelephonyManager.getSubscriberId : ()Ljava/lang/String; -> (Landroid/telephony/TelephonyManager;)Ljava/lang/String;
java/net/NetworkInterface.getHardwareAddress : ()[B -> (Ljava/net/NetworkInterface;)[B
android/provider/Settings$System.{getString -> getSystemString} : (Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String; -> (Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;
android/provider/Settings$Secure.{getString -> getSecureString} : (Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String; -> (Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;
android/net/wifi/WifiInfo.getMacAddress : ()Ljava/lang/String; -> (Landroid/net/wifi/WifiInfo;)Ljava/lang/String;
android/net/wifi/WifiInfo.getSSID : ()Ljava/lang/String; -> (Landroid/net/wifi/WifiInfo;)Ljava/lang/String;
android/net/wifi/WifiInfo.getBSSID : ()Ljava/lang/String; -> (Landroid/net/wifi/WifiInfo;)Ljava/lang/String;
android/net/wifi/WifiInfo.getRssi : ()I -> (Landroid/net/wifi/WifiInfo;)I
android/net/wifi/WifiInfo.getNetworkId : ()I -> (Landroid/net/wifi/WifiInfo;)I

  1. transform 将待hook的方法调用替换为目标方法调用,结束后生成日志 build/reports/HookMethodTransformer/xx/hooks.txt
GETSTATIC, android/os/Build.BRAND -> com/google/android/material/color/DynamicColors.isDynamicColorAvailable
INVOKESTATIC, android/provider/Settings$Secure.getString -> androidx/core/app/NotificationManagerCompat.getEnabledListenerPackages
INVOKESTATIC, android/provider/Settings$Secure.getString -> androidx/core/location/LocationManagerCompat.isLocationEnabled
INVOKEVIRTUAL, android/telephony/TelephonyManager.getImei -> androidx/core/telephony/TelephonyManagerCompat$Api26Impl.getImei
INVOKEVIRTUAL, android/telephony/TelephonyManager.getDeviceId -> androidx/core/telephony/TelephonyManagerCompat.getImei
GETSTATIC, android/os/Build.BRAND -> com/demo/app/MainActivity.onCreate
INVOKESTATIC, android/os/Build.getSerial -> com/demo/app/MainActivity.onCreate
INVOKEVIRTUAL, android/app/ActivityManager.getRunningTasks -> com/demo/app/MainActivity.onCreate
INVOKESTATIC, android/provider/Settings$Secure.getString -> com/demo/app/MainActivity.onCreate

LICENSE

The Component is open-sourced software licensed under the Apache license.

hookmethod's People

Contributors

czy1121 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.