作者:FloatingGuy 转载请注明出处:https://floatingguy.github.io/


xposed 是专门针对Android 系统定制的一套框架。该框架的作用是给开发者提供一套接口,使用该接口并配合着一定的逆向技术就可以达到修改Android 系统服务(Framework层), 修改系统APP功能,或者修改普通APP功能的目的。

该框架hook的原理简单说来,就是替换Android zygote进程为Xposed 修改过的zygote (对应app_process进程)。之所以修改Zygote 最主要的目的就是替换将XposedBridge 框架插入到Zygote加载的库中这样zygote fork 出的所有子进程都共享XposedBridge库。
(这篇文章的重点在应用,不过多关注原理)。

Xposed 开发语言:Java

支持的系统版本:Android(<7.x)

目前主要的问题:

  • 不能hook 抽象函数
  • 不能hook 内部类
  • 只能hook java函数

创建一个Xposed Module

步骤:

  1. 创建一个no Activity 的app
    包名:floatg.xposeddemo
  2. 新建一个Java Class
    类名:MyClass
  3. 创建assets 目录,并创建xposed_init 文件
    路径:src/main/assets/xposed_init
  4. 修改 AndroidManifest.xml 文件
  5. 修改 build.gradle
  6. 删除 res/values 目录下除 strings.xml 的所有文件, 其他xml 文件做相应的修改。

    floatg.xposeddemo.MyClass

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    package floatg.xposeddemo;
    /**
    * Created by floatg on 2017/6/17.
    */
    import de.robv.android.xposed.IXposedHookLoadPackage;
    import de.robv.android.xposed.XC_MethodHook;
    import de.robv.android.xposed.callbacks.XC_LoadPackage;
    import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
    import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
    import static de.robv.android.xposed.XposedBridge.log;
    public class MyClass implements IXposedHookLoadPackage {
    public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
    if (!lpparam.packageName.equals("com.android.systemui"))
    return;
    findAndHookMethod("com.android.systemui.statusbar.policy.Clock", lpparam.classLoader, "updateClock", new XC_MethodHook() {
    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
    TextView tv = (TextView) param.thisObject;
    String text = tv.getText().toString();
    tv.setText(text + " :)");
    tv.setTextColor(Color.RED);
    }
    });
    }
    }

xposed_init

floatg.xposeddemo.MyClass

build.gradle

1
2
3
4
5
6
7
8
9
10
11
12
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
//compile 'com.android.support:appcompat-v7:24.2.1'
//testCompile 'junit:junit:4.12'
//关键是 这个jar不能编译到app中,因为Xposed 系统已经提供了,必须是provided, 而不是compile
provided files('provided/XposedBridgeApi-82.jar')
//如果需要引入文档,方便查看的话
provided 'de.robv.android.xposed:api:82:sources'
}

注释掉下面2条
compile ‘com.android.support:appcompat-v7:24.2.1’
testCompile ‘junit:junit:4.12’

增加
provided files(‘provided/XposedBridgeApi-82.jar’)

AndroidManifest.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<application
android:xx
android:yy >
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposeddescription"
android:value="xposed module to bypass authentication" />
<meta-data
android:name="xposedminversion"
android:value="53" />
</application>

注意:一定要在 applitcation 标签内部添加,不然模块在install中显示不出来。

其他