Xposed 简介

1. 简介

Xposed框架的原理是替换安卓系统/System/bin目录下的文件,从而实现对系统某些功能的替换,进而给予基于 Xposed 框架开发的App更多权限。

下图是作者rovo89 在github上Xposed工程目录:
Xposed 简介_第1张图片
从上图可以看出Xposed共有五个部分:

Xposed:Xposed的C++部分,主要是用来替换/system/bin/app_process,并为 XposedBridge提供JNI方法;

XposedBridge:Xposed的Java部分,以XposedBridge.jar文件存在,负责在Native 层与FrameWork层进行交互。/system/bin/app_process进程启动过程中会加载该jar包,其它的Modules的开发与运行都是基于这个jar;

XposedInstaller:Xposed的安装包,负责配置Xposed工作的环境并且提供对基于Xposed框架的Modules的管理。在安装XposedInstaller之后,app_process与XposedBridge.jar放置在了/data/data/de.robv.android.xposed.installer

XposedMods:用Xposed Framework实现的实现的demo;

XposedAppSettings: 使用Xposed开发的一些Modules,其中AppSettings是一个可以进行权限动态管理的应用;

2. 运行原理

Xposed通过替换/system/bin/app_process程序控制zygote进程,使得app_process在启动过程中会加载XposedBridge.jar这个jar包,从而完成对Zygote进程及其创建的Dalvik虚拟机的劫持;

当系统中安装了 Xposed Framework 之后,会对 app_process 进行扩展,也就是说,Xposed Framework 会拿自己实现的 app_process 覆盖掉 Android 原生提供的 app_process 文件,当系统启动的时候,就会加载由 Xposed Framework 替换过的进程文件,并且XposedFramework 还有一个 jar 包,系统启动的时候,也会加载这个包:XposedBridge.jar。

Xposed框架实现Hook的原理介绍: Zygote进程是 Android 的核心,每运行一个 app,Zygote 就会 fork 一个虚拟机实例来运行 app。Zygote 的启动配置在/init.rc 脚本中,由系统启动的时候开启此进程,对应的执行文件是/system/bin/app_process,这个文件完成类库加载及一些函数调用的工作。当系统中安装了 Xposed 框架 之后,会对 app_process 进行扩展,也就是说,Xposed 框架会拿自己实现的 app_process 覆盖掉 Android 原生提供的 app_process 文件,当系统启动的时候,就会加载由 Xposed Framework 替换过的进程文件,并且,Xposed框架 还定义了一个 jar 包,系统启动的时候,也会加载这个XposedBridge包。

3.Xposed运行的条件

  1. 从上述原理可以看出Xposed需要替换/system/bin/app_process,因此需要手机获得root权限;
  2. 手机需要安装XposedInstaller.apk;

    Xposed的使用流程
    Xposed使用起来还是相对简单(到目前为止个人麻烦的是对需要hook的混淆过的app业务逻辑的分析,混淆!!), 大致流程可以分为五步:
    建立一个空的Android工程;
    修改AndroidManifest.xml, 并且添加Xposed配置信息;
    删除Activity有关的信息,并且添加如下三项meta-data内容:

 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.appchina.xpoesd"> 

    <application 
        android:allowBackup="true" 
        android:icon="@mipmap/ic_launcher" 
        android:label="@string/app_name" 
        android:supportsRtl="true" 
        android:theme="@style/AppTheme"> 
        <meta-data 
            android:name="xposedmodule" 
            android:value="true"/> 
        <meta-data 
            android:name="xposeddescription" 
            android:value="微信抢红包"/> 
        <meta-data 
            android:name="xposedminversion" 
            android:value="54"/> 
    application> 

manifest> 

在工程目录下新建一个libs文件夹, 将下载好的XposedBridgeApi-54.jar包放入其中;
3. 在assets目录下新建一个xposed_init文件,
格式为:包名+类名,如:com.appchina.xposed.XposedWeChatMoney
hook函数的编写, 这也是最核心的部分,在这部分你可以劫持需要hook的app的参数以及做一些我们自己想要完成的事情(可不要做太过分和违法的事情哦);
(1). 将之前新建的工程的java类实现IXposedHookLoadPackage接口并重新它的两个方法;
(2). 在handleLoadPackage()方法中对包名进行过滤,如果不是我们想要hook的包则什么都不做;
(3). 这也是最核心的一步,在这一步我们将处理我们的核心业务,如果前面过滤得到的是我们需要hook的包,在这里我们就需要对其它所属的方法进行hook,也就是对原app具体业务逻辑的hook,使用Xposed提供的findAndHookMethod()直接进行Hook操作,具体分为hook前执行的方法beforeAndHookMethod()和hook后需要执行的方法afterAndHookMethod(),在hook的回调中可以使用XposedBridge.log()方法打出log日志.

public class XposedWeChatMoney implements IXposedHookLoadPackage { 
    @Override 
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { 
       if (!loadPackageParam.packageName.equals("com.appchina.xposed")) { 
            return; 
        } 
        XposedBridge.log("loadPackageParam = "+loadPackageParam.packageName); 
        XposedHelpers.findAndHookMethod("android.app.application", 
        loadPackageParam.classLoader, "onCreate", new XC_MethodHook() { 
            @Override 
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 
                super.beforeHookedMethod(param); 
                XposedBridge.log("beforeHookedMethod"); 
                XposedBridge.log("loadPackageParam 0 = "+param.args[0]); 
                XposedBridge.log("loadPackageParam 1 = "+param.args[1]); 
            } 
            @Override 
            protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
                super.afterHookedMethod(param); 
                XposedBridge.log("afterHookedMethod"); 
                XposedBridge.log("loadPackageParam 0 = "+param.args[0]); 
                XposedBridge.log("loadPackageParam 1 = "+param.args[1]); 
            } 
        }); 
    } 
} 

重写XC_MethodHook的两个方法beforeHookedMethod和afterHookedMethod,这两个方法会在原始的方法的之前和之后执行.您可以使用beforeHookedMethod 方法来打印/篡改方法调用的参数(通过param.args) ,甚至阻止调用原来的方法(发送自己的结果).afterHookedMethod 方法可以用来做基于原始方法的结果的事情.您还可以用它来操纵结果 .当然,你可以添加自己的代码,它将会准确地在原始方法的前或后执行.

你可能感兴趣的:(Android,基础详解)