Android Root插件模式:Xposed源码剖析

目录(?)[+]

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文件。

<code class="hljs cs 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-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
     * xposed install
     * @return 安装成功返回true,否则false
     */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> boolean <span class="hljs-title" style="box-sizing: border-box;">install</span>() {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取安装的方式,直接写入 or 使用 recovery进行安装</span>
        final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> installMode = getInstallMode();

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 检查获取Root权限</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!startShell())
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;

        List<String> messages = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LinkedList<String>();
        boolean showAlert = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
            messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.sdcard_location, XposedApp.getInstance().getExternalFilesDir(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>)));
            messages.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>);

            messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_copying, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Xposed-Disabler-Recovery.zip"</span>));

            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 把Xposed-Disabler-Recovery.zip文件 从asset copy到sdcard中</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (AssetUtil.writeAssetToSdcardFile(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Xposed-Disabler-Recovery.zip"</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">00644</span>) == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
                messages.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>);
                messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_extract_failed, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Xposed-Disabler-Recovery.zip"</span>));
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
            }

            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 将编译后的app_process二进制文件,从asset文件夹中,copy到/data/data/de.robv.android.xposed.installer/bin/app_process下</span>
            File appProcessFile = AssetUtil.writeAssetToFile(APP_PROCESS_NAME, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> File(XposedApp.BASE_DIR + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"bin/app_process"</span>), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">00700</span>);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (appProcessFile == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
                showAlert(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_extract_failed, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"app_process"</span>));
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
            }

            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (installMode == INSTALL_MODE_NORMAL) {
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 普通安装模式</span>
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 重新挂载/system为rw模式</span>
                messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_mounting_writable, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/system"</span>));
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mRootUtil.executeWithBusybox(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"mount -o remount,rw /system"</span>, messages) != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                    messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_mount_writable_failed, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/system"</span>));
                    messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_trying_to_continue));
                }

                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 查看原有的app_process文件是否已经备份,如果没有备份,现将原有的app_process文件备份一下</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> File(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/system/bin/app_process.orig"</span>).exists()) {
                    messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_backup_already_exists, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/system/bin/app_process.orig"</span>));
                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mRootUtil.executeWithBusybox(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"cp -a /system/bin/app_process /system/bin/app_process.orig"</span>, messages) != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                        messages.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>);
                        messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_backup_failed, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/system/bin/app_process"</span>));
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
                    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                        messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_backup_successful, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/system/bin/app_process.orig"</span>));
                    }

                    mRootUtil.executeWithBusybox(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"sync"</span>, messages);
                }

                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 将项目中的自定义app_process文件copy覆盖系统的app_process,修改权限</span>
                messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_copying, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"app_process"</span>));
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mRootUtil.executeWithBusybox(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"cp -a "</span> + appProcessFile.getAbsolutePath() + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">" /system/bin/app_process"</span>, messages) != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                    messages.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>);
                    messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_copy_failed, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"app_process"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/system/bin"</span>));
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
                }
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mRootUtil.executeWithBusybox(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"chmod 755 /system/bin/app_process"</span>, messages) != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                    messages.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>);
                    messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_set_perms_failed, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/system/bin/app_process"</span>));
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
                }
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mRootUtil.executeWithBusybox(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"chown root:shell /system/bin/app_process"</span>, messages) != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                    messages.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>);
                    messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_set_owner_failed, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/system/bin/app_process"</span>));
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
                }

            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (installMode == INSTALL_MODE_RECOVERY_AUTO) {
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 自动进入Recovery</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!prepareAutoFlash(messages, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Xposed-Installer-Recovery.zip"</span>))
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;

            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (installMode == INSTALL_MODE_RECOVERY_MANUAL) {
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 手动进入Recovery</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!prepareManualFlash(messages, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Xposed-Installer-Recovery.zip"</span>))
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
            }

            File blocker = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> File(XposedApp.BASE_DIR + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"conf/disabled"</span>);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (blocker.exists()) {
                messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_removing, blocker.getAbsolutePath()));
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mRootUtil.executeWithBusybox(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"rm "</span> + blocker.getAbsolutePath(), messages) != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                    messages.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>);
                    messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_remove_failed, blocker.getAbsolutePath()));
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
                }
            }

            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// copy XposedBridge.jar 到私有目录 XposedBridge.jar是Xposed提供的jar文件,负责在Native层与FrameWork层进行交互</span>
            messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_copying, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"XposedBridge.jar"</span>));
            File jarFile = AssetUtil.writeAssetToFile(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"XposedBridge.jar"</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> File(JAR_PATH_NEWVERSION), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">00644</span>);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (jarFile == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
                messages.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>);
                messages.add(getString(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.file_extract_failed, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"XposedBridge.jar"</span>));
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
            }

            mRootUtil.executeWithBusybox(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"sync"</span>, messages);

            showAlert = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
            messages.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>);

            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (installMode == INSTALL_MODE_NORMAL) {
                offerReboot(messages);
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                offerRebootToRecovery(messages, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Xposed-Installer-Recovery.zip"</span>, installMode);
            }
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;

        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span> {
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 删除busybox 工具库</span>
            AssetUtil.removeBusybox();

            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (showAlert)
                showAlert(TextUtils.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">join</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\n"</span>, messages).trim());
        }
    }</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><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</li><li style="box-sizing: border-box; padding: 0px 5px;">113</li><li style="box-sizing: border-box; padding: 0px 5px;">114</li><li style="box-sizing: border-box; padding: 0px 5px;">115</li><li style="box-sizing: border-box; padding: 0px 5px;">116</li><li style="box-sizing: border-box; padding: 0px 5px;">117</li><li style="box-sizing: border-box; padding: 0px 5px;">118</li><li style="box-sizing: border-box; padding: 0px 5px;">119</li><li style="box-sizing: border-box; padding: 0px 5px;">120</li><li style="box-sizing: border-box; padding: 0px 5px;">121</li><li style="box-sizing: border-box; padding: 0px 5px;">122</li><li style="box-sizing: border-box; padding: 0px 5px;">123</li><li style="box-sizing: border-box; padding: 0px 5px;">124</li><li style="box-sizing: border-box; padding: 0px 5px;">125</li><li style="box-sizing: border-box; padding: 0px 5px;">126</li></ul>

