Uso compartido de complementos de gancho de instrumentación de bytecode de método de Android, enterramiento completo, monitoreo de rendimiento, subprocesos, monitoreo de creación de IO, ventanilla única, altamente personalizable, ¡muy fácil de usar!

Dirección del proyecto: gancho-método-plugin

Este es un complemento para el gancho de método de Android. Cuando el método entra y sale, todos los parámetros que se están ejecutando actualmente se vuelven a llamar a la interfaz fija. Con esto, se puede llevar a cabo el desarrollo del segmento del método. Al configurar el punto de gancho, el monitoreo de gancho se puede lograr Propósito.

Con este complemento, puedes:

  1. Punto de enterramiento completo de Android, navegación de páginas, clic, etc. Sin rastro de punto de entierro, solo configure el punto de enganche según sea necesario, el método de configuración es el siguiente
  2. Método Android que requiere mucho tiempo, estadísticas de rendimiento
  3. Varios interceptores, por ejemplo, para interceptar un método, antes de ejecutar un método, primero determinan la autoridad o hacen preparativos
  4. Agregue código al paquete jar de terceros al que se hace referencia, agregue creación de subprocesos, monitoreo relacionado con archivo IO, etc.
  5. Verifique la lógica de ejecución que hace referencia a los SDK de terceros, como verificar qué SDK obtiene la ubicación, el imei y las ejecuciones frecuentes en segundo plano.

Mostrar resultados

Por ejemplo, en el desarrollo diario, es posible que inevitablemente tengamos que realizar algunas tareas de ocultación de eventos de clic. Si usamos este complemento, podemos configurar y contar directamente todos los puntos de ocultación de eventos de clic una vez. Echemos un vistazo a los métodos específicos:

  1. Primero defina el punto de gancho, el objetivo de este punto de gancho es monitorear todos los eventos de clic. Agregue el siguiente código a build.gradle en el módulo de la aplicación y el significado de los campos detallados se explicará a continuación.
apply plugin: 'com.miqt.plugin.hookmethod'
hook_method {
    
    
    buildLog = true
    injectJar = false //是否hook引用的第三方jar包
    enable = true
    hookTargets {
    
    
        hook_onclick {
    
     // <-- 定义Hook点
            interfaces = "android/view/View\$OnClickListener"//<-- hook条件1,继承了这个接口
            methodName = "onClick"							//<-- hook条件2,方法名
            descriptor = "(Landroid/view/View;)V"			//<-- hook条件3,方法参数和返回值类型
            hookTiming = "Enter"							//<-- hook条件4,指定是在方法进入时进行Hook
        }
    }
}

hook_method es la configuración general del complemento, y hookTargets es la configuración del punto Hook. Al compilar, se filtrará de acuerdo con las condiciones de filtro definidas. Solo cuando se cumplan las cuatro condiciones al mismo tiempo, la instrumentación será realizado.

Tenga en cuenta que debido a que es una operación de código de bytes, las definiciones aquí descriptorson tanto descriptores de campo como descriptores de código de bytes . Si no lo sabe, puede encontrarlo en Baidu, que es muy simple. Está bien si no quiere saberlo, presentaré un método para ver directamente la información del código de bytes de un método. Usar @HookInfoanotaciones

Después de la configuración anterior, escribimos un botón casualmente y luego agregamos un evento de clic.

public class MainActivity extends Activity {
    
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                Toast.makeText(MainActivity.this, "onClick", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

Haga clic en el botón de sincronización para compilar el proyecto. En este momento, el complemento generará automáticamente la clase de procesamiento del controlador de reenvío de enlace para el evento de clic:

Algo como esto: HookHandler

En este momento, abrimos la vista y descompilación de Apk, y podemos ver el código auxiliar:

public class MainActivity extends Activity {
    
    
    /* access modifiers changed from: protected */
    public void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
    
    
            /* class com.asm.code.MainActivity.AnonymousClass1 */

            public void onClick(View view) {
    
    
                HookHandler.hook_onclickEnter(this, "com/asm/code/MainActivity$1", "onClick", "[android.view.View]", "void", new Object[]{
    
    view});//<--插桩的代码
                Toast.makeText(MainActivity.this, "onClick", 0).show();
            }
        });
    }
}

En este punto, solo necesitamos hook_onclickEnterescribir la lógica de procesamiento y monitoreo de eventos de clic global en este método. Todo esto lo hace automáticamente el complemento. Solo necesitamos configurar las reglas de Hook. ¿No es muy simple?

Portal de configuración de ejemplo: https://github.com/miqt/android-plugin/blob/master/app/build.gradle

Por analogía, el complemento también puede lograr el propósito de la programación de aspectos al personalizar las reglas de Hook y el código de cualquier método en el proyecto Hook.

