专栏名称: 郭霖
Android技术分享平台,每天都有优质技术文章推送。你还可以向公众号投稿,将自己总结的技术心得分享给大家。
目录
相关文章推荐
stormzhang  ·  来自李子柒的压迫感 ·  昨天  
鸿洋  ·  理解Android ... ·  昨天  
鸿洋  ·  Android H5页面性能分析策略 ·  3 天前  
鸿洋  ·  AndroidManifest中uses-l ... ·  1 周前  
51好读  ›  专栏  ›  郭霖

Android Hook框架Xposed入门

郭霖  · 公众号  · android  · 2016-09-28 08:00

正文

今日科技快讯

据知情人士透漏,迪士尼公司正在评估对Twitter的收购事宜。全球第二大的社交网络平台Twitter,在成立最初几年内迅速爆红,国内的新浪微博也正是模仿的Twitter而建立的。但最近几年Twitter遇到成长乏力,用户流失率高,股价持续低迷等一系列问题,被收购的声音也是不绝于耳。目前对Twitter表示感兴趣的公司还是有不少的,包括微软、迪士尼、Salesforce等巨头。而Twitter目前的CEO杰克·多西正是迪士尼的董事之一,因此外界猜测由迪士尼收购Twitter的概率较高。

作者简介

本篇来自 chendd 的投稿,分享了如何使用 Xposed框架(尚未明了的朋友看正文即可)。另外友情提示,Xposed框架的原理是修改系统文件,有一定风险,如变砖、无限重启等。需谨慎!

chendd 的博客地址:

http://chendd.com

基础知识

Xposed 是 Android平台上较为出名的一个开源框架。在这个框架下,我们可以加载很多 插件App,这些 插件App 可以直接或间接操纵普通应用甚至系统上的东西。Xposed 原理上是 Hook Android 系统的核心进程 Zygote 来达到修改程序运行过程和结果。讲到这里,可能有人会问什么是 Hook?什么是 Zygote

  • Hook(钩子):钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。

  • Zygote(Android进程名):Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是 init进程 的子孙进程,也就是说,所有的进程都是直接或者间接地由 init进程fork出来的。在Android系统中,所有的应用程序进程以及系统服务进程 SystemServer 都是由 Zygote 进程孕育(fork)出来的,这也许就是为什么要取名英文本意为受精卵的 Zygote 原因吧。

由于 Xposed 框架 Hook 了Android的核心进程 Zygote,而其他应用启动都是从 Zygote 进程 fork 而来,就够达到针对系统上所有的应用程序进程的 Hook

Xposed简介

官网地址:

http://repo.xposed.info

源码地址:

https://github.com/rovo89

rovo89大神github主页,如图所示:

主页大致可以看出,xposed 主要由三个项目来组成的:

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

  • XposedBridge:Xposed 提供的jar文件,app_process 启动过程中会加载该jar包,其他的 Modules 的开发都是基于 该jar包。

  • XposedInstaller:Xposed的安装包,提供对基于Xposed框架的Modules的管理。

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

Xposed使用

在Android 4.0以上Android设备(需root权限,建议直接用模拟器)安装:

XposedInstaller

http://repo.xposed.info/module/de.robv.android.xposed.installer

启动 XposedInstaller 点击 【框架】:


点击 【安装/更新】 并重启,再点击框架看到看到 激活 底下两个都是绿色,代表框架安装成功:


我们可以点击【下载】来查看热门插件进行安装。

安装完插件点击【模块】进行勾选激活。

之后还需重启,插件才能生效。大家可以自己下载几个插件玩玩,本文重点不在这,就不演示了。

编写插件

这里我们 hook 自己编写的一个小的登录app来获取用户名密码。

界面比较简单,输入用户名密码点击登录弹出用户输入的密码:


界面代码:


1. 在 AndroidManifest.xml 文件中配置:


2. 导入其jar包:

XposedBridgeApi-.jar

http://forum.xda-developers.com/xposed/xposed-api-changelog-developer-news-t2714067

下载完毕后我们需要将 Xposed Library 复制到 lib目录注意是lib目录,不是Android提供的libs目录),然后将这个jar包添加到 Build PATH 中。

3. 声明主入口路径

需要在 assets文件夹 中新建一个 xposed_init 的文件,并在其中声明主入口类。如这里我们的主入口类为:

com.example.xposedtest.HookUtil

4. 使用 findAndHookMethod 方法 Hook

这是最重要的一步,我们之前所分析的都需要到这一步进行操作。如我们之前所分析的登陆程序,我们需要劫持,就是需要 Hook com.example.logintest.MainActivity 中的isCorrectInfo 方法。我们使用 Xposed 提供的 findAndHookMethod 直接进行 MethodHook 操作。在其 Hook 回调中使用 XposedBridge.log 方法,将登陆的账号密码信息打印至 Xposed 的日志中。具体操作如下所示:


5. 运行程序,查看效果:


重启Android设备,进入 XposedInstalle r点击【日志】查看,因为我们之前使用的是 XposedBridge.log 方法打印 log,所以 log 都会显示在此处。我们发现我们需要劫持的账号密码都显示再来此处。


这里由于demo是我们自己写的,所以知道 hook 它的帐号校验方法 isCorrectInfo 来获取用户名密码,如果有些程序账户校验没有封装方法呢?其实我们可以 hook 其它一些必有的方法,如 button的onClick方法,甚至可以动态改变 EditText 的内容,做法如下:



点击登录按钮,发现输入框内容改变了:


之前 登录app 密码EditText 声明为 private 时,导致反射获取报 NoSuchFileException,原因是普通的反射不能获取私有变量, 改为 EditText 声明改为 public 后成功,或者不能改 EditText 声明时,可以用以下方法,无论公有私有都可以获取:


总结

既然能成功Hook自己的App,那么系统应用和其它应用的也同理,只不过需要知道系统公开接口或者反编译获得相应的接口,下次讲解Hook来做些好玩的东西。

本文源码:

https://github.com/chendd/XposedTest.git

参考文章:

http://www.csdn.net/article/1970-01-01/2825462


更多