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方法