Xposed源码剖析——概述
来源:互联网 发布:acm网络赛 编辑:程序博客网 时间:2024/05/09 20:19
转: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其实主要是由三个项目来组成的,如下图所示;
三个分别是:
XposedInstaller的构成
XposedInstaller项目使我们最常用的项目,当然,他也是构造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-serversocket zygote stream 666 onrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart mediaonrestart 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。如下图所示:
- Xposed源码剖析——概述
- Xposed源码剖析——概述
- Xposed源码剖析——概述
- Xposed源码剖析——概述
- Xposed源码剖析——概述
- Xposed源码剖析——Xposed初始化
- Xposed源码剖析——Xposed初始化
- Xposed源码剖析——Xposed初始化
- Xposed源码剖析——app_process作用详解
- Xposed源码剖析——hook具体实现
- Xposed源码剖析——app_process作用详解
- Xposed源码剖析——hook具体实现
- Xposed源码剖析——app_process作用详解
- Xposed源码剖析——hook具体实现
- STL源码剖析—整体简要概述
- Android Root插件模式:Xposed源码剖析
- GTest源码剖析(一)——概述
- STL源码剖析--概述
- C#调用C++DLL的小总结5---和C++的DLL的联合调试
- c#实现登陆之后,关闭登陆界面并且进入主程序
- 111111
- php中常见设计模式
- Modeling System Behavior with Use Case(1)
- Xposed源码剖析——概述
- LPC1788启动文件分析(转载)
- 配置多个虚拟主机
- Android之蓝牙 开发基本流程
- 特征选择常用算法综述
- 多做这一步,你就被HR留下了!
- UGI GUI API
- 项目管理十大知识领域和47个过程
- 浅谈CSS在前端优化中一些值得注意的关键点