Usar método de configuración

  1. Agregar repositorio maven

    maven {
          
           url 'https://raw.githubusercontent.com/miqt/maven/master' }
    maven {
          
           url 'https://gitee.com/miqt/maven/raw/master' }
    

    ¿Aún no puedes sacar la biblioteca?

    maven {
          
           url 'https://raw.fastgit.org/miqt/maven/master' }
    

    O vaya a la dirección git de mi almacén para descargarlo y confíe en él localmente.

    Lo usé al principio jcenter(), pero luego esta biblioteca quedó obsoleta oficialmente, pero ahora la versión 0.3.5 aún se puede extraer de esta biblioteca, y uso gitee y github como direcciones de almacenamiento de almacén para versiones posteriores.

  2. Agregar dependencias de complementos

    Directorio raíz del proyecto: build.gradle agregue el siguiente código

    dependencies {
          
          
        classpath 'com.miqt:hook-method-plugin:0.4.1'
    }
    

    El complemento se habilita en el módulo correspondiente, que puede ser applicationolibrary

    apply plugin: 'com.miqt.plugin.hookmethod'
    hook_method {
          
          
        buildLog = true
        injectJar = false //是否hook引用的第三方jar包
        enable = true
        hookTargets {
          
          
            hook_onclick {
          
           // <-- 自定义Hook点
                interfaces = "android/view/View\$OnClickListener"	//<-- hook条件1,继承了这个接口
                methodName = "onClick"	//<-- hook条件2,方法名
                descriptor = "(Landroid/view/View;)V"	//<-- hook条件3,方法参数和返回值类型
                hookTiming = "Enter"	//<-- hook条件4,指定是在方法进入时进行Hook
            }
        }
    }
    
  3. Agregar dependencias de la biblioteca de clases en el módulo correspondiente

    dependencies {
          
          
        implementation 'com.miqt:hook-method-lib:0.4.1'
    }
    

    ¡Limpie el proyecto y ejecútelo, filtre logcat MethodHookHandlery podrá ver el resultado de la impresión!

Descripción de los parámetros de configuración del complemento

Parámetros en hook_method {}

Esto es para definir la configuración relacionada con el complemento.

parámetro ¿Es obligatorio? tipo significado valores predeterminados
permitir No bool Ya sea para habilitar verdadero
ejecutarVariante No cadena El entorno de ejecución del complemento, a veces solo queremos insertar stubs en el entorno de depuración, y el entorno de lanzamiento no lo necesita. En este momento, se puede configurar en: DEBUG, lo que significa que solo cuando se ejecuta DEBUG, se ejecuta el complemento. Este parámetro tiene cuatro valores enumerados: DEBUG
: solo depuración de instrumentación en tiempo de ejecución
RELEASE: solo RELEASE instrumentación en
tiempo de ejecución SIEMPRE: todos los tiempos de ejecución (predeterminado)
NUNCA: nunca instrumentación, equivalente a habilitar = falso
SIEMPRE
injectJar No bool Si implementar la inserción de ganchos de acuerdo con las reglas para todos los archivos jar y aars dependientes de terceros a los que se hace referencia FALSO
buildLog No bool Si generar el registro de compilación del complemento en la carpeta .\app\build\plugin. Cuando haya un error en la compilación, abra verdadero
manipulador No cadena La clase de recepción del controlador enviada por el gancho de instrumentación es la clase de procesamiento de instrumentación. Por ejemplo, si pasa xxx.xxx.A, la clase A.java se generará automáticamente después de la compilación, y el método se generará automáticamente, similar a esto : com.miqt.hookplugin.HookHandler
handlerDir No cadena La clase de recepción del controlador reenviada por el gancho instrumentado se genera en esa ruta, el valor predeterminado .\src\main\javageneralmente no es necesario personalizar .\src\principal\java

Parámetros en hookTargets {}

estructura:

hook_method {
    
    
    hookTargets {
    
    
        name1 {
    
    
        	条件1 = value1
        	条件2 = value2
        	条件3 = value3
        }
        name2 {
    
    
        	条件1 = value1
        	条件2 = value2
        	条件3 = value3
        }
    }
}

Esta es la definición de las condiciones del filtro de punto de campana. La lógica es que las condiciones establecidas por los parámetros 1, 2 y 3 deben cumplirse antes de que se puedan insertar las estacas.

Nota: si está configurado: hook_All{ }este parámetro incondicional significa que todos los métodos serán stub.

