【Android】Xposed 框架解析

前言

Xposed这位老兄大家可能不认识,微信自动抢红包大家听过吧、微信记录器作弊大家听过吧、地理位置模拟大家听过吧,我很负责任的告诉大家,这些都是Xposed干的,对的,就是它,相信大家充着“谁抢我红包”的愤怒,也想结识下这个牛逼的人物吧,草民在此(淫荡一笑),我们开始吧。

Xposed 介绍

大名鼎鼎得Xposed,是Android平台上最负盛名的一个框架,百度百科介绍是:“Xposed框架是一款可以在不修改APK的情况下影响程序运行(修改系统)的框架服务,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作”,在这个框架下,我们可以加载很多插件App,这些插件App可以直接或间接劫持、篡改、伪造一些信息。有了Xposed后,理论上我们的插件APP可以hook到系统任意一个Java进程zygote、systemserver、systemui。

Xposed 原理

Zygote 进程简析及与Xposed关系

在Android系统中,应用程序进程以及系统服务进程SystemServer都是由Zygote进程孵化出来的,而Zygote进程是由Init进程启动的,Zygote进程在启动时会创建一个Dalvik虚拟机实例,每当它孵化一个新的应用程序进程时,都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面去,从而使得每一个应用程序进程都有一个独立的Dalvik虚拟机实例,这也是Xposed选择替换app_process的原因。

Zygote进程在启动的过程中,除了会创建一个Dalvik虚拟机实例之外,还会注册一些Android核心类的JNI方法到Dalvik虚拟机实例中去,以及将Java运行时库加载到进程中来。而一个应用程序进程被Zygote进程孵化出来的时候,不仅会获得Zygote进程中的Dalvik虚拟机实例拷贝,还会与Zygote一起共享Java运行时库,这也就是可以将XposedBridge这个jar包加载到每一个Android应用程序中的原因,想更多了解Zygote 进程可以去看下老罗的文章Android系统进程Zygote启动过程的源代码分析

Hook/Replace 简析

Xposed 框架中真正起作用的是对方法的hook。在Repackage技术中,如果要对APK做修改,则需要修改Smali代码中的指令,而另一种动态修改指令的技术需要在程序运行时基于匹配搜索来替换smali代码,但因为方法声明的多样性与复杂性,这种方法也比较复杂。

在Android系统启动的时候,zygote进程加载XposedBridge将所有需要替换的Method通过JNI方法hookMethodNative指向Native方法
xposedCallHandler,xposedCallHandler在转入handleHookedMethod这个Java方法执行用户规定的Hook Func。

Xposed框架的原理是通过替换/system/bin/app_process程序控制zygote进程,使得app_process在启动过程中会加载XposedBridge.jar这个jar包,从而完成对Zygote进程及其创建的Dalvik虚拟机的劫持。
与采取传统的Inhook方式详见Dynamic Dalvik Instrumentation这篇文章 相比,Xposed在开机的时候完成对所有的Hook Function的劫持,在原Function执行的前后加上自定义代码,由于是通过安装基于Xposed框架的App来修改系统,所以风险会比直接修改系统文件来得少,有一定风险,如变砖、无限重启等,需谨慎!

工程组成

XposedInstaller

这是Xposed的插件管理和功能控制APP,也就是说Xposed整体管控功能就是由这个APP来完成的,它包括启用Xposed插件功能,下载和启用指定插件APP,还可以禁用Xposed插件功能等。注意,这个app要正常无误得运行必须能拿到root权限。

Xposed

这个项目属于Xposed框架,其实它就是单独搞了一套xposed版的zygote。这个zygote会替换系统原生的zygote。所以,它需要由XposedInstaller在root之后放到/system/bin下。

XposedBridge

这个项目也是Xposed框架,它属于Xposed框架的Java部分,编译出来是一个XposedBridge.jar包。

XposedTools

Xposed和XposedBridge编译依赖于Android源码,而且还有一些定制化的东西。所以XposedTools就是用来帮助我们编译XposedXposedBridge的。

使用示例

环境搭建

一、下载、安装XposedInstaller

