美文网首页插件等 移动 前端 Python Android Java
Hook机制学习(一) - weishu系列博客学习笔记

Hook机制学习(一) - weishu系列博客学习笔记

作者: shuixingge | 来源:发表于2016-10-15 11:24 被阅读119次

    weishu系列博客

    一:Hook点的选择:

    1 Hook的对象,称之为Hook点;一般选择容易找到的对象为Hook点。因此一般选择静态变量和单例。
    2 在一个进程之内,静态变量和单例变量是相对不容易发生变化的,因此非常容易定位,而普通的对象则要么无法标志,要么容易改变。根据这个原则找到所谓的Hook点。

    二:Hook例子 - Hook Instrumentation.execStartActivity()

    ContextImpl.startActivity()

    @Override
    public void startActivity(Intent intent, Bundle options) {
        warnIfCallingFromSystemProcess();
        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
            throw new AndroidRuntimeException(
                    "Calling startActivity() from outside of an Activity "
                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                    + " Is this really what you want?");
        }
        mMainThread.getInstrumentation().execStartActivity(
            getOuterContext(), mMainThread.getApplicationThread(), null,
            (Activity)null, intent, -1, options);
    }
    
    

    EvilInstrumentation: 继承Instrumentation。

    public class EvilInstrumentation extends Instrumentation {
    
        private static final String TAG = "EvilInstrumentation";
    
        // ActivityThread中原始的对象, 保存起来
        Instrumentation mBase;
    
        public EvilInstrumentation(Instrumentation base) {
            mBase = base;
        }
    
        public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity target,
                Intent intent, int requestCode, Bundle options) {
    
            // Hook之前, XXX到此一游!
            Log.d(TAG, "\n执行了startActivity, 参数如下: \n" + "who = [" + who + "], " +
                    "\ncontextThread = [" + contextThread + "], \ntoken = [" + token + "], " +
                    "\ntarget = [" + target + "], \nintent = [" + intent +
                    "], \nrequestCode = [" + requestCode + "], \noptions = [" + options + "]");
    
            // 开始调用原始的方法, 调不调用随你,但是不调用的话, 所有的startActivity都失效了.
            // 由于这个方法是隐藏的,因此需要使用反射调用;首先找到这个方法
            try {
                Method execStartActivity = Instrumentation.class.getDeclaredMethod(
                        "execStartActivity",
                        Context.class, IBinder.class, IBinder.class, Activity.class, 
                        Intent.class, int.class, Bundle.class);
                execStartActivity.setAccessible(true);
                return (ActivityResult) execStartActivity.invoke(mBase, who, 
                        contextThread, token, target, intent, requestCode, options);
            } catch (Exception e) {
                // 某该死的rom修改了  需要手动适配
                throw new RuntimeException("do not support!!! pls adapt it");
            }
        }
    }
    
    

    设置 evilInstrumentation对象替代系统的Instrumentation

    public static void attachContext() throws Exception{
        // 先获取到当前的ActivityThread对象
        Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
        Method currentActivityThreadMethod = activityThreadClass.getDeclaredMethod("currentActivityThread");
        currentActivityThreadMethod.setAccessible(true);
        Object currentActivityThread = currentActivityThreadMethod.invoke(null);
    
        // 拿到原始的 mInstrumentation字段
        Field mInstrumentationField = activityThreadClass.getDeclaredField("mInstrumentation");
        mInstrumentationField.setAccessible(true);
        Instrumentation mInstrumentation = (Instrumentation) mInstrumentationField.get(currentActivityThread);
    
        // 创建代理对象
        Instrumentation evilInstrumentation = new EvilInstrumentation(mInstrumentation);
    
        // 偷梁换柱
        mInstrumentationField.set(currentActivityThread, evilInstrumentation);
    }
    

    相关文章

      网友评论

        本文标题:Hook机制学习(一) - weishu系列博客学习笔记

        本文链接:https://www.haomeiwen.com/subject/bjwnyttx.html