zoukankan      html  css  js  c++  java
  • xposed 原理分析

    1.添加hook方法

    首先是init进程打开 app_process,然后进入XposedInit.java main() - > initForZygote() 加入对ActivityThread.handleBindApplication() 的hook,找到Method对象

    XposedBridge.hookMethod(method,callback) 加入到一个  key=method val=callbacks 的map中 sHookedMethodCallbacks

    Native 方法 hookMethodNative(),当前在zygote中,zygote的app_process被xposed修改过,加载过这个方法。

    然后是loadModules() 加载所有模块app

     

    App_process

    先加载/system/framework/XposedBridge.jar 到 env CLASSPATH 中

    然后启动虚拟机,调用onVmCreatedCommon()加载native方法

    加载jar路径成功后到 de.robv.android.xposed.XposedBridge main() 中

    ArtMethod* artMethod = ArtMethod::FromReflectedMethod(soa, javaReflectedMethod); //(soa = Method = jobject)

    该方法根据 soa对象里的 artMethod int值经过一系列操作,asArtMethod()

    得到artMethod,然后执行hook

    artMethod->EnableXposedHook(soa, javaAdditionalInfo);  //EnableXposedHook 找不到定义

    ArtMethod定义在android源码中

    class MANAGED ArtMethod FINAL : public Object

    dvm的实现

    Method* method = dvmSlotToMethod(declaredClass, slot);  //return &clazz->virtualMethods[slot];

    保存原先的method副本到XposedHookInfo中。

    method->nativeFunc = &hookedMethodCallback

    method->insns = (const u2*) hookInfo;  //表示让dvm判为内部native方法 = DalvikNativeFunc  =  typedef void (*DalvikNativeFunc)(const u4* args, JValue* pResult);

    method->registersSize = method->insSize;

    最主要的一个操作是 nativeFunc 指向自己的方法

    完成HOOK

     

    Method结构

    struct Method {

    ClassObject*    clazz;

    u4              accessFlags;

    u2             methodIndex;  //在虚方法表中的下标

    508    u2              registersSize;  /* ins + locals 需要的寄存器数量  smali: .register */ 

    509    u2              outsSize;

    510    u2              insSize;

    513    const char*     name; //方法名

    523    DexProto        prototype;  //方法签名  smali: (I[I)V     = void xxxxx(int,int[])

    525    const char*     shorty;  /* short-form method descriptor string */

     

    535    const u2*       insns;          /* 1.指令,在内存中映射的.dex   2.JNI 会把这里用作方法指针。 3.内部本地方法这里是null*/

    536

    537    /* JNI: cached argument and return-type hints */

    538    int             jniArgInfo;

    547    DalvikBridgeFunc nativeFunc;  //Jni方法指针,可以是具体方法或者JNIbridge 。DalvikBridgeFunc / DalvikNativeFunc insns == null 代表Jni方法(DalvikBridgeFunc ),否则等于内部方法(DalvikNativeFunc),

    。。。

    577    const RegisterMap* registerMap; //方法中用到的寄存器

    。。。

    581};

     

    触发

    之后当这个方法被虚拟机调用时会调用 hookedMethodCallback()

    然后会调用 java层的 handleHookedMethod()方法。

    然后的主要流程是取出在hook时给的additionalInfo.callbacks 中的所有XC_MethodHook,调beforeHookedMethod(),invokeOriginalMethodNative()调原来的方法,然后是调用afterHookedMethod(),最后返回方法返回值。

    invokeOriginalMethodNative() 通过 dvmInvokeMethod()调用原生方法

    Art是 用 InvokeMethod() 调用原生方法

     

    android_art/runtime

    EableXposedHook   ArtMehtod 修改后的方法在这个修改后的 art 虚拟机工程里

    xposedInstaller 安装框架的时候,除了下载xposedBrage.jar 更换 app_Process 等,还从这个项目中下载 libart.so

     

     

    1.挂载入口

    xposedInitLib = dlsym(xposedLibHandle, "xposedInitLib") //根据 dvm 或 art 动态加载函数地址

    xposedInitLib()

    xposed->onVmCreated = &onVmCreatedCommon;

     

    2.根据生命周期进入

    虚拟机onVmCreated()

    Xposed::onVmCreated() -》 onVmCreatedCommon()

    onVmCreatedCommon()

    initXposedBridge()

    register_natives_XposedBridge()-》 注册hookMethodNative native方法

     

  • 相关阅读:
    JMeter
    MeasureSpec介绍及使用详解
    AS中一些不经常用到的快捷键
    gradle 构建工具,与Ant Maven关系
    关于runOnUiThread()与Handler两种更新UI的方法
    关于new Handler()与new Handler(Looper.getMainLooper())区别
    RTSP协议详解
    overridePendingTransition的简介
    Android获取手机分辨率DisplayMetircs类
    RTSP消息交互过程
  • 原文地址:https://www.cnblogs.com/cyy12/p/11767701.html
Copyright © 2011-2022 走看看