下载地址

安装后如图所示:

XposedInstaller.apk
XposedInstaller.apk

...

二、gradle 配置

dependencies {
    // ** 省略部分代码
    provided 'de.robv.android.xposed:api:82'
    //如果需要引入文档,方便查看的话
    provided 'de.robv.android.xposed:api:82:sources'
}

三、AndroidManifest 配置

在application标签下添加配置:

<?xml version="1.0" encoding="utf-8"?>
<manifest xxx

    <application xxx>
    
        <!-- 1、标识自己是否为一个Xposed模块 -->
        <meta-data
            android:name="xposedmodule"
            android:value="true"/>
            
        <!-- 2、Xposed模块的描述信息 -->
        <meta-data
            android:name="xposeddescription"
            android:value="a sample for xposed"/>
            
        <!-- 3、支持Xposed框架的最低版本 -->
        <meta-data
            android:name="xposedminversion"
            android:value="53"/>

    </application>

</manifest>

至此,准备工作都已完毕,下面可以扩展xposed模块了~

模块扩展

这里我简单模拟一下获取imei号的劫持篡改。

一、activity 代码示例:

        TextView tvImei = (TextView) findViewById(R.id.tv_imei);
        TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
        String imei = telephonyManager.getDeviceId();
        tvImei.setText("imei:" + imei);

二、TelephonyHooks

通过源代码跟踪,我们发现telephonyManager.getDeviceId()
在android.telephony.TelephonyManager包下,所以我们需要劫持此方法。

public class TelephonyHooks implements IXposedHookLoadPackage {

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        // 可以排除非当前包名
        if (!lpparam.packageName.equals("com.walid.xposedlocation")) {
            return;
        }
        XC_MethodHook hook = new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                XposedBridge.log("beforeHookedMethod");
            }

            @Override
            protected void afterHookedMethod(MethodHookParam methodHookParam) throws Throwable {
                methodHookParam.setResult("walid");
                XposedBridge.log("Hook device id is successful!!! ");
            }
        };
        findAndHookMethod("android.telephony.TelephonyManager", lpparam.classLoader, "getDeviceId", hook);
    }

}

三、在assets目录下创建xposed_init文件并添加TelephonyHooks文件所在完整目录

例如我的是:

com.walid.xposedlocation.TelephonyHooks

四、运行项目

运行结果如下:

劫持篡改前运行结果

此刻有的同学要吐槽了:

问:说您老忙活半天,这不还是没篡改成功吗,结果还是真正的imei号呀!是在逗我呢吗?

答: 由于xposed框架从根上Hook了Android Java虚拟机,所以它需要root,且每次为它启用新插件APP都需要重新启动才能生效,这点草民也有些想吐槽,不过这个权衡之后草民还是接受了,毕竟人无完人,何况程序呢。

五、开启xposed模块并软重启

1、选中模块

模块列表

2、选择重启

重新启动

3、运行结果

运行结果

长叹一口气,我们终于看到劫持篡改后的结果了~

结语

这篇简短的教程,草民并没有像其他人一样给予大家demo地址之类的,因为草民并不想让大家直接下载demo,run一下就可以了,还是希望大家多动手,同时如果有不清楚的同学,随时联系草民,同时这样的hook技术可以应用到任何场合,包括反编译、分析竞品、植入广告、抢红包等等,还是希望将技术应用到该用的地方,而不是应用在非法或者违法常规的事情上面,忘谨记!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,520评论 25 707
  • 安全博客 > 技术研究 > 浅谈android hook技术 浅谈android hook技术 您当前的位置:...
    光剑书架上的书阅读 6,146评论 0 8
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,401评论 2 45
  • 人生如跑步,或领跑,或逃跑,仅在你的一念之间。 人生就像一场跑步,少年时候,是这场跑步的初始,每个人都充满了生机与...
    凤凉阅读 286评论 3 12
  • 不断创新,不断进步,是中科贴针灸从不改变的使命! 铭记历史,创造历史,是中科贴针灸从不遗忘的初衷! 中科贴针灸,创...
    das0609阅读 2,105评论 0 0