• 瑞金千人雨伞拼图创世界吉尼斯纪录 2019-07-02
  • “熊孩子”与幼儿教育 2019-06-15
  • 港媒称中国手游在韩国吸金美日手游遭韩玩家冷落 2019-06-15
  • 酒与植物 轻酌一樽是花香 2019-05-13
  • 台军为帮农民每餐吃香蕉 台媒改善两岸关系是根本 2019-05-12
  • 原脉——大地肌体上的血脉文章中国国家地理网 2019-05-11
  • 用更加过硬的作风追求改革新突破 2019-05-11
  • 欧版T90暴露法德坦克硬伤 VT4我离最强只差两步 2019-05-10
  • 【专题】河北省无偿献血领导小组会议报道 2019-05-10
  • 科幻推理剧《端脑》北京首映 搜狐匠心“烧脑”之作获赞 2019-05-09
  • 【大家谈】激励实干担当,谱写奋斗“进行曲” 2019-05-08
  • 回复@老老保老张工:连马克思都要重构个人所有制也!你不会自以为比马克思还高明吧? 2019-05-08
  • 学习宣传贯彻习近平新时代中国特色社会主义思想系列研讨会br第三场研讨会发言摘编 2019-05-07
  • 2000年出生的孩子属龙,要风得风,要雨得雨 2019-05-07
  • 美国防部宣布暂停8月美韩联合军演 2019-05-06
  • 购买生肖时时彩:Android Hook技术小实践 [复制链接]

    2019-11-13 09:58
    爱码仕 阅读:471 评论:0 赞:0

    概述

    香港生肖时时彩 www.eptu.com.cn 在学习Android插件化的过程中有用到Hook相关技术,本篇文章对Hook相关技术做也给简单的介绍,并写两个小Demo,当你了解了Hook之后可能会对你以后的碰到问题时多了一个解题思路

    定义

    Hook单词的意思就是钩子,那我们在什么时候用到这个钩子呢,如上图所示,在一个事件或者动作执行的过程中,截获相关事件或者动作,加入自己的代码或者替换装自己的代理对象,这就叫Hook

    Hook的原理

    本文主要是采用java反射机制拿到要执行的对象或者方法就行修改或者替换

    关注点:在hook的时候我们首先需要找到要Hook的对象,什么样的对象比较好Hook呢,那就是单例和静态变量,单例和静态变量在进程中不容易发生变化,相对容易被定位到,二普通象则比价容易发生变化(随时有可能被销毁),。我们根据这个原则找到所谓的Hook点

    以上就是我对Hook的理解,且是还挺简单的,但实践是检验真理的唯一标准,下面我会写两个小Demo

    Demo1

    本例子Hook的是一个工具类

    /**
     * 打印机工具类,提供黑白打印和彩色打印
     */
    public class PrintUtil {
        private static IPrint colorPrint = new ColorPrint(); //彩色打印机
        private static IPrint blackWhitePrint = new BlackWhitePrint(); //黑白打印机
    
        public static void colorPrint(String content){
            colorPrint.print(content);
        }
    
        public static void blackWhitePrint(String content){
            blackWhitePrint.print(content);
        }
    
    }
    

    工具类如上

        private void operate4(){
    //        HookHelper.hookPrint();
            PrintUtil.blackWhitePrint("黑白内容");
            PrintUtil.colorPrint("彩色内容");
        }

    正常结果如上 ,下面我们对PrintUtil进行hook ,首先我们先找Hook点,在PrintUtil中有两个静态变量,这就是我们要找的Hook点 具体代码如下

    /**
         * 对printUtil进行hook处理
         */
        public static void hookPrint(){
            try {
                Class<?> printClass = Class.forName("com.example.shiyagang.myapplication.util.PrintUtil");
                Field colorPrintField= printClass.getDeclaredField("colorPrint");
                Field blackWhitePrintField = printClass.getDeclaredField("blackWhitePrint");
                colorPrintField.setAccessible(true);
                blackWhitePrintField.setAccessible(true);
                colorPrintField.set(null,new BlackWhitePrint());
                blackWhitePrintField.set(null,new ColorPrint());
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    

    我们通过反射对PrintUtil的两个静态变量进行替换

    替换完执行结果如下







    彩色打印机打出了黑白内容,我们成功了,嘿嘿

    Demo2

    这个例子我们在context.startActivity的调用链,找到相关的hook点进行替换。我们首先分下context.startActivity的流程,Context.startActivity其实走到了ContextImpl的startActivity

    如上图所示最终调用了ActivityThread类的mInstrumentation成员的execStartActivity方法;注意到,ActivityThread 实际上是主线程,而主线程一个进程只有一个,因此这里是一个良好的Hook点
    • 我们要拿到ActivityThread的mInstrumentation ,首先得拿到ActivityThread的实例
    • ActivityThread类里面有一个静态方法currentActivityThread可以帮助我们拿到ActivityThread的实例

    通过以上步骤我们就能进行相关hook了

     /**
         * 对activityThread进行Hook
         * 
         */
        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);
        }
    

    EvilInstrumentation的代理对象如下:

    /**
     * Instrumentation 的静态代理类
     */
    public class EvilInstrumentation extends Instrumentation {
        private static final String TAG = EvilInstrumentation.class.getSimpleName();
    
        // 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) {
    
            Log.e(TAG, "我们Hook了 Activity的启动流程");
            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) {
                throw new RuntimeException("出问题了,去适配吧");
            }
        }
    }
    

    下面我们看下Activity的代码 ,我们在attachBaseContext中进行Hook

    private void operate3(){
            Intent intent = new Intent(getApplicationContext(),SecondActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            getApplicationContext().startActivity(intent);
        }
    
        @Override
        protected void attachBaseContext(Context newBase) {
            super.attachBaseContext(newBase);
            try {
                // 在这里进行Hook
                HookHelper.attachContext();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    入上图所示我们已经成功了,我们在这只是打印了一个日志,当然你可以干任何事情

    总结

    到此已经对Hook做了简单的介绍

    • 我们需要先找到Hook点 ,静态变量和单例比较好Hook
    • 植入我们的代码,可以采用代理的方式进行植入
    • 进行偷梁换柱

    今年年初我花一个月的时间收录整理了一套知识体系,如果有想法深入的系统化的去学习的,可以点击传送门,我会把我收录整理的资料都送给大家,帮助大家更快的进阶。



    我来说两句
    您需要登录后才可以评论 登录 | 立即注册
    facelist
    所有评论(0)
    领先的中文移动开发者社区
    18620764416
    7*24全天服务
    意见反?。[email protected]

    扫一扫关注我们

    Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 香港生肖时时彩 )

  • 瑞金千人雨伞拼图创世界吉尼斯纪录 2019-07-02
  • “熊孩子”与幼儿教育 2019-06-15
  • 港媒称中国手游在韩国吸金美日手游遭韩玩家冷落 2019-06-15
  • 酒与植物 轻酌一樽是花香 2019-05-13
  • 台军为帮农民每餐吃香蕉 台媒改善两岸关系是根本 2019-05-12
  • 原脉——大地肌体上的血脉文章中国国家地理网 2019-05-11
  • 用更加过硬的作风追求改革新突破 2019-05-11
  • 欧版T90暴露法德坦克硬伤 VT4我离最强只差两步 2019-05-10
  • 【专题】河北省无偿献血领导小组会议报道 2019-05-10
  • 科幻推理剧《端脑》北京首映 搜狐匠心“烧脑”之作获赞 2019-05-09
  • 【大家谈】激励实干担当,谱写奋斗“进行曲” 2019-05-08
  • 回复@老老保老张工:连马克思都要重构个人所有制也!你不会自以为比马克思还高明吧? 2019-05-08
  • 学习宣传贯彻习近平新时代中国特色社会主义思想系列研讨会br第三场研讨会发言摘编 2019-05-07
  • 2000年出生的孩子属龙,要风得风,要雨得雨 2019-05-07
  • 美国防部宣布暂停8月美韩联合军演 2019-05-06
  • 亚洲足球指数 山东十一选五遗漏走势 混合过关选择联赛 福建36选7开奖今晚70 爱乐彩天津十一选五 3d试机号查询今晚 安卓版街机捕鱼 快乐10分20选8结果 9915黄金城棋牌下载 重庆彩票欢乐生肖表 彩票中心 2012曾道人特码诗 澳洲幸运10开奖直播现场 江西多乐彩11选5走势图 永利真人龙虎斗开户 綦江在家赚钱手工活