parámetro ¿Es obligatorio? tipo significado valores predeterminados
nombre cadena La posición de nombre1 y nombre2 arriba significa el nombre del punto de gancho. Este nombre eventualmente será el nombre del método de recepción de gancho en este punto, que puede definirlo usted mismo. nulo
acceso No En t Restricciones: los modificadores de acceso a métodos, como privado, público, estático, final, se definen en Opcodes.ACC_PRIVATE|Opcodes.ACC_STATICeste formulario -1
interfaces No cadena La condición limitante: qué interfaz debe implementar la clase donde se encuentra el método, por ejemplo, la interfaz OnClickListener se escribe así: interfaces = "android/view/View\$OnClickListener"aquí no se usan puntos y / se usa para indicar que se trata de un identificador de código de bytes. Agregue la anotación @HookInfo al método o clase, y el complemento mostrará automáticamente el identificador de código de bytes correspondiente en la consola de compilación y el archivo de registro de registro de compilación. nulo
supernombre No cadena Restricción: La clase del método debe ser una subclase de superName nulo
nombre de la clase No cadena Restricción: el nombre de la clase donde se encuentra el método, aquí está el nombre completo, como com/xxx/A, admite restricciones regulares nulo
métodoNombre No cadena Restricción: nombre del método, soporte para restricciones regulares nulo
descriptor No cadena Restricción: descriptor de campo de método , si no sabe cómo escribirlo, use la etiqueta @HookInfo para ver el resultado. nulo
anotación No cadena Restricción: El método o clase debe contener esta anotación nulo
firma No cadena Restricción: El método o clase debe contener este genérico nulo
excepciones No cadena Restricción: el método debe ajustarse a la forma de lanzar una excepción nulo
ganchoTiempo No cadena Condiciones restringidas: cuando el método ingresa al stub o cuando sale
Enter: cuando el método ingresa
Return: cuando el método sale
Enter|Return: al ingresar y salir (predeterminado)
Entrar|Volver

anotación incorporada

@HookInfo: genera la información de restricción de bytecode correspondiente, que se puede copiar e imprimir para el mismo tipo de método Hook
@HookMethod: marca el método hook, no es necesario escribir hookTargets, puede entenderse como el @HookMethodInherited incorporado
: Mark el método de gancho, hay herencia de clase, no es necesario escribir objetivos de gancho, se puede entender como el
@IgnoreMethodHook incorporado : marca el método de ignorar, la prioridad más alta

读都读到这里了,如果觉得还不错就帮我点个star吧,你的肯定是我持续维护的动力!

如果有使用问题欢迎提交Issues ,或者加我微信一起交流,微信号在我的主页。

最后贴个Demo中的示例:

apply plugin: 'com.miqt.plugin.hookmethod'
hook_method {
    
    
    buildLog = true
    injectJar = true
    enable = true
    hookTargets {
    
    
        hook_onclick {
    
    
            //<-- 所有点击事件
            interfaces = "android/view/View\$OnClickListener"
            methodName = "onClick"
            descriptor = "(Landroid/view/View;)V"
            hookTiming = "Enter|Return"
        }
        hook_activity_lifeCycle {
    
    
            //<-- 所有activity生命周期方法
            access = 4
            superName = "android/app/Activity"
            //这里是个正则表达式
            methodName = "(onCreate)|(onResume)|(onPause)|(onStart)|(onDestroy)|(onStop)"
            hookTiming = "Enter|Return"
        }
        hook_thread_run{
    
    
            //<-- 线程run方法
            access = 1
            superName = "java/lang/Thread"
            methodName = "run"
            descriptor = "()V"
        }
        hook_Runnable_run{
    
    
            //<-- 线程run方法
            access = 1
            interfaces = "java/lang/Runnable"
            methodName = "run"
            descriptor = "()V"
        }
    }
}

demo打印结果:

I/MethodHookHandler: ┌com/asm/code/[email protected]():[main]
I/MethodHookHandler: └com/asm/code/[email protected]():[0]
I/MethodHookHandler: ┌com/asm/code/[email protected]():[main]
I/MethodHookHandler: └com/asm/code/[email protected]():[0]
I/MethodHookHandler: ┌com/asm/code/[email protected]():[main]
I/MethodHookHandler: └com/asm/code/[email protected]():[0]
I/MethodHookHandler: ┌com/asm/code/[email protected]():[main]
I/MethodHookHandler: └com/asm/code/[email protected]():[3]
I/MethodHookHandler: ┌com/asm/code/[email protected]():[Thread-5]
I/MethodHookHandler: └com/asm/code/[email protected]():[1]
I/MethodHookHandler: ┌com/asm/code/[email protected]():[main]
I/MethodHookHandler: └com/asm/code/[email protected]():[0]
I/MethodHookHandler: ┌com/asm/code/[email protected]():[main]
I/MethodHookHandler: └com/asm/code/[email protected]():[0]

致谢

这个插件是借鉴了很多大佬的代码,并结合自己的想法进行了一些调整,在此感谢他们付出的努力。

https://github.com/novoda/bintray-release
https://github.com/JeasonWong/CostTime
https://github.com/MegatronKing/StringFog

Supongo que te gusta

Origin blog.csdn.net/qq_27512671/article/details/119570908
Recomendado
Clasificación