Android Xposed 模块开发:劫持并修改运营商标识

833113621927141286

说到Xposed框架,想必喜欢鼓捣安卓手机的同学都不会陌生,这个来国外自XDA论坛的神器,作者是GitHub上rovo89大神,这个框架可以在不修改APK的情况下劫持程序运行或者修改系统,简直是Android上的Cydia。比如强行更改通知栏颜色,微信防止撤回等等,著名的省电app绿色守护在搭配Xposed框架后也能实现更加强大的功能,今天我这个博客将会带大家来开发一个修改运营商标识的Xposed模块。

  • 基本

Xposed官网:http://repo.xposed.info/要运行Xposed框架,手机必须已经获取Root权限

手机上root后下载,Xposed installer 就可以使用了

具体看这里 http://forum.xda-developers.com/showthread.php?t=3034811

  • Xposed运行原理

说道Xposed框架的运行原理,Android和Linux一样,任何进程都是由Zygote进程fork出来的,而Zygote进程是由Init进程启动的。Zygote进程在启动时会创建一个虚拟机实例,每当它fork一个新的应用程序进程时,都会创建一个新的虚拟机实例,并且新的程序会和Zygote共享一个Java运行库。Xposed通过替换app_process,(app_process是负责启动Zygote_init的)来使操作系统运行自己编写的Zygote,又因为所有程序都和Zygote共享Java库,所以Xposed可以在其他App调用Java库的时候Hook到其他程序中劫持程序。

  • 修改运营商标识模块

了解了大概以后就一起来编写一个修改运营商标识的模块吧~

先梳理一下流程,在Android中,运营商标签的控件是类CarrierText控制的。

    • 检测包名
    • 如果为 com.android.keyguard.CarrierText
    • 修改显示数值为自定义数值
  • 开发

梳理一下过程后就可以开始开发了,首先在Android Studio中新建项目,名字任意啦。

注意在开发时请关闭Android Studio的Instant Run功能,这个功能会导致Xposed项目运行不正常。

  • 导入API

http://forum.xda-developers.com/xposed/xposed-api-changelog-developer-news-t2714067 下载XposedBridgeApi-54.jar 到本地,复制到项目的 /lib/ 文件夹下

然后在app的build.gradle中的dependencies 中加入 provided files(‘libs/XposedBridgeApi-54.jar’)

这一步一定要做好,用compile是不行的,Xposed框架会报错的。

  • 修改manifest在标签中加入如下
    <meta-data
        android:name="xposedmodule"
        android:value="true"/>
    <meta-data
        android:name="xposeddescription"
        android:value="更改运营商名称 \n开发者:周毅刚"/>
    <meta-data
        android:name="xposedminversion"
        android:value="54"/><!-- 对应的XposedBridge版本号 -->
    

这样,Xposed框架在启动的时候就会知道这个项目为一个Xposed模块

  • 新建HookUtil类实现IXposedHookLoadPackage接口

新建一个类用来Hook进程,实现IXposedHookLoadPackage接口后会实现重写方法

@Override
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {

    }
});

handleLoadPackage方法实现后,系统每次载入一个包的时候就会运行这个方法,并且将包的对象 LoadPackageParam传进来,这时就可以做相应的调整了。

  • 查看Android源代码

既然可以对传入的包进行编辑,可是运营商标签的类是什么呢,他的包名又是什么?

这时候就只能去查阅Android系统的源代码来看了:

https://github.com/android就可以查看Android的源代码

最后发现,控制运营商标签的类叫做CarrierText,位于 /com/android/keyguard/CarrierText.java 中

点此访问

分析这个类,CarrierText类继承自TextView,其中updateCarrierText()方法用来更新运营商标签显示的内容,比如中国联通,中国移动,无SIM卡等等。我们要在这个类的这个方法运行的时候Hook他并且做相应的修改。

  • Hook updateCarrierText方法

在handleLoadPackage中调用findAndHookMethod方法

