假設想飛得高。就該把地平線忘掉。javascript
前段時間寫了一篇有關於CydiaSubstrate的廣告注入的文章(地址:http://blog.csdn.net/yzzst/article/details/47318751),你們都直呼過癮。java
但是。真正瞭解這一方面的同窗應該這道。事實上另外一個比CydiaSubstrate更出名的工具:XPosed。android
不是因爲Xposed比CydiaSubstrate作的多好。而是Xposed是完全開源的。今天。咱們就向你們簡單的介紹一下Xposed。並書寫一個簡單的登錄劫持demo,讓你們高速的入門學習Xposed。git
Xposed框架是一款可以在不改動APK的狀況下影響程序執行(改動系統)的框架服務。經過替換/system/bin/app_process程序控制zygote進程。使得app_process在啓動過程當中會載入XposedBridge.jar這個jar包,從而完畢對Zygote進程及其建立的Dalvik虛擬機的劫持。github
基於Xposed框架可以製做出不少功能強大的模塊。且在功能不衝突的狀況下同一時候運做。api
此外。Xposed框架中的每一個庫還可以單獨下載使用,如Per APP Setting(爲每一個應用設置單獨的dpi或改動權限)、Cydia、XPrivacy(防止隱私泄露)、BootManager(開啓自啓動程序管理應用)對原生Launcher替換圖標等應用或功能均基於此框架。markdown
官網地址:http://repo.xposed.info/。網絡
源代碼地址:https://github.com/rovo89。app
Xposed框架是基於一個Android的本地服務應用XposedInstaller與一個提供API 的jar文件來完畢的。框架
因此。安裝使用Xposed框架咱們需要完畢如下幾個步驟:
安裝本地服務XposedInstaller
需要安裝XposedInstall.apk本地服務應用,咱們可以在其官網的framework欄目中找到,下載並安裝。地址爲:
http://repo.xposed.info/module/de.robv.android.xposed.installer
安裝好後進入XposedInstaller應用程序,會出現需要激活框架的界面,如圖8-5所看到的。這裏咱們點擊「安裝/更新」就能完畢框架的激活了。部分設備假設不支持直接寫入的話,可以選擇「安裝方式」,改動爲在Recovery模式下本身主動安裝就能夠。
因爲安裝時會存在需要Root權限,安裝後會啓動Xposed的app_process,因此安裝過程當中會存在設備屢次又一次啓動。
TIPS:因爲國內的部分ROM對Xposed不兼容,假設安裝Xposed不成功的話。強制使用Recovery寫入可能會形成設備重複從新啓動而沒法正常啓動。
下載使用API庫
其API庫XposedBridgeApi-.jar(version是XposedAPI的版本,如咱們這裏是XposedBridgeApi-54.jar)文件。咱們可以在Xposed的官方支持xda論壇找到,其地址爲:
http://forum.xda-developers.com/xposed/xposed-api-changelog-developer-news-t2714067
下載完畢後咱們需要將 Xposed Library 拷貝到 lib文件夾(注意是 lib 文件夾不是Android提供的 libs 文件夾),而後將這個 jar 包加入到 Build PATH 中
假設直接將jar包放置到了libs文件夾下,很是可能會產生錯 誤「IllegalAccessError: Class ref in
pre-verified class resolved to unexpected
implementation」。
預計Xposed做者在其框架內部也引用了BridgeApi,這樣操做避免重複引用。
以前跟你們也說過使用CydiaSubstrate進行廣告注入(地址:http://blog.csdn.net/yzzst/article/details/47318751),很是多網友問我,就僅僅能簡單的注入一個廣告。還能作什麼嗎?
登錄劫持!!!,你沒聽錯,今天咱們這裏就簡單的演示一下,怎樣對一個應用程序的登錄功能進行劫持,並把帳號password打印出來。
如咱們常見的登錄劫持,就是使用到了Hook技術來完畢的。那麼這個登錄劫持是怎樣完畢的呢?如下咱們就詳細來看看。一個咱們在開發中常見到的登錄樣例。首先咱們看看一個常見的登錄界面是什麼樣子的。
其相應的登錄流程代碼例如如下所看到的:
// 登錄button的onClick事件
mLoginButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 獲取用戶名
String username = mUserEditText.getText() + "";
// 獲取password
String password = mPasswordEditText.getText() + "";
if (isCorrectInfo(username, password)) {
Toast.makeText(MainActivity.this, "登錄成功!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this, "登錄失敗!", Toast.LENGTH_LONG).show();
}
}
});
咱們會發現,登錄界面上面的用戶信息都是存儲在EditText控件上。而後經過用戶手動點擊「登錄」button纔會將上面的信息發送至server端去驗證帳號與password是否正確。
這樣就很是easy了,黑客們僅僅需要找到開發人員在使用EditText控件的getText方法後進行網絡驗證的方法,Hook該方法,就能劫持到用戶的帳戶與password劫了。
TIPS:固然。咱們也可以仿照上以前CydiaSubstrate的廣告注入樣例(地址:http://blog.csdn.net/yzzst/article/details/47318751)。作一個如出一轍的Activity。在劫持原Activity優先彈出來。達到欺騙用戶獲取password的目的。
詳細流程例如如下:
明確了原理如下咱們就實際的操做一次。這裏咱們選擇使用Xposed框架來操做。使用Xposed進行Hook操做主要就是使用到了Xposed中的兩個比較重要的方法。handleLoadPackage獲取包載入時候的回調並拿到其相應的classLoader;findAndHookMethod對指定類的方法進行Hook。
它們的詳細定義例如如下所看到的:
/** * 包載入時候的回調 */
public void handleLoadPackage(final LoadPackageParam lpparam)
/** * Xposed提供的Hook方法 * * @param className 待Hook的Class * @param classLoader classLoader * @param methodName 待Hook的Method * @param parameterTypesAndCallback hook回調 * @return */
Unhook findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback)
固然,咱們使用Xposed進行Hook也分爲例如如下幾個步驟:
1. 在AndroidManifest.xml文件裏配置插件名稱與Api版本
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" >
<meta-data android:name="xposedmodule" android:value="true" />
<!-- 模塊描寫敘述 -->
<meta-data android:name="xposeddescription" android:value="一個登錄劫持的樣例" />
<!-- 最低版本 -->
<meta-data android:name="xposedminversion" android:value="30" />
</application>
2. 新建一個入口類並繼承並實現IXposedHookLoadPackage接口
例如如下操做,咱們新建了一個com.example.loginhook.Main的類,並實現IXposedHookLoadPackage接口中的handleLoadPackage方法,將非com.example.login包名的應用過濾掉。即咱們僅僅操做包名爲com.example.login的應用。例如如下所看到的:
public class Main implements IXposedHookLoadPackage {
/** * 包載入時候的回調 */
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
// 將包名不是 com.example.login 的應用剔除掉
if (!lpparam.packageName.equals("com.example.login"))
return;
XposedBridge.log("Loaded app: " + lpparam.packageName);
}
}
3. 聲明主入口路徑
需要在assets文件夾中新建一個xposed_init的文件。並在當中聲明主入口類。如這裏咱們的主入口類爲com.example.loginhook.Main
4. 使用findAndHookMethod方法Hook劫持登錄信息
這是最重要的一步,咱們以前所分析的都需要到這一步進行操做。
如咱們以前所分析的登錄程序,咱們需要劫持就是需要Hook其com.example.login.MainActivity中的isCorrectInfo方法。
咱們使用Xposed提供的findAndHookMethod直接進行MethodHook操做(與Cydia很是類似)。在其Hook回調中使用XposedBridge.log方法,將登錄的帳號password打印信息至Xposed的日誌中。詳細操做例如如下所看到的:
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
public class Main implements