日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Alibaba-Dexposed Bug框架原理及源码解析

發(fā)布時間:2025/3/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Alibaba-Dexposed Bug框架原理及源码解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


目錄(?)
[+]

Alibaba的AndFix熱修復(fù):?
Alibaba-AndFix Bug熱修復(fù)框架的使用?
Alibaba-AndFix Bug熱修復(fù)框架原理及源碼解析

上一篇中已經(jīng)介紹了Alibaba-Dexposed框架在線熱補丁修復(fù)的使用?,這篇主要是了解框架的原理和源碼解析。

原理:

在Dalvik虛擬機下,主要是通過改變一個方法對象方法在Dalvik虛擬機中的定義來實現(xiàn),具體做法就是將該方法的類型改變?yōu)镹ative并且將這個方法的實現(xiàn)鏈接到一個通用的Native Dispatch方法上。這個 Dispatch方法通過JNI回調(diào)到Java端的一個統(tǒng)一處理方法,最后在統(tǒng)一處理方法中調(diào)用before, after函數(shù)來實現(xiàn)AOP。在Art虛擬機上目前也是通過改變一個 ArtMethod的入口函數(shù)來實現(xiàn)。

在宿主項目的Application需要調(diào)用以下方法來判斷手機是否支持Dexposed框架:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">DexposedBridge.canDexposed(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">this</span>);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

canDexposed方法源碼:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">synchronized</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">canDexposed</span>(Context context) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> !DeviceCheck.isDeviceSupport(context)?<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>:loadDexposedLib(context);}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

