原文鏈接——>[Xposed源碼剖析——概述](http://blog.csdn.net/yzzst/article/details/47659987)
XPosed是與Cydia其名的工具,它能夠讓Android設備在沒有修改源碼的情況下修改系統中的API運行結果。我們通常稱之為:God Mode(上帝模式)。
之前享大家分享了Xposed的基礎,Xposed的作用和最簡單的用法。那么,它的原理和它的內部構造是如何構成的?下面,我們從Github上看看,rovo89大神是如何制作的。
rovo89的github地址:https://github.com/rovo89
在主頁上我們看到了,xposed其實主要是由三個項目來組成的,如下圖所示;

三個分別是:
|項目 |說明|
| --- | --- |
|Xposed |Xposed框架的native部分(主要是改性app_process二進制文件)|
|XposedInstaller |Xposed框架的Android端本地管理,環境架構搭建,以及第三方module資源下載的工具。|
|XposedBridge |Xposed向開發者提供的API與相應的工具類庫|
#### **XposedInstaller的構成**
Xposed項目使我們最常用的項目,當然,他也是構造Xposed的核心部分。(也許你會說,其實是xposed項目更重要,它主要是替換app_process,ok我們后面再說它)。
如下圖所示,是我們在XPosedInstaller apk中見到的,安裝xposed框架的界面。

InstallerFragment我們能夠在其中找到install方法,其中主要就是針對使用不同方式的將自定義的app_process文件替換掉系統的app_process文件。
~~~
/**
* xposed install
* @return 安裝成功返回true,否則false
*/
private boolean install() {
// 獲取安裝的方式,直接寫入 or 使用 recovery進行安裝
final int installMode = getInstallMode();
// 檢查獲取Root權限
if (!startShell())
return false;
List<String> messages = new LinkedList<String>();
boolean showAlert = true;
try {
messages.add(getString(R.string.sdcard_location, XposedApp.getInstance().getExternalFilesDir(null)));
messages.add("");
messages.add(getString(R.string.file_copying, "Xposed-Disabler-Recovery.zip"));
// 把Xposed-Disabler-Recovery.zip文件 從asset copy到sdcard中
if (AssetUtil.writeAssetToSdcardFile("Xposed-Disabler-Recovery.zip", 00644) == null) {
messages.add("");
messages.add(getString(R.string.file_extract_failed, "Xposed-Disabler-Recovery.zip"));
return false;
}
// 將編譯后的app_process二進制文件,從asset文件夾中,copy到/data/data/de.robv.android.xposed.installer/bin/app_process下
File appProcessFile = AssetUtil.writeAssetToFile(APP_PROCESS_NAME, new File(XposedApp.BASE_DIR + "bin/app_process"), 00700);
if (appProcessFile == null) {
showAlert(getString(R.string.file_extract_failed, "app_process"));
return false;
}
if (installMode == INSTALL_MODE_NORMAL) {
// 普通安裝模式
// 重新掛載/system為rw模式
messages.add(getString(R.string.file_mounting_writable, "/system"));
if (mRootUtil.executeWithBusybox("mount -o remount,rw /system", messages) != 0) {
messages.add(getString(R.string.file_mount_writable_failed, "/system"));
messages.add(getString(R.string.file_trying_to_continue));
}
// 查看原有的app_process文件是否已經備份,如果沒有備份,現將原有的app_process文件備份一下
if (new File("/system/bin/app_process.orig").exists()) {
messages.add(getString(R.string.file_backup_already_exists, "/system/bin/app_process.orig"));
} else {
if (mRootUtil.executeWithBusybox("cp -a /system/bin/app_process /system/bin/app_process.orig", messages) != 0) {
messages.add("");
messages.add(getString(R.string.file_backup_failed, "/system/bin/app_process"));
return false;
} else {
messages.add(getString(R.string.file_backup_successful, "/system/bin/app_process.orig"));
}
mRootUtil.executeWithBusybox("sync", messages);
}
// 將項目中的自定義app_process文件copy覆蓋系統的app_process,修改權限
messages.add(getString(R.string.file_copying, "app_process"));
if (mRootUtil.executeWithBusybox("cp -a " + appProcessFile.getAbsolutePath() + " /system/bin/app_process", messages) != 0) {
messages.add("");
messages.add(getString(R.string.file_copy_failed, "app_process", "/system/bin"));
return false;
}
if (mRootUtil.executeWithBusybox("chmod 755 /system/bin/app_process", messages) != 0) {
messages.add("");
messages.add(getString(R.string.file_set_perms_failed, "/system/bin/app_process"));
return false;
}
if (mRootUtil.executeWithBusybox("chown root:shell /system/bin/app_process", messages) != 0) {
messages.add("");
messages.add(getString(R.string.file_set_owner_failed, "/system/bin/app_process"));
return false;
}
} else if (installMode == INSTALL_MODE_RECOVERY_AUTO) {
// 自動進入Recovery
if (!prepareAutoFlash(messages, "Xposed-Installer-Recovery.zip"))
return false;
} else if (installMode == INSTALL_MODE_RECOVERY_MANUAL) {
// 手動進入Recovery
if (!prepareManualFlash(messages, "Xposed-Installer-Recovery.zip"))
return false;
}
File blocker = new File(XposedApp.BASE_DIR + "conf/disabled");
if (blocker.exists()) {
messages.add(getString(R.string.file_removing, blocker.getAbsolutePath()));
if (mRootUtil.executeWithBusybox("rm " + blocker.getAbsolutePath(), messages) != 0) {
messages.add("");
messages.add(getString(R.string.file_remove_failed, blocker.getAbsolutePath()));
return false;
}
}
// copy XposedBridge.jar 到私有目錄 XposedBridge.jar是Xposed提供的jar文件,負責在Native層與FrameWork層進行交互
messages.add(getString(R.string.file_copying, "XposedBridge.jar"));
File jarFile = AssetUtil.writeAssetToFile("XposedBridge.jar", new File(JAR_PATH_NEWVERSION), 00644);
if (jarFile == null) {
messages.add("");
messages.add(getString(R.string.file_extract_failed, "XposedBridge.jar"));
return false;
}
mRootUtil.executeWithBusybox("sync", messages);
showAlert = false;
messages.add("");
if (installMode == INSTALL_MODE_NORMAL) {
offerReboot(messages);
} else {
offerRebootToRecovery(messages, "Xposed-Installer-Recovery.zip", installMode);
}
return true;
} finally {
// 刪除busybox 工具庫
AssetUtil.removeBusybox();
if (showAlert)
showAlert(TextUtils.join("\n", messages).trim());
}
}
~~~
ok,我們看完了代碼,發現所有的工作都是為了app_process文件的替換。那么,系統中這個app_process是做什么的?為什么我們需要替換?替換成什么樣?替換后對于我們么來說有什么幫助呢?
#### **Xposed原理**
我們在android的源碼中的init.rc文件可以看到
~~~
service zygote /system/bin/app_process -Xzygote /system/bin –zygote –start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
~~~
app_process是andriod app的啟動程序(具體形式是zygote fork()調用一個 app_process作為Android app的載體)
**Xposed的實現方案**
針對Hook的不同進程來說又可以分為全局Hook與單個應用程序進程Hook,我們知道在Android系統中,應用程序進程都是由Zygote進程孵化出來的,而Zygote進程是由Init進程啟動的。
Zygote進程在啟動時會創建一個Dalvik虛擬機實例,每當它孵化一個新的應用程序進程時,都會將這個Dalvik虛擬機實例復制到新的應用程序進程里面去,從而使得每一個應用程序進程都有一個獨立的Dalvik虛擬機實例。所以如果選擇對Zygote進程Hook,則能夠達到針對系統上所有的應用程序進程Hook,即一個全局Hook。如下圖所示:

- 前言
- Android系統的體系結構
- Dalvik VM 和 JVM 的比較
- Android 打包應用程序并安裝的過程
- Android ADB工具
- Android應用開發
- Android UI相關知識總結
- Android 中window 、view、 Activity的關系
- Android應用界面
- Android中的drawable和bitmap
- AndroidUI組件adapterView及其子類和Adapter的關系
- Android四大組件
- Android 數據存儲
- SharedPreference
- Android應用的資源
- 數組資源
- 使用Drawable資源
- Material Design
- Android 進程和線程
- 進程
- 線程
- Android Application類的介紹
- 意圖(Intent)
- Intent 和 Intent 過濾器(Google官網介紹)
- Android中關于任務棧的總結
- 任務和返回棧(官網譯文)
- 總結
- Android應用安全現狀與解決方案
- Android 安全開發
- HTTPS
- 安卓 代碼混淆與打包
- 動態注入技術(hook技術)
- 一、什么是hook技術
- 二、常用的Hook 工具
- Xposed源碼剖析——概述
- Xposed源碼剖析——app_process作用詳解
- Xposed源碼剖析——Xposed初始化
- Xposed源碼剖析——hook具體實現
- 無需Root也能Hook?——Depoxsed框架演示
- 三、HookAndroid應用
- 四、Hook原生應用程序
- 五、Hook 檢測/修復
- Android 應用的逆向與加固保護技術
- OpenCV在Android中的開發
- Android高級開發進階
- 高級UI
- UI繪制流程及原理
- Android新布局ConstraintLayout約束布局
- 關鍵幀動畫
- 幀動畫共享元素變換
- Android異步消息處理機制完全解析,帶你從源碼的角度徹底理解
- Android中為什么主線程不會因為Looper.loop()里的死循環卡死?
- 為什么 Android 要采用 Binder 作為 IPC 機制?
- JVM 中一個線程的 Java 棧和寄存器中分別放的是什么?
- Android源碼的Binder權限是如何控制?
- 如何詳解 Activity 的生命周期?
- 為什么Android的Handler采用管道而不使用Binder?
- ThreadLocal,你真的懂了嗎?
- Android屏幕刷新機制