无需Root也能Hook?——Depoxsed框架演示
之前我們介紹過rovo89在Githu上的Xposed框架,我們也介紹了如何使用Xposed框架進行
登錄劫持,和廣告注入。
但是,之后很多朋友都在問我,這個Xposed框架使用起來很確實很好用。可是就是有一
個巨大的缺點,就是需要Root權限。很多設備都沒有Root權限,有沒有一個不需要Root
權限的Hook框架。
答案是,確定的。就是目前的Alibab的開源框架,Dexposed框架。
github地址 :?https://github.com/alibaba/dexposed
Dexposed
它的官方介紹如下:
它基于ROOT社區著名開源項目Xposed改造剝離了ROOT部分,演化為服務于所在應用自
身的AOP框架,并在Apache 2.0協議下開源。
Xposed是XDA社區用戶rovo89開發并管理的一個項目,它通過修改Android?
Dalvik運行時的Zygote進程,使用Xposed?
Bridge將第三方代碼注入到Android應用的方法調用中,實現非侵入式的在運行期動態
修改系統和應用行為的能力。
Dexposed的原理也是很簡單,如它介紹中所說的。它是Xposed框架剝離掉了Root部分的
功能。
不熟悉Xposed原理的,可以看這里
http://blog.csdn.net/yzzst/article/details/47659987
沒有Root權限,那么Xposed框架式無法替換app_process的,當然也就無法進行整個系統
級應用程序的注入了。當然,對自我程序本身還是沒有問題的。
目前Dexposed的主要應用場景有以下幾種:
- AOP編程
- 插樁 (如測試、性能監控等)
- 在線熱補丁
- SDK hooking以提供更好的開發體驗
AOP為Aspect Oriented?
Programming的縮寫,意為:面向切面編程,通過預編譯方式和運行期動態代理實現程
序功能的統一維護的一種技術。
看到這里,很多小伙伴估計都會產生疑問,我靠,不能進行登錄劫持了,不能注入廣告
了。我用你來干什么。/(ㄒoㄒ)/~
AOP編程,在線熱補丁
沒錯,Dexposed框架主要的功能,還是提供作為AOP框架使用。這么一來的話,我們之前
也介紹過Android的插件實現方式。這里我們所用Dexposed框架來實現的話,插件模型將
會更加簡單。
首先先介紹一下,Dexposed框架也提供了一個與Xposed框架類似的方法。
<code class="language-java hljs 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-javadoc" style="color:#8800;box-sizing: border-box;">/*** 該系統是否支持hook*/</span> <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)/*** 尋找并hook一個指定的方法* @param clazz 類的<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">class</span>* @<span class="hljs-title" style="color:#66066;box-sizing: border-box;">param</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">methodName</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">hook</span>的方法名稱* @<span class="hljs-title" style="color:#66066;box-sizing: border-box;">param</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">parameterTypesAndCallback</span> 參數和返回<span class="hljs-title" style="color:#66066;box-sizing: border-box;">callback</span>* @<span class="hljs-title" style="color:#66066;box-sizing: border-box;">return</span> */ <span class="hljs-title" style="color:#66066;box-sizing: border-box;">public</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">static</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">Unhook</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">findAndHookMethod</span>(<span class="hljs-title" style="color:#66066;box-sizing: border-box;">Class</span><?> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">clazz</span>, <span class="hljs-title" style="color:#66066;box-sizing: border-box;">String</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">methodName</span>, <span class="hljs-title" style="color:#66066;box-sizing: border-box;">Object</span>... <span class="hljs-title" style="color:#66066;box-sizing: border-box;">parameterTypesAndCallback</span>)</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></ul>在線熱補丁實例
如何進行在線的熱補丁呢?我們這里以alibaba的demo為例。
如在主線版本中,我們有一個showDialog方法。已經發布出去了。但是,突然發現有一
點bug或者突發性需求,我們不能夠理解的發版更新。
。?
2. 通過Dexposed框架,動態的Hook并替換主線版本中的showDialog函數方法。
具體的邏輯如下圖所示:
看到上面的效果說明圖之后,相信大家對Dexposed的在線熱補丁已經有一定的了解了。
這里我們也不用做過多的贅述。
當然,你可能想到很多使用熱補丁的應用方向,比如:
- Bug補丁修復
- 插件功能
- 等等
Dexposed框架原理很簡單,功能也算不上強大。但是,確實特別實用。我也是推薦各大
Android開發者,特別是創業公司使用。是墻裂推薦!!
下面是主工程中與補丁工程中的邏輯實現。這里,童鞋們可以對比著效果圖看一下。
如果大家對動態的使用DexClassLoader載入一個apk代碼還存在疑問。 可以clone一下
dexposed的源碼學習學習。
當然,這里還是推薦大家去我的博客看看,Android的插件原理。?
地址:http://blog.csdn.net/yzzst/article/details/45582315
主工程中,MainActivity showDialog方法的定義
<code class="language-java hljs 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-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">class</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">MainActivity</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">extends</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">Activity</span> {</span><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">//..........一些忽略掉的代碼</span><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">showDialog</span>() {AlertDialog.Builder builder = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> AlertDialog.Builder(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">this</span>);builder.setTitle(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Dexposed sample"</span>).setMessage(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Please clone patchsample project to generate apk, and copy it to \"/Android/data/com.taobao.dexposed/cache/patch.apk\""</span>).setPositiveButton(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"ok"</span>, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> DialogInterface.OnClickListener() {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClick</span>(DialogInterface dialog, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> whichButton) {}}).create().show();} }</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>在線熱補丁,Path.apk中的代碼
<code class="language-java hljs 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-javadoc" style="color:#8800;box-sizing: border-box;">/*** 插件的補丁類*/</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">class</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">DialogPatch</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">implements</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">IPatch</span> {</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;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">handlePatch</span>(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">final</span> PatchParam arg0) <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;">// 獲取主程序的ClassLoader</span>Class<?> cls = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</span>;<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">try</span> {<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 獲取主程序的MainActivity類</span>cls= arg0.context.getClassLoader().loadClass(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"com.taobao.dexposed.MainActivity"</span>);} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">catch</span> (ClassNotFoundException e) {e.printStackTrace();<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;}<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// hook并替換MainActivity中的showDialog方法</span>DexposedBridge.findAndHookMethod(cls, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"showDialog"</span>, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> XC_MethodReplacement() {<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> Object <span class="hljs-title" style="box-sizing: border-box;">replaceHookedMethod</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;">// 彈出一個插件中的Dialog</span>Activity mainActivity = (Activity) param.thisObject;AlertDialog.Builder builder = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> AlertDialog.Builder(mainActivity);builder.setTitle(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Dexposed sample"</span>).setMessage(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"The dialog is shown from patch apk!"</span>).setPositiveButton(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"ok"</span>, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">new</span> DialogInterface.OnClickListener() {<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClick</span>(DialogInterface dialog, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> whichButton) {}}).create().show();<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">null</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></ul>
原文地址: http://blog.csdn.net/yzzst/article/details/47954479
總結
以上是生活随笔為你收集整理的无需Root也能Hook?——Depoxsed框架演示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Xposed源码剖析——hook具体实现
- 下一篇: Trie树的常见应用大总结(面试+附代码