可以看到,第一判斷了機型是否支持,如果支持就加載lib文件。?
DeviceCheck.isDeviceSupport()源碼:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">synchronized</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">isDeviceSupport</span>(Context context) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> var2;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span>(!isCheckedDeviceSupport) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span>(isDalvikMode() && isSupportSDKVersion() && !isX86CPU() && !isYunOS()) {isDeviceSupportable = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">true</span>;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> isDeviceSupportable;}isDeviceSupportable = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> isDeviceSupportable;}var2 = isDeviceSupportable;} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">finally</span> {Log.d(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"hotpatch"</span>, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"device support is "</span> + isDeviceSupportable + <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"checked"</span> + isCheckedDeviceSupport);isCheckedDeviceSupport = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">true</span>;}<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> var2;}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>

判斷機型,主要判斷的有是否是Dalvik虛擬機、sdk版本、是否是x86cpu架構(gòu)、是否是YunOS系統(tǒng)。

loadDexposedLib加載lib的源碼:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">loadDexposedLib</span>(Context context) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span>(VERSION.SDK_INT != <span class="hljs-number" style="color:#06666;box-sizing: border-box;">10</span> && VERSION.SDK_INT != <span class="hljs-number" style="color:#06666;box-sizing: border-box;">9</span>) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span>(VERSION.SDK_INT > <span class="hljs-number" style="color:#06666;box-sizing: border-box;">19</span>) {System.loadLibrary(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"dexposed_l"</span>);} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> {System.loadLibrary(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"dexposed"</span>);}} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> {System.loadLibrary(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"dexposed2.3"</span>);}<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">true</span>;} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (Throwable var2) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;}}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>

根據(jù)sdk的不同版本加載不同的so文件。

以上僅是判斷當然機型是否支持Dexposed框架的運行環(huán)境。

接下,就是對Dexposed的使用原理進行源碼分析:

在上一篇提到,當加載補丁文件時,會掃描補丁文件中實現(xiàn)IPatch接口的所有的類。?
IPatch定義如下:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">interface</span> IPatch {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> handlePatch(PatchParam var1) throws Throwable; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

就是說,修復(fù)bug的處理只能在handlePatch方法中實現(xiàn)。

官網(wǎng)也只提供了2種實現(xiàn)方式:?
第一:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Target class, method with parameter types, followed by the hook callback (XC_MethodHook).</span>DexposedBridge.findAndHookMethod(Activity.class, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"onCreate"</span>, Bundle.class, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> XC_MethodHook() {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// To be invoked before Activity.onCreate().</span><span class="hljs-annotation" style="color:#9b859d;box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">beforeHookedMethod</span>(MethodHookParam param) <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">throws</span> Throwable {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// "thisObject" keeps the reference to the instance of target class.</span>Activity instance = (Activity) param.thisObject;<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// The array args include all the parameters.</span>Bundle bundle = (Bundle) param.args[<span class="hljs-number" style="color:#06666;box-sizing: border-box;">0</span>];Intent intent = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> Intent();<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// XposedHelpers provide useful utility methods.</span>XposedHelpers.setObjectField(param.thisObject, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"mIntent"</span>, intent);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Calling setResult() will bypass the original method body use the result as method return value directly.</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (bundle.containsKey(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"return"</span>))param.setResult(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>);}<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// To be invoked after Activity.onCreate()</span><span class="hljs-annotation" style="color:#9b859d;box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">afterHookedMethod</span>(MethodHookParam param) <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">throws</span> Throwable {XposedHelpers.callMethod(param.thisObject, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"sampleMethod"</span>, <span class="hljs-number" style="color:#06666;box-sizing: border-box;">2</span>);}});</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul>

第二:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> DexposedBridge.findAndHookMethod(Activity.class, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"onCreate"</span>, Bundle.class, new XC_MethodReplacement() {@Override protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {// Re-writing the method logic outside the original method context is a bit tricky but still viable.<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">...</span>}});</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

調(diào)用的接口是相同的,只不過傳遞的回調(diào)接口不同。?
第一種是在方法前后執(zhí)行做一些處理,第二種就是直接把方法進行替換。

在這里,我們就重點看findAndHookMethod方法,跟著此方法追蹤源碼:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> Unhook <span class="hljs-title" style="box-sizing: border-box;">findAndHookMethod</span>(Class<?> clazz, String methodName, Object... parameterTypesAndCallback) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span>(parameterTypesAndCallback.length != <span class="hljs-number" style="color:#06666;box-sizing: border-box;">0</span> && parameterTypesAndCallback[parameterTypesAndCallback.length - <span class="hljs-number" style="color:#06666;box-sizing: border-box;">1</span>] <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">instanceof</span> XC_MethodHook) {XC_MethodHook callback = (XC_MethodHook)parameterTypesAndCallback[parameterTypesAndCallback.length - <span class="hljs-number" style="color:#06666;box-sizing: border-box;">1</span>];Method m = XposedHelpers.findMethodExact(clazz, methodName, parameterTypesAndCallback);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//根據(jù)Java的反射機制獲取到Method對象</span>Unhook unhook = hookMethod(m, callback);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//見下方代碼分析</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span>(!(callback <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">instanceof</span> XC_MethodKeepHook) && !(callback <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">instanceof</span> XC_MethodKeepReplacement)) {ArrayList var6 = allUnhookCallbacks;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">synchronized</span>(allUnhookCallbacks) {allUnhookCallbacks.add(unhook);}}<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> unhook;} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> IllegalArgumentException(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"no callback defined"</span>);}}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>

hookMethod方法源碼:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> Unhook <span class="hljs-title" style="box-sizing: border-box;">hookMethod</span>(Member hookMethod, XC_MethodHook callback) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span>(!(hookMethod <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">instanceof</span> Method) && !(hookMethod <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">instanceof</span> Constructor)) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> IllegalArgumentException(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"only methods and constructors can be hooked"</span>);} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">boolean</span> newMethod = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;Map declaringClass = hookedMethodCallbacks;DexposedBridge.CopyOnWriteSortedSet callbacks;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">synchronized</span>(hookedMethodCallbacks) {callbacks = (DexposedBridge.CopyOnWriteSortedSet)hookedMethodCallbacks.get(hookMethod);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//如果沒有修復(fù)此方法,就創(chuàng)建一個回調(diào)接口的集合</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span>(callbacks == <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>) {callbacks = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> DexposedBridge.CopyOnWriteSortedSet();hookedMethodCallbacks.put(hookMethod, callbacks);newMethod = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">true</span>;}}callbacks.add(callback);<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span>(newMethod) {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//如果是新方法,獲取方法的參數(shù)列表和返回值</span>Class declaringClass1 = hookMethod.getDeclaringClass();<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> slot = runtime == <span class="hljs-number" style="color:#06666;box-sizing: border-box;">1</span>?XposedHelpers.getIntField(hookMethod, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"slot"</span>):<span class="hljs-number" style="color:#06666;box-sizing: border-box;">0</span>;Class[] parameterTypes;Class returnType;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span>(hookMethod <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">instanceof</span> Method) {parameterTypes = ((Method)hookMethod).getParameterTypes();returnType = ((Method)hookMethod).getReturnType();} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> {parameterTypes = ((Constructor)hookMethod).getParameterTypes();returnType = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>;}DexposedBridge.AdditionalHookInfo additionalInfo = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> DexposedBridge.AdditionalHookInfo(callbacks, parameterTypes, returnType, (DexposedBridge.AdditionalHookInfo)<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//調(diào)用Native方法,接口在下方</span>hookMethodNative(hookMethod, declaringClass1, slot, additionalInfo);}callback.getClass();<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> Unhook(callback, hookMethod);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//返回一個Unhook實例對象</span>}}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li></ul>

hookMethodNative Native方法生命:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">synchronized</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">native</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">hookMethodNative</span>(Member var0, Class<?> var1, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> var2, Object var3);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

Dalvik虛擬機的Native方法實現(xiàn):

hookMethodNative Native層的代碼實現(xiàn):

<code class="hljs oxygene has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> void com_taobao_android_dexposed_DexposedBridge_hookMethodNative(JNIEnv* env, jclass clazz, jobject reflectedMethodIndirect,jobject declaredClassIndirect, jint slot, jobject additionalInfoIndirect) <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">{s// Usage errors?if (declaredClassIndirect == NULL || reflectedMethodIndirect == NULL) {dvmThrowIllegalArgumentException("method and declaredClass must not be null");return;}</span><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Find the internal representation of the method</span>ClassObject* declaredClass = (ClassObject*) dvmDecodeIndirectRef(dvmThreadSelf(), declaredClassIndirect);<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">Method</span>* <span class="hljs-title" style="box-sizing: border-box;">method</span> = <span class="hljs-title" style="box-sizing: border-box;">dvmSlotToMethod</span><span class="hljs-params" style="color:#66066;box-sizing: border-box;">(declaredClass, slot)</span>;</span><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//把Java的Method映射為Native Method</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">method</span> == <span class="hljs-title" style="box-sizing: border-box;">NULL</span>) <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">{dvmThrowNoSuchMethodError("could not get internal representation for method");return;}</span><span class="hljs-title" style="box-sizing: border-box;">if</span> <span class="hljs-params" style="color:#66066;box-sizing: border-box;">(dexposedIsHooked(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">method</span>)</span>) <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">{//判斷此方法是否已經(jīng)被hook(鉤)// already hookedreturn;}</span>// <span class="hljs-title" style="box-sizing: border-box;">Save</span> <span class="hljs-title" style="box-sizing: border-box;">a</span> <span class="hljs-title" style="box-sizing: border-box;">copy</span> <span class="hljs-title" style="box-sizing: border-box;">of</span> <span class="hljs-title" style="box-sizing: border-box;">the</span> <span class="hljs-title" style="box-sizing: border-box;">original</span> <span class="hljs-title" style="box-sizing: border-box;">method</span> <span class="hljs-title" style="box-sizing: border-box;">and</span> <span class="hljs-title" style="box-sizing: border-box;">other</span> <span class="hljs-title" style="box-sizing: border-box;">hook</span> <span class="hljs-title" style="box-sizing: border-box;">info</span><span class="hljs-title" style="box-sizing: border-box;">DexposedHookInfo</span>* <span class="hljs-title" style="box-sizing: border-box;">hookInfo</span> = <span class="hljs-params" style="color:#66066;box-sizing: border-box;">(DexposedHookInfo*)</span> <span class="hljs-title" style="box-sizing: border-box;">calloc</span><span class="hljs-params" style="color:#66066;box-sizing: border-box;">(1, sizeof(DexposedHookInfo)</span>);</span><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//新申請一塊內(nèi)存</span><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//備份method對象到hookInfo中</span>memcpy(hookInfo, <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">method</span>, <span class="hljs-title" style="box-sizing: border-box;">sizeof</span><span class="hljs-params" style="color:#66066;box-sizing: border-box;">(hookInfo->originalMethodStruct)</span>);</span>hookInfo->reflectedMethod = dvmDecodeIndirectRef(dvmThreadSelf(), env->NewGlobalRef(reflectedMethodIndirect));<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//把方法的實現(xiàn)指向native方法的實現(xiàn),指針替換</span>hookInfo->additionalInfo = dvmDecodeIndirectRef(dvmThreadSelf(), env->NewGlobalRef(additionalInfoIndirect));<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Replace method with our own code</span>SET_METHOD_FLAG(<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">method</span>, <span class="hljs-title" style="box-sizing: border-box;">ACC_NATIVE</span>);</span><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//把method對象方法屬性設(shè)置成native方法</span><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">method</span>-><span class="hljs-title" style="box-sizing: border-box;">insns</span> = <span class="hljs-params" style="color:#66066;box-sizing: border-box;">(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> u2*)</span> <span class="hljs-title" style="box-sizing: border-box;">hookInfo</span>;</span><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//把備份的method數(shù)據(jù)掛在這里傳遞數(shù)據(jù)</span><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">method</span>-><span class="hljs-title" style="box-sizing: border-box;">registersSize</span> = <span class="hljs-title" style="box-sizing: border-box;">method</span>-><span class="hljs-title" style="box-sizing: border-box;">insSize</span>;</span><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">method</span>-><span class="hljs-title" style="box-sizing: border-box;">outsSize</span> = 0;</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (PTR_gDvmJit != NULL) <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">{// reset JIT cacheMEMBER_VAL(PTR_gDvmJit, DvmJitGlobals, codeCacheFull) = true;}</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li></ul><code class="hljs oxygene has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">method</span>-><span class="hljs-title" style="box-sizing: border-box;">nativeFunc</span> = &<span class="hljs-title" style="box-sizing: border-box;">dexposedCallHandler</span>;</span><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//鏈接到Native方法的實現(xiàn)</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

當虛擬機調(diào)用到這個存在bug的方法時就會調(diào)用這個Native方法:?
dexposedCallHandler方法源碼:

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> dexposedCallHandler(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> u4* args, JValue* pResult, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> Method* method, ::Thread* <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">self</span>) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!dexposedIsHooked(method)) {dvmThrowNoSuchMethodError(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"could not find Dexposed original method - how did you even get here?"</span>);<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;}DexposedHookInfo* hookInfo = (DexposedHookInfo*) method->insns;Method* original = (Method*) hookInfo;Object* originalReflected = hookInfo->reflectedMethod;Object* additionalInfo = hookInfo->additionalInfo;<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// convert/box arguments</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">char</span>* desc = &method->shorty[<span class="hljs-number" style="color:#06666;box-sizing: border-box;">1</span>]; <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// [0] is the return type.</span>Object* thisObject = <span class="hljs-literal" style="color:#06666;box-sizing: border-box;">NULL</span>;size_t srcIndex = <span class="hljs-number" style="color:#06666;box-sizing: border-box;">0</span>;size_t dstIndex = <span class="hljs-number" style="color:#06666;box-sizing: border-box;">0</span>;<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// for non-static methods determine the "this" pointer</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!dvmIsStaticMethod(original)) {thisObject = (Object*) args[<span class="hljs-number" style="color:#06666;box-sizing: border-box;">0</span>];srcIndex++;}ArrayObject* argsArray = dvmAllocArrayByClass(objectArrayClass, strlen(method->shorty) - <span class="hljs-number" style="color:#06666;box-sizing: border-box;">1</span>, ALLOC_DEFAULT);<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (argsArray == <span class="hljs-literal" style="color:#06666;box-sizing: border-box;">NULL</span>) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;}<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">while</span> (*desc != <span class="hljs-string" style="color:#0880;box-sizing: border-box;">'\0'</span>) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">char</span> descChar = *(desc++);JValue value;Object* obj;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">switch</span> (descChar) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">case</span> <span class="hljs-string" style="color:#0880;box-sizing: border-box;">'Z'</span>:<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">case</span> <span class="hljs-string" style="color:#0880;box-sizing: border-box;">'C'</span>:<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">case</span> <span class="hljs-string" style="color:#0880;box-sizing: border-box;">'F'</span>:<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">case</span> <span class="hljs-string" style="color:#0880;box-sizing: border-box;">'B'</span>:<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">case</span> <span class="hljs-string" style="color:#0880;box-sizing: border-box;">'S'</span>:<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">case</span> <span class="hljs-string" style="color:#0880;box-sizing: border-box;">'I'</span>:value<span class="hljs-variable" style="color:#66066;box-sizing: border-box;">.i</span> = args[srcIndex++];obj = (Object*) dvmBoxPrimitive(value, dvmFindPrimitiveClass(descChar));dvmReleaseTrackedAlloc(obj, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">self</span>);<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">break</span>;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">case</span> <span class="hljs-string" style="color:#0880;box-sizing: border-box;">'D'</span>:<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">case</span> <span class="hljs-string" style="color:#0880;box-sizing: border-box;">'J'</span>:value<span class="hljs-variable" style="color:#66066;box-sizing: border-box;">.j</span> = dvmGetArgLong(args, srcIndex);srcIndex += <span class="hljs-number" style="color:#06666;box-sizing: border-box;">2</span>;obj = (Object*) dvmBoxPrimitive(value, dvmFindPrimitiveClass(descChar));dvmReleaseTrackedAlloc(obj, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">self</span>);<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">break</span>;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">case</span> <span class="hljs-string" style="color:#0880;box-sizing: border-box;">'['</span>:<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">case</span> <span class="hljs-string" style="color:#0880;box-sizing: border-box;">'L'</span>:obj = (Object*) args[srcIndex++];<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">break</span>;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">default</span>:ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Unknown method signature description character: %c\n"</span>, descChar);obj = <span class="hljs-literal" style="color:#06666;box-sizing: border-box;">NULL</span>;srcIndex++;}dexposedSetObjectArrayElement(argsArray, dstIndex++, obj);}<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// call the Java handler function</span>JValue result;<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//調(diào)用了Java層的方法</span>dvmCallMethod(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">self</span>, dexposedHandleHookedMethod, <span class="hljs-literal" style="color:#06666;box-sizing: border-box;">NULL</span>, &result,originalReflected, (<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span>) original, additionalInfo, thisObject, argsArray);dvmReleaseTrackedAlloc((Object *)argsArray, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">self</span>);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// exceptions are thrown to the caller</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (dvmCheckException(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">self</span>)) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;}<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// return result with proper type</span>ClassObject* returnType = dvmGetBoxedReturnType(method);<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (returnType->primitiveType == PRIM_VOID) {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// ignored</span>} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (result<span class="hljs-variable" style="color:#66066;box-sizing: border-box;">.l</span> == <span class="hljs-literal" style="color:#06666;box-sizing: border-box;">NULL</span>) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (dvmIsPrimitiveClass(returnType)) {dvmThrowNullPointerException(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"null result when primitive expected"</span>);}pResult->l = <span class="hljs-literal" style="color:#06666;box-sizing: border-box;">NULL</span>;} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!dvmUnboxPrimitive((Object *)result<span class="hljs-variable" style="color:#66066;box-sizing: border-box;">.l</span>, returnType, pResult)) {dvmThrowClassCastException(((Object *)result<span class="hljs-variable" style="color:#66066;box-sizing: border-box;">.l</span>)->clazz, returnType);}} }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li></ul>

這個方法主要就是調(diào)用Java的方法,實現(xiàn)調(diào)度。?
調(diào)用的Java的方法是:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> Object <span class="hljs-title" style="box-sizing: border-box;">handleHookedMethod</span>(Member method, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> originalMethodId, Object additionalInfoObj,Object thisObject, Object[] args) throws Throwable {AdditionalHookInfo additionalInfo = (AdditionalHookInfo) additionalInfoObj;Object[] callbacksSnapshot = additionalInfo.callbacks.getSnapshot();final <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> callbacksLength = callbacksSnapshot.length;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (callbacksLength == <span class="hljs-number" style="color:#06666;box-sizing: border-box;">0</span>) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> invokeOriginalMethodNative(method, originalMethodId, additionalInfo.parameterTypes,additionalInfo.returnType, thisObject, args);} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (InvocationTargetException e) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">throw</span> e.getCause();}}MethodHookParam param = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> MethodHookParam();param.method = method;param.thisObject = thisObject;param.args = args;<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// call "before method" callbacks</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> beforeIdx = <span class="hljs-number" style="color:#06666;box-sizing: border-box;">0</span>;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">do</span> {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {((XC_MethodHook) callbacksSnapshot[beforeIdx]).beforeHookedMethod(param);} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (Throwable t) {log(t);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// reset result (ignoring what the unexpectedly exiting callback did)</span>param.setResult(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>);param.returnEarly = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">continue</span>;}<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (param.returnEarly) {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// skip remaining "before" callbacks and corresponding "after" callbacks</span>beforeIdx++;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">break</span>;}} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">while</span> (++beforeIdx < callbacksLength);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// call original method if not requested otherwise</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!param.returnEarly) {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {param.setResult(invokeOriginalMethodNative(method, originalMethodId,additionalInfo.parameterTypes, additionalInfo.returnType, param.thisObject, param.args));} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (InvocationTargetException e) {param.setThrowable(e.getCause());}}<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// call "after method" callbacks</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> afterIdx = beforeIdx - <span class="hljs-number" style="color:#06666;box-sizing: border-box;">1</span>;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">do</span> {Object lastResult = param.getResult();Throwable lastThrowable = param.getThrowable();<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {((XC_MethodHook) callbacksSnapshot[afterIdx]).afterHookedMethod(param);} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (Throwable t) {DexposedBridge.log(t);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// reset to last result (ignoring what the unexpectedly exiting callback did)</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (lastThrowable == <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>)param.setResult(lastResult);<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span>param.setThrowable(lastThrowable);}} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">while</span> (--afterIdx >= <span class="hljs-number" style="color:#06666;box-sizing: border-box;">0</span>);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// return</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (param.hasThrowable())<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">throw</span> param.getThrowable();<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> param.getResult();}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li></ul>

這個方法里面了實現(xiàn)了調(diào)度機制,調(diào)用回調(diào)接口的方法和備份的Java方法。?
本質(zhì)上仍然是尋找被掛鉤函數(shù)的 Method 結(jié)構(gòu)體,將Method屬性改為native ,然后對其成員 nativeFunc,?
registersize 等進行賦值,其中 insns 成員保存了掛鉤的詳細信息。所有被掛鉤的函數(shù),其nativeFunc都賦值為 dexposedCallHandler 函數(shù),該函數(shù)最終執(zhí)行 XposedBridge.class 里的 handleHookedMethod 。 handleHookedMethod 尋找dexposed模塊及dexposed框架調(diào)用 findAndHookMethod 注冊的 before,after?
函數(shù),如果有,就執(zhí)行,再通過invokeOriginalMethodNative 執(zhí)行掛鉤前函數(shù)。

MethodHookParam.thisObject:這個類的一個實例?
MethodHookParam.args:用于傳遞被注入函數(shù)的所有參數(shù)?
MethodHookParam.setResult:用于修改原函數(shù)調(diào)用的結(jié)果,如果在beforeHookedMethod回調(diào)函數(shù)中調(diào)用setResult,可以阻止對原函數(shù)的調(diào)用。但是如果有返回值的話仍然需要通過hook處理器進行return操作。

Art虛擬機的Native方法實現(xiàn)

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">static <span class="hljs-literal" style="color:#06666;box-sizing: border-box;">void</span> com_taobao_android_dexposed_DexposedBridge_hookMethodNative(JNIEnv<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span> env, jclass, jobject java_method, jobject, jint,jobject additional_info) {ScopedObjectAccess soa(env);art<span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::Thread</span><span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span> <span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">self</span> <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> art<span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::Thread</span><span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::Current</span>();jobject javaArtMethod <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> env<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">-></span>GetObjectField(java_method,WellKnownClasses<span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::java_lang_reflect_AbstractMethod_artMethod</span>);ArtMethod<span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*</span> method <span class="hljs-subst" style="color:#000000;box-sizing: border-box;">=</span> soa<span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">.</span>Decode<span class="hljs-subst" style="color:#000000;box-sizing: border-box;"><</span>mirror<span class="hljs-tag" style="color:#06666;box-sizing: border-box;">::ArtMethod</span><span class="hljs-subst" style="color:#000000;box-sizing: border-box;">*></span>(javaArtMethod);<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">LOG</span>(INFO) <span class="hljs-subst" style="color:#000000;box-sizing: border-box;"><<</span> <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"dexposed: >>> hookMethodNative "</span> <span class="hljs-subst" style="color:#000000;box-sizing: border-box;"><<</span> method <span class="hljs-subst" style="color:#000000;box-sizing: border-box;"><<</span> <span class="hljs-string" style="color:#0880;box-sizing: border-box;">" "</span> <span class="hljs-subst" style="color:#000000;box-sizing: border-box;"><<</span> PrettyMethod(method);EnableXposedHook(env, method, additional_info);}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>

EnableXposedHook:

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> EnableXposedHook(JNIEnv* env, ArtMethod* art_method, jobject additional_info)SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {LOG(INFO) << <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"dexposed: >>> EnableXposedHook"</span> << art_method << <span class="hljs-string" style="color:#0880;box-sizing: border-box;">" "</span> << PrettyMethod(art_method);<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (dexposedIsHooked(art_method)) {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Already hooked</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;} <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// else if (UNLIKELY(art_method->IsXposedOriginalMethod())) {</span> <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// // This should never happen</span> <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// ThrowIllegalArgumentException(nullptr, StringPrintf("Cannot hook the method backup: %s", PrettyMethod(art_method).c_str()).c_str());</span> <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// return;</span> <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// }</span>ScopedObjectAccess soa(env);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Create a backup of the ArtMethod object</span>ArtMethod* backup_method = down_cast<ArtMethod*>(art_method->Clone(soa.Self()));<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Set private flag to avoid virtual table lookups during invocation</span>backup_method->SetAccessFlags(backup_method->GetAccessFlags() <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">/*| kAccXposedOriginalMethod*/</span>);<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Create a Method/Constructor object for the backup ArtMethod object</span>jobject reflect_method;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (art_method->IsConstructor()) {reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Constructor);} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> {reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Method);}env->SetObjectField(reflect_method, WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod,env->NewGlobalRef(soa.AddLocalReference<jobject>(backup_method)));<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Save extra information in a separate structure, stored instead of the native method</span>DexposedHookInfo* hookInfo = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">reinterpret_cast</span><DexposedHookInfo*>(<span class="hljs-built_in" style="color:#66066;box-sizing: border-box;">calloc</span>(<span class="hljs-number" style="color:#06666;box-sizing: border-box;">1</span>, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">sizeof</span>(DexposedHookInfo)));hookInfo->reflectedMethod = env->NewGlobalRef(reflect_method);hookInfo->additionalInfo = env->NewGlobalRef(additional_info);hookInfo->originalMethod = backup_method;jstring shorty = (jstring)env->GetObjectField(additional_info,additionalhookinfo_shorty_field);hookInfo->shorty = env->GetStringUTFChars(shorty, <span class="hljs-number" style="color:#06666;box-sizing: border-box;">0</span>);LOG(INFO) << <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"dexposed: >>> EnableXposedHook shorty:"</span> << hookInfo->shorty;<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#if PLATFORM_SDK_VERSION < 22</span>art_method->SetNativeMethod(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">reinterpret_cast</span><uint8_t *>(hookInfo)); <span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#else</span>art_method->SetEntryPointFromJni(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">reinterpret_cast</span><<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> *>(hookInfo)); <span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#endif</span>art_method->SetEntryPointFromQuickCompiledCode(GetQuickDexposedInvokeHandler()); <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// art_method->SetEntryPointFromInterpreter(art::artInterpreterToCompiledCodeBridge);</span><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Adjust access flags</span>art_method->SetAccessFlags((art_method->GetAccessFlags() & ~kAccNative) <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">/*| kAccXposedHookedMethod*/</span>);}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li></ul>

通過:?
art_method->SetAccessFlags((art_method->GetAccessFlags()&~kAccNative)/| kAccXposedHookedMethod/);?
art_method->SetEntryPointFromQuickCompiledCode(GetQuickDexposedInvokeHandler());?
同樣也是把把實現(xiàn)指向native方法實現(xiàn)調(diào)度機制來達到目的。


原文地址: http://blog.csdn.net/qxs965266509/article/details/50117137

總結(jié)

以上是生活随笔為你收集整理的Alibaba-Dexposed Bug框架原理及源码解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。