原文链接——>[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其实主要是由三个项目来组成的,如下图所示;
![](http://img.blog.csdn.net/20150817000528010)
三个分别是:
|项目 |说明|
| --- | --- |
|Xposed |Xposed框架的native部分(主要是改性app_process二进制文件)|
|XposedInstaller |Xposed框架的Android端本地管理,环境架构搭建,以及第三方module资源下载的工具。|
|XposedBridge |Xposed向开发者提供的API与相应的工具类库|
#### **XposedInstaller的构成**
Xposed项目使我们最常用的项目,当然,他也是构造Xposed的核心部分。(也许你会说,其实是xposed项目更重要,它主要是替换app_process,ok我们后面再说它)。
如下图所示,是我们在XPosedInstaller apk中见到的,安装xposed框架的界面。
![](http://img.blog.csdn.net/20150814114556942)
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。如下图所示:
![](http://img.blog.csdn.net/20150818193611276)
- 前言
- 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屏幕刷新机制