@Override
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {

	//过滤包名
    if (!loadPackageParam.packageName.equals("com.android.systemui"))
        return;

    XposedBridge.log("Changing Carrier");

    XposedHelpers.findAndHookMethod("com.android.keyguard.CarrierText", loadPackageParam.classLoader, "updateCarrierText", new XC_MethodHook() {


        @Override
        protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {

            TextView mLabel = (TextView) param.thisObject;
            mLabel.setText("Mike.Zhou");
            XposedBridge.log("Changing Carrier Done");
        }
    });

}

findAndHookMethod需要传入四个参数,包名,类,函数名,和一个XC_MethodHook实例

其中XC_MethodHook抽象类中有两个方法,分别用于Hook前和Hook后的操作.我只实现了afterHookedMethod。

@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
    super.beforeHookedMethod(param);
}

@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
    super.afterHookedMethod(param);
}
TextView mLabel = (TextView) param.thisObject;
mLabel.setText("Mike.Zhou");
XposedBridge.log("Changing Carrier Done");			

因为这个类继承自TextView,更新内容也用的是setText方法,所以我用传递进来的MethodHookParam得到了对象,并转换为TextView,然后调用setText方法来更新内容。

好了,现在HookUtil类就编写完成了,需要让Xposed框架识别并运行它还有一步。

  • 添加xposed_init文件

在assets资源目录新建一个xposed_init文本文件。写入以下内容:

miketech.it.carrieredit.HookUtil

就是你的包名加上那个类的类名,这样Xposed在初始化的时候就会自动加载HookUtil类并且运行刚才编写的handleLoadPackage方法了。

  • 完成

好了,现在这个项目就编写完成了,可以运行到手机上试试效果了。

完整项目可以到我的Github上获取

https://github.com/Yigang0622/Xposed-Carrier-Edit

  • 开发中的一些坑

在开发GUI过程中需要一些持久化的资源,比如是否开启了这个功能,还有用来保存用户输入的标签名称,这时候就肯定要用到SharedPreference了,可是Xposed每次自动就启动了HookUtil类,那时候你的Activity或者Application都没启动,得不到一个Context,SharedPreference就无法读取数据,之后发现Xposed API提供了一个XSharedPreference可以不用Context就能读取持久化数据。

  • 结束语

Xposed是个好东西,但是有可能也很危险,如果你下载了别人的module,那个人的module都可以去控制你手机的任何操作。

比如关机窃听

1、hook关机时的提示按钮

PhoneWindowManager.interceptKeyBeforeQueueing

2、hook电源服务,防止屏幕亮起
关闭系统音量,休眠机器,hook住PowerManagerService中的setScreenStateLocked方法,阻止点亮屏幕。这样用户就不会发现

3、处理电源按键
在“假关机”状态中处理电源按键,如果检测到长按,执行reboot命令重启手机,清除1024.hack中的假关机标志。

4、hook来电

hook 住CallNotifier中的handleMessage方法,如果检测到新的来电,直接调用PhoneUtils中的answerCall方法,就可以接通电话。

为什么我知道Android手机的关机时候执行的各种操作呢?因为,Android是一个开源操作系统,只有想不到,没有做不到。

 

我的博客MikeTech app现已登陆iPhone和Android

iPhone版下载
Android版下载

 

 

打赏

2 thoughts on “Android Xposed 模块开发:劫持并修改运营商标识

  1. Hi,博主你好。我想问一下你这边
    “`
    if (!loadPackageParam.packageName.equals(“com.android.systemui”))
    return;
    “`
    这里过滤包名的包名是怎么确定的?我想Hook TextView的setText方法,可是找不到包名。
    谢谢你的分享。

    1. textView应该在一个包含widget的包名下我猜,我就是看Android源代码确定包名的,但你你也可以硬碰,先不过滤,hook成功了后台输出下包名,然后你就知道包名了

Leave a Reply

Your email address will not be published. Required fields are marked *