学习笔记:Android Xposed 框架入门

学习笔记:Android Xposed 框架入门

目录

  • Xposed 框架简介
  • Xposed 框架的具体使用
  • 原理分析

Xposed 框架简介

Xposed是一款优秀的android java层 hook 框架。它允许你在不修改apk源码的情况下,通过编写自己的模块来改变apk的行为。它的优点是采用了插件机制,模块能够适用不同版本的框架和rom。模块改变apk行为的操作发生在内存中,对源apk不进行任何修改。你只需要安装编写的模块并重启相应的设备即可。

xposed 主要由三个项目来组成的:

  1. Xposed:Xposed的C++ 部分,主要是用来替换 /system/bin/app_process,并为XposedBridge 提供 JNI方法。
  2. XposedBridge:Xposed 提供的jar文件,app_process 启动过程中会加载该jar包,其他的 Modules 的开发都是基于 该jar包。
  3. XposedInstaller:Xposed的安装包,提供对基于Xposed框架的Modules的管理。

xposed 目前已逐步支持 ART虚拟机,兼容 android 5.0 以上版本。


Xposed 框架的具体使用

具体的安装教程需要自行百度,的确是安装环境比较耗费时间,不过都是躲不掉的!!!这里用一个绕过密码登录的例子进行说明。Android studio的配置代码这里就不贴了,需要的话可以去百度一下,很多资源。以下是安装使用教程:Xposed框架安装使用教程

1. 创建 Android 工程

一个 Xposed 模块本质上是一个正常的 apk,所以你只需要去创建一个空的工程,不需要添加任何的 Activity。

2. 添加 jar 包

下载地址:jar包
在添加依赖项的时候注意使用 provided 不要使用 compile! 如下图红线部分所示:

然后还需要在 AndroidManifest.xml 文件配置,在Application节点下添加以下信息:

3. 在 assets 文件夹下写入入口信息

在 Android 工程的 main 文件夹下创建 assets 文件夹(没有的话)。XposedBridge 从assets 目录中的xposed_init 文件中获取入口点。xposed_init文件中每行配置一个进入点,使用完全限定名。在该例子中,进行如下配置。

4. 模块实现
  1. 在模块中创建一个类,根据自己的需求实现以下的接口:

    • 安卓系统启动的时候(使用 IXposedHookZygoteInit 接口)
    • 一个新的app被加载的时候(使用 IXposedHookLoadPackage 接口)
    • 一个资源被初始化的时候( 使用 IXposedHookInitPackageResources 接口)
  2. 指定要 hook 的包名(这里是 com.markable.androidsecurity ),也就是你想要 hook 的应用包名,我这里就是本项目。

  3. 判断当前加载的包是否是指定的包(在接口方法中判断)

  4. 指定要 hook 的方法名‍‍

  5. 实现beforeHookedMethod方法和afterHookedMethod方法( hook 的具体功能)‍‍

以下是绕过登录的完整代码。

package com.markable.androidsecurity.module;

import android.widget.TextView;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;

/**
 * Created by Markable on 2018/7/11.
 * Github: https://github.com/ddz-mark
 * Info:
 */

public class SkipLoginCheck implements IXposedHookLoadPackage {

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam param) throws Throwable {
        // 判断是否是应用的包名
        if (param.packageName.equals("com.markable.androidsecurity")) {
            findAndHookMethod("com.markable.androidsecurity.LoginActivity", param.classLoader, "login", String.class, String.class, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                    XposedBridge.log("开始劫持了~");
                    XposedBridge.log("参数1 = " + param.args[0]);
                    XposedBridge.log("参数2 = " + param.args[1]);
                }

                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    XposedBridge.log("劫持前返回的result: " + param.getResult());
                    param.setResult(true);// 绕过登录
                    XposedBridge.log("劫持后返回的result: " + param.getResult());
                    XposedBridge.log("hook finish");
                }
            });
        }

    }

}

以上是绕过登录的功能代码,核心代码在于 param.setResult(true),可以让登录直接通过(这里是简单的登录模拟功能)。


5. 原理分析

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

Zygote进程在启动的过程中,除了会创建一个Dalvik虚拟机实例之外,还会将Java运行时库加载到进程中来,以及注册一些Android核心类的JNI方法来前面创建的Dalvik虚拟机实例中去。注意,一个应用程序进程被Zygote进程孵化出来的时候,不仅会获得Zygote进程中的Dalvik虚拟机实例拷贝,还会与Zygote一起共享Java运行时库。这也就是可以将XposedBridge这个jar包加载到每一个Android应用程序中的原因。XposedBridge有一个私有的Native(JNI)方法hookMethodNative,这个方法也在app_process中使用。这个函数提供一个方法对象利用Java的Reflection机制来对内置方法覆写。具体的实现可以看下文的Xposed源代码分析。

  • Hook/Replace 简析

Xposed 框架中真正起作用的是对方法的hook。在Repackage技术中,如果要对APK做修改,则需要修改Smali代码中的指令。而另一种动态修改指令的技术需要在程序运行时基于匹配搜索来替换smali代码,但因为方法声明的多样性与复杂性,这种方法也比较复杂。
在Android系统启动的时候,zygote进程加载XposedBridge将所有需要替换的Method通过JNI方法hookMethodNative指向Native方法xposedCallHandler,xposedCallHandler在转入handleHookedMethod这个Java方法执行用户规定的Hook Func。
XposedBridge这个jar包含有一个私有的本地方法:hookMethodNative,该方法在附加的app_process程序中也得到了实现。它将一个方法对象作为输入参数(你可以使用Java的反射机制来获取这个方法)并且改变Dalvik虚拟机中对于该方法的定义。它将该方法的类型改变为native并且将这个方法的实现链接到它的本地的通用类的方法。换言之,当调用那个被hook的方法时候,通用的类方法会被调用而不会对调用者有任何的影响。在hookMethodNative的实现中,会调用XposedBridge中的handleHookedMethod这个方法来传递参数。handleHookedMethod这个方法类似于一个统一调度的Dispatch例程,其对应的底层的C++函数是xposedCallHandler。而handleHookedMethod实现里面会根据一个全局结构hookedMethodCallbacks来选择相应的hook函数,并调用他们的before, after函数。
当多模块同时Hook一个方法的时候,Xposed会自动根据Module的优先级来排序,调用顺序如下:
A.before -> B.before -> original method -> B.after -> A.after

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

推荐阅读更多精彩内容