Android 如何优雅的hook私有方法

最近在使用java写反射进行hook系统的方法,但是每次都会写一长串代码,各种try catch,着实让人的着急,偶然间想起来从一个开源库里看到的一个类,当时没看懂,就保存了下来,现在回头看看居然很有意思

Hack.java

就是这个类

有几大特性

  • 链式调用
  • 简洁,清晰

下面我们来看这个类的使用方法

首先放一个类,咱们就来hack这个类

package com.utils.dddemo.hack;import android.util.Log;import com.utils.library.log.LogA;public class HackDemo {    private int mIntField;    private String mStr;    private static String staticField = "dds";    // 构造方法    private HackDemo() {        Log.d("dds", "constructor");    }    private HackDemo(int x) {        mIntField = x;        Log.d("dds", "constructor " + x);    }    private HackDemo(int x, String str) {        mIntField = x;        mStr = str;        Log.d("dds", "constructor " + x);    }         // 成员方法    private int foo() {        Log.d("dds", "method :foo");        // 返回私有变量        return mIntField;    }    private int foo(int type, String str) {        Log.d("dds", "method :foo " + type + "," + str);        return 7;    }        // 静态成员方法    private static void bar() {        Log.d("dds", "static method :bar");    }    private static int bar(int type) {        Log.d("dds", "static method :bar " + type);        return type;    }    private static void bar(int type, String name, Bean bean) {        LogA.d("dds", "static method :bar type:%d,%s,%s", type, name, bean.toString());    }        // 打印静态成员变量    public void printStaticField() {        Log.d("dds_test", "printStaticField:" + staticField);    }}

私有构造方法

无参数构造方法

        构造Hack.HackedMethod0 constructor = Hack                .into("com.utils.dddemo.hack.HackDemo")                .constructor()                .withoutParams();// check        assertNotNull(constructor);// 调用        Object statically = constructor                .invoke()                .statically();// check        assertNotNull(statically);

有参数构造方法

  // 构造Hack.HackedMethod1 constructor1 = Hack                .into("com.utils.dddemo.hack.HackDemo")                .constructor()                .withParam(int.class);        // check        assertNotNull(constructor1);        // 调用        Object statically1 = constructor1        .invoke(1222)            .statically();        // check        assertNotNull(statically1);

私有成员方法

无参数成员方法

        Hack.HackedMethod1 constructor1 = Hack                .into("com.utils.dddemo.hack.HackDemo")                .constructor()                .withParam(int.class);// check        assertNotNull(constructor1);// 构造方法        Object statically1 = constructor1.invoke(1222).statically();     // check        assertNotNull(statically1);        // 构造该方法        Hack.HackedMethod0 foo = Hack                .into("com.utils.dddemo.hack.HackDemo")                .method("foo")                .returning(int.class)                .withoutParams();// check        assertNotNull(foo);         // check 返回值是否等于传入的值        assertEquals(1222, (int) foo.invoke().on(statically1));

有参数,有返回值方法

        Hack.HackedMethod1 constructor1 = Hack                .into("com.utils.dddemo.hack.HackDemo")                .constructor()                .withParam(int.class);        assertNotNull(constructor1);        Object statically1 = constructor1.invoke(1222).statically();        assertNotNull(statically1);        Hack.HackedMethod2 foo = Hack                .into("com.utils.dddemo.hack.HackDemo")                .method("foo")                .returning(int.class)                .withParams(int.class, String.class);        assertNotNull(foo);        assertEquals(7, (int) foo.invoke(11, "dds_test").on(statically1));

私有静态方法

无参数静态方法

Hack.HackedMethod0 method = Hack                .into("com.utils.dddemo.hack.HackDemo")                .staticMethod("bar")                .withoutParams();        assertNotNull(method);// 方法调用        method.invoke().statically();

有参数静态方法

        Hack.HackedMethod3 method                = Hack.into("com.utils.dddemo.hack.HackDemo")                .staticMethod("bar")                .throwing(IOException.class)                .withParams(int.class, String.class, Bean.class);        assertNotNull(method);// 调用方法        method.invoke(-1, "xyz", new Bean()).statically();

下面重点来了,我们经常hook系统的方法都是hook的静态成员变量,那我们该如何修改静态成员变量的呢?

静态成员变量

Hack.HackedTargetField field = Hack.into("com.utils.dddemo.hack.HackDemo")    .staticField("staticField")    .ofType(String.class);//设置新值        field.set("dds111111111");//打印出新值        Hack.HackedMethod0 constructor = Hack                .into("com.utils.dddemo.hack.HackDemo")                .constructor()                .withoutParams();        assertNotNull(constructor);                Object statically = constructor.invoke().statically();        ((HackDemo) statically).printStaticField();

打印出结果

D/dds_test: printStaticField:dds111111111

代码收录

https://github.com/ddssingsong/AnyTool

更多相关文章

  1. Nginx系列教程(四)| 一文带你读懂Nginx的动静分离
  2. Eclipse ADT 中自动提示的方法参数都是arg0, arg1的解决方法
  3. android adapter的学习
  4. 如何避免Android内存泄漏之Context
  5. 【Android基础】AsyncTask基础
  6. Android(安卓)中保持屏幕唤醒的方法
  7. Android(安卓)- SharedPreferences
  8. UI开发中所用到特殊方法
  9. Android(安卓)的性能 V-保持APP的响应

随机推荐

  1. 什么是电子面单?他们对电商运营有什么影响
  2. 快递公司如何接入快递100?快递100的快递实
  3. 快递公司如何接入快递100?快递100的快递查
  4. 快递公司如何接入快递100?快递100电子面单
  5. 快递公司如何接入快递100?快递100手机查快
  6. 0517 mvc架构模式思想
  7. php 的变量与常量----0426
  8. js 中 for,foreach 遍历数组,与PHP 中 for,f
  9. 网站安全响应头缺失和php配置漏洞
  10. php之请求api数据与composer