Alibaba-Dexposed Bug框架原理及源码解析
目錄(?)[+]
Alibaba的AndFix熱修復(fù):?
Alibaba-AndFix Bug熱修復(fù)框架的使用?
Alibaba-AndFix Bug熱修復(fù)框架原理及源碼解析
上一篇中已經(jīng)介紹了Alibaba-Dexposed框架在線熱補(bǔ)丁修復(fù)的使用?,這篇主要是了解框架的原理和源碼解析。
原理:
在Dalvik虛擬機(jī)下,主要是通過改變一個(gè)方法對(duì)象方法在Dalvik虛擬機(jī)中的定義來實(shí)現(xiàn),具體做法就是將該方法的類型改變?yōu)镹ative并且將這個(gè)方法的實(shí)現(xiàn)鏈接到一個(gè)通用的Native Dispatch方法上。這個(gè) Dispatch方法通過JNI回調(diào)到Java端的一個(gè)統(tǒng)一處理方法,最后在統(tǒng)一處理方法中調(diào)用before, after函數(shù)來實(shí)現(xiàn)AOP。在Art虛擬機(jī)上目前也是通過改變一個(gè) ArtMethod的入口函數(shù)來實(shí)現(xiàn)。
在宿主項(xiàng)目的Application需要調(diào)用以下方法來判斷手機(jī)是否支持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>可以看到,第一判斷了機(jī)型是否支持,如果支持就加載lib文件。?
DeviceCheck.isDeviceSupport()源碼:
判斷機(jī)型,主要判斷的有是否是Dalvik虛擬機(jī)、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文件。
以上僅是判斷當(dāng)然機(jī)型是否支持Dexposed框架的運(yùn)行環(huán)境。
接下,就是對(duì)Dexposed的使用原理進(jìn)行源碼分析:
在上一篇提到,當(dāng)加載補(bǔ)丁文件時(shí),會(huì)掃描補(bǔ)丁文件中實(shí)現(xiàn)IPatch接口的所有的類。?
IPatch定義如下:
就是說,修復(fù)bug的處理只能在handlePatch方法中實(shí)現(xiàn)。
官網(wǎng)也只提供了2種實(shí)現(xiàn)方式:?
第一:
第二:
<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í)行做一些處理,第二種就是直接把方法進(jìn)行替換。
在這里,我們就重點(diǎn)看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的反射機(jī)制獲取到Method對(duì)象</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)建一個(gè)回調(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;">//返回一個(gè)Unhook實(shí)例對(duì)象</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虛擬機(jī)的Native方法實(shí)現(xiàn):
hookMethodNative Native層的代碼實(shí)現(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;">//新申請(qǐng)一塊內(nèi)存</span><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//備份method對(duì)象到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;">//把方法的實(shí)現(xiàn)指向native方法的實(shí)現(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對(duì)象方法屬性設(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方法的實(shí)現(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>當(dāng)虛擬機(jī)調(diào)用到這個(gè)存在bug的方法時(shí)就會(huì)調(diào)用這個(gè)Native方法:?
dexposedCallHandler方法源碼:
這個(gè)方法主要就是調(diào)用Java的方法,實(shí)現(xiàn)調(diào)度。?
調(diào)用的Java的方法是:
這個(gè)方法里面了實(shí)現(xiàn)了調(diào)度機(jī)制,調(diào)用回調(diào)接口的方法和備份的Java方法。?
本質(zhì)上仍然是尋找被掛鉤函數(shù)的 Method 結(jié)構(gòu)體,將Method屬性改為native ,然后對(duì)其成員 nativeFunc,?
registersize 等進(jìn)行賦值,其中 insns 成員保存了掛鉤的詳細(xì)信息。所有被掛鉤的函數(shù),其nativeFunc都賦值為 dexposedCallHandler 函數(shù),該函數(shù)最終執(zhí)行 XposedBridge.class 里的 handleHookedMethod 。 handleHookedMethod 尋找dexposed模塊及dexposed框架調(diào)用 findAndHookMethod 注冊的 before,after?
函數(shù),如果有,就執(zhí)行,再通過invokeOriginalMethodNative 執(zhí)行掛鉤前函數(shù)。
MethodHookParam.thisObject:這個(gè)類的一個(gè)實(shí)例?
MethodHookParam.args:用于傳遞被注入函數(shù)的所有參數(shù)?
MethodHookParam.setResult:用于修改原函數(shù)調(diào)用的結(jié)果,如果在beforeHookedMethod回調(diào)函數(shù)中調(diào)用setResult,可以阻止對(duì)原函數(shù)的調(diào)用。但是如果有返回值的話仍然需要通過hook處理器進(jìn)行return操作。
Art虛擬機(jī)的Native方法實(shí)現(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());?
同樣也是把把實(shí)現(xiàn)指向native方法實(shí)現(xiàn)調(diào)度機(jī)制來達(dá)到目的。
原文地址: http://blog.csdn.net/qxs965266509/article/details/50117137
總結(jié)
以上是生活随笔為你收集整理的Alibaba-Dexposed Bug框架原理及源码解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JNI实战
- 下一篇: Alibaba-Dexposed框架在线