ok,我们看完了代码,发现所有的工作都是为了app_process文件的替换。那么,系统中这个app_process是做什么的?为什么我们需要替换?替换成什么样?替换后对于我们么来说有什么帮助呢?


Xposed原理

我们在android的源码中的init.rc文件可以看到

<code class="hljs livecodeserver 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;">service zygote /<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">system</span>/bin/app_process -Xzygote /<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">system</span>/bin –zygote –start-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">system</span>-server
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">socket</span> zygote stream <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">666</span> 
onrestart <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">write</span> /sys/android_power/request_state wake
onrestart <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">write</span> /sys/power/state <span class="hljs-command" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">on</span></span>
onrestart restart media
onrestart restart netd</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></ul>

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。如下图所示:

/* 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Virtual Cam是一款基于Xposed框架的应用程序。Xposed框架是一种Android平台的开源软件,它允许在不修改系统的情况下对应用程序和系统进行定制和修改。Android Virtual Cam利用Xposed框架的强大功能,使用户能够在Android设备上添加虚拟摄像头。 使用Android Virtual Cam,用户可以模拟多个虚拟摄像头,并将它们用于各种视频应用程序。通过虚拟摄像头,用户可以同时在多个视频应用程序中使用设备的摄像头。这对于需要同时进行多个视频通话或者使用多个视频应用程序的用户来说非常方便。 Android Virtual Cam不仅通过虚拟摄像头功能,还提供了其他实用的功能。例如,用户可以自定义虚拟摄像头的属性和特征,如分辨率、帧率和图像效果等。这样,用户可以根据需要调整虚拟摄像头的设置,以获得最佳的拍摄效果。 此外,Android Virtual Cam还支持将其他设备的摄像头映射到Android设备上。这样,用户可以在Android设备上使用其他设备的摄像头,而无需将它们物理连接到Android设备上。这对于需要使用其他设备的摄像头进行拍摄和录制的用户来说非常方便。 总的来说,Android Virtual Cam借助Xposed框架的强大功能,为用户提供了一种便捷的方式来管理和使用虚拟摄像头。它不仅可以模拟多个虚拟摄像头,还支持自定义设置和映射其他设备的摄像头。这使得用户可以更加方便地进行多种视频应用程序的操作和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值