装X指南之Xposed安装与配置

作者: 幕后眼光 | 来源:发表于2019-01-12 12:44 被阅读84次
    装X指南之Xposed安装与配置

    一、前言

    Xposed 能干嘛?我可以告诉你 Root + Xposed ,真的可以为所欲为。而 Android 开源,为“搞机”带了更多的乐趣的同时,当然也引入安全性问题,部分流氓软件在 Root 下,会盗取用户私密信息,例如:号码、照片、短信、密码······,所以需要慎重使用 Root,此外本文仅作为技术学习。

    二、Xposed 安装

    1.首先你的手机 必须 Root,关于各安卓机型的 Root 方法,请自行到对应机型论坛和贴吧找找 (注:Root 有风险,失败可能导致手机变砖,风险自行承担)

    2.下载「Xposed Installer」软件并安装,需要留意的是你的手机系统版本,不同版本下载对应的 apk,如果上不了该网址,可百度搜索——Xposed Installer 最新版本下载。

    • Xposed 官方网址:

    https://repo.xposed.info/module/de.robv.android.xposed.installer

    • Android 5.0 及以上版本的下载地址:

    http://forum.xda-developers.com/showthread.php?t=3034811

    官网说明

    3.激活 Xposed 框架(确保你手机刷入了第三方 Recovery),激活后可能会使系统变的有些卡顿,但为了技术(装B),我们牺牲点性能还是值得~

    • 点击【安装/更新】,选择【Install via recovery】
    • 等待【下载】,重启到【Recovery】模式,期间请勿操作
    • 耐心等待,刷完会自动重启,打开【Xposed Installer】,显示框架已激活。
    Install via recovery 框架已激活

    三、配置 Xposed 插件

    如何配置 Android Studio 项目为 Xposed 插件?

    1、配置项目 Gradle 的依赖

        compileOnly 'de.robv.android.xposed:api:82'
        compileOnly 'de.robv.android.xposed:api:82:sources'
    

    注:需要 compileOnly 来依赖,如果不想通过 Gradle 配置,也可以下载 XposedBridgeApi.jar ,放到项目 libs 目录。

    2、配置 AndroidManifest.xml

    <meta-data
        android:name="xposedmodule"
        android:value="true" />
    <meta-data
        android:name="xposeddescription"    
        android:value="XXX插件" />
    <meta-data
        android:name="xposedminversion"
        android:value="89" />
    
    • xposedmodule:是否配置为 Xposed 插件,设置为 true
    • xposeddescription:模块名称
    • xposedminversion:最低版本号

    3、新建 Hook 入口类

    该类需要实现接口 IXposedHookLoadPackage,并实现里面关键方法handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam),该方法会在每个软件被启动的时候回调,所以一般需要通过目标包名过滤。

    /**
     * @author zhicheng.chen
     */
    public class TargetHook implements IXposedHookLoadPackage {
        @Override
        public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
            //通过目标包名过滤
            if (lpparam.packageName.equals("com.xxx.xxx")) {
                XposedBridge.log("启动了xxx软件");
            }
        }
    }
    

    4、Xposed 免重启调试

    Xposed插件每次代码改动,都需要重启手机才能生效,有时候重启一次还不生效(我的手机有一次重启 3 次,才看到生效,还好是公司测试机,不心疼),所以代码最好写上相关 Log 信息,来看代码生效没。

    XposedBridge.log("启动了xxx软件");

    不过这里分享一个免重启调试的方法,方法来自网上,感谢 DX :
    /**
     * @author DX
     *         这种方案建议只在开发调试的时候使用,因为这将损耗一些性能(需要额外加载apk文件),调试没问题后,直接修改xposed_init文件为正确的类即可
     *         可以实现免重启,由于存在缓存,需要杀死宿主程序以后才能生效
     *         这种免重启的方式针对某些特殊情况的hook无效
     *         例如我们需要implements IXposedHookZygoteInit,并将自己的一个服务注册为系统服务,这种就必须重启了
     *         Created by DX on 2017/10/4.
     */
    
    public class HookLoader2 implements IXposedHookLoadPackage {
        //按照实际使用情况修改下面几项的值
        /**
         * 当前Xposed模块的包名,方便寻找apk文件
         */
        private final String modulePackage = "com.xxx.plugin";
        /**
         * 宿主程序的包名(允许多个),过滤无意义的包名,防止无意义的apk文件加载
         */
        private static List<String> hostAppPackages = new ArrayList<>();
    
        static {
            // TODO: Add the package name of application your want to hook!
            hostAppPackages.add("com.eg.android.AlipayGphone");
            hostAppPackages.add("com.xxx.plugin");
        }
    
        /**
         * 实际hook逻辑处理类
         */
        private final String handleHookClass = TargetHook.class.getName();
        /**
         * 实际hook逻辑处理类的入口方法
         */
        private final String handleHookMethod = "handleLoadPackage";
    
        @Override
        public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
            if (hostAppPackages.contains(loadPackageParam.packageName)) {
                //将loadPackageParam的classloader替换为宿主程序Application的classloader,解决宿主程序存在多个.dex文件时,有时候ClassNotFound的问题
                XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        Context context=(Context) param.args[0];
                        loadPackageParam.classLoader = context.getClassLoader();
                        invokeHandleHookMethod(context,modulePackage, handleHookClass, handleHookMethod, loadPackageParam);
                    }
                });
            }
        }
    
        /**
         * 安装app以后,系统会在/data/app/下备份了一份.apk文件,通过动态加载这个apk文件,调用相应的方法
         * 这样就可以实现,只需要第一次重启,以后修改hook代码就不用重启了
         * @param context context参数
         * @param modulePackageName 当前模块的packageName
         * @param handleHookClass   指定由哪一个类处理相关的hook逻辑
         * @param loadPackageParam  传入XC_LoadPackage.LoadPackageParam参数
         * @throws Throwable 抛出各种异常,包括具体hook逻辑的异常,寻找apk文件异常,反射加载Class异常等
         */
        private void invokeHandleHookMethod(Context context, String modulePackageName, String handleHookClass, String handleHookMethod, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
            File apkFile=findApkFile(context,modulePackageName);
            if (apkFile==null){
                throw new RuntimeException("寻找模块apk失败");
            }
            //加载指定的hook逻辑处理类,并调用它的handleHook方法
            PathClassLoader pathClassLoader = new PathClassLoader(apkFile.getAbsolutePath(), ClassLoader.getSystemClassLoader());
            Class<?> cls = Class.forName(handleHookClass, true, pathClassLoader);
            Object instance = cls.newInstance();
            Method method = cls.getDeclaredMethod(handleHookMethod, XC_LoadPackage.LoadPackageParam.class);
            method.invoke(instance, loadPackageParam);
        }
    
        /**
         * 根据包名构建目标Context,并调用getPackageCodePath()来定位apk
         * @param context context参数
         * @param modulePackageName 当前模块包名
         * @return return apk file
         */
        private File findApkFile(Context context, String modulePackageName){
            if (context==null){
                return null;
            }
            try {
                Context moudleContext = context.createPackageContext(modulePackageName, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
                String apkPath=moudleContext.getPackageCodePath();
                return new File(apkPath);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

    四、反编译工具

    1、TopActivity.apk

    安装这个工具可以直接查看当前 App 显示的最前 Activity,后面我们接触别人写的项目,这个工具可以很方便跟踪代码的入口,项目原理是通过 AccessibilityService 服务,监听所有的界面变化,读取当前界面 Activity,需要给软件开启【辅助权限】。

    项目地址:
    https://github.com/109021017/android-TopActivity

    当然也可以通过 Adb 命令,获取 Dumpsys 当前 Activity 的信息:

    adb shell dumpsys activity top
    
    Activity信息

    2、BDOpener.apk

    这是 Xposed 的插件模块,也就是说需要刷入 Xposed 框架后,才能使用该,通过安装这个软件,我们可以使手机安装的软件,变为可调试状态,这样就可以通过 Android Studio 的 Monitor 工具,查看所有的进程状态,并 dumpsys 方法调用信息。

    安装这个软件之后,需要在 Xposed 里面的【模块】里面,把该软件勾选后,【重启手机】才能生效。

    有人说找不到 Monitor 工具,该工具在新的 As 版本把入口取消了,我们可以在:C:\Users\Administrator\AppData\Local\Android\Sdk\tools\monitor.bat 目录下找到。

    开启调试状态之前,只能看到 AS 调试安装的进程:

    打开前
    开启调试状态之后,可以看到所有的进程信息:
    打开后

    3、jadx-gui 工具

    关于这个工具的介绍,这里我就不再赘述,贴一篇我觉得写得很好的博文,作者讲得很详细易懂。

    Android 反编译利器,jadx 的高级技巧:https://www.jianshu.com/p/e5b021df2170

    jadx

    注:如果出现 Jdk 错误,请安装 Jdk 64 位版本。
    更多技术分享,请加微信公众号——码农茅草屋:

    码农茅草屋

    相关文章

      网友评论

        本文标题:装X指南之Xposed安装与配置

        本文链接:https://www.haomeiwen.com/subject/uncbrqtx.html