万物皆可Hook!重新捡起Hook神器-Xposed框架
引言
这个Hook
不是邓紫棋要给你唱的Hook
哦!而是在程序界流传的强大秘技-Hook
函数,Hook
原意是指钩子
,它表示的就是在某个函数的上下文做自定义的处理来实现我们想要的黑科技
。
在很多技术领域都存在的这种Hook
技术,比如下面这些:
在
Python
的Web框架
中,如Django
,Flask
都存在这种Hook
技术,可以在请求的上下文
,应用的上下文
做自定义操作。在
Scrapy
框架中,可以自定义MiddlerWare
,在请求
,解析
的时候做自定操作。在
K8S
编排框架中,我们也可以在执行某些函数的上下文中插入Hook
函数,这也是和Web
框架同理
而今天我们讲解的是关于Android
的Hook
技术,而有一款神器能够帮助我们快速地开发Hook
模块,也就是Xposed
框架。其实网上的关于Xposed
模块编写的教程可谓是一抓一大把。但由于时间的推移,很多工具和方法都发生了变化(如Eclipse
退出安卓编程舞台,AndroidStudio
不断升级导致其一些设置也随之变化等)也正因此,网上的教程往往有一些时限性,比如现如今provide
这个关键字已经被舍弃了却仍有人在用,还有些说要把jar
包放到lib
文件夹而非libs
文件夹……种种错误或者落伍的教程对新手产生了很大的误导。之前也搞过一阵子Xposed
框架,而今天在重新部署环境的时候参考某些教程的时候也遇到了很多的坑,所以想重新结合最新的配套工具写个小教程,主要讲解的以下两个方面:Xposed
框架介绍以及原理Xposed
框架实战
Xposed
框架介绍以及原理
Xposed
是Github
上rovo89
大佬设计的一个针对Android平台
的动态劫持项目,通过替换/system/bin/app_process
程序控制Zygote
进程,使得app_process
在启动过程中会加载XposedBridge.jar
这个jar
包,从而完成对Zygote
进程及其创建的Dalvik虚拟机
的劫持。
因为Xposed
工作原理是在/system/bin
目录下替换文件,在install
的时候需要root
权限,但是运行时不需要root
权限。
看到这里很多人会很懵,什么是Zygote
?简单来说在Android
系统中,应用程序进程都是由Zygote
进程孵化出来的,而Zygote
进程是由Init
进程启动的。Zygote
进程在启动时会创建一个Dalvik
虚拟机实例,每当它孵化一个新的应用程序进程时,都会将这个Dalvik
虚拟机实例复制到新的应用程序进程里面去,而一个应用程序进程被Zygote
进程孵化出来的时候,不仅会获得Zygote
进程中的Dalvik
虚拟机实例拷贝,还会与Zygote
一起共享Java运行时
库。这也就是可以将XposedBridge
这个jar
包加载到每一个Android
应用程序中的原因。XposedBridge
有一个私有的Native(JNI)
方法hookMethodNative
,这个方法也在app_process
中使用。这个函数提供一个方法对象利用Java
的Reflection
机制来对内置方法覆写。。。。等等这些都会借鉴各路大神的思路和分析,总而言之,就是从底层替换方法,可以让我们在不修改APK
源码的情况下,通过自己编写的模块来影响程序运行的框架服务,实现类似于自动抢红包、微信消息自动回复等功能。
其实,从本质上来讲,Xposed
模块也是一个Android
程序。但与普通程序不同的是,想要让写出的Android
程序成为一个``Xposed 模块,要额外多完成以下四个硬性任务:
1、让手机上的xposed框架知道我们安装的这个程序是个xposed模块。2、模块里要包含有xposed的API的jar包,以实现下一步的hook操作。3、这个模块里面要有对目标程序进行hook操作的方法。4、要让手机上的xposed框架知道,我们编写的xposed模块中,哪一个方法是实现hook操作的。
这就引出我即将要介绍的四大件(与前四步一一对照):
1、AndroidManifest.xml2、XposedBridgeApi-xx.jar 与 build.gradle3、实现hook操作的具体代码4、xposed_Init
牢记以上四大件,按照顺序一个一个实现,就能完成我们的第一个Xposed模块编写。以上的原理我们大致就介绍这么多,下面我们实战开始吧!
Xposed
框架实战
1. 迈开第一步,新建项目并编辑AndroidManifest.xml
我们使用的IDE
是Android Studio
,首先打开AndroidStudio
(以版本3.4.2
为例,还在用老版本的请升级),建立一个工程,提示我们选择“Activity
”,那就选一个Empty Activity
吧。(这个是模块的界面,随意选择即可)。
2、快速运行模板的Xposed
模块
我们可以把项目查看方式设置为Project
模式,以方便查看。然后在 “项目名称/app/src/main/
”目录下找到AndroidManifest.xml
,打开这个文件,并在指定位置插入以下三段代码:
<meta-dataandroid:name="xposedmodule"android:value="true" /><meta-dataandroid:name="xposeddescription"android:value="微信hook" /><meta-dataandroid:name="xposedminversion"android:value="53" />
效果如图:
插入代码之后,我们可以点击Run
运行App
。
不过,此时会出现如图提示,也就是缺少Device
设备来运行这个App
下一步我们要把手机连接Android Studio
,连接的办法很多,包括通过USB连接(物理连接)
和Wifi连接(也就是网络连接)
,我们为了节省方法,就采用物理连接,Ps: 有关于远程连接可以参考这篇文章,连接好我们的实体机之后我们点击这里
我们等待Android Studio
连接手机,连接好我们就可以看到在Logcat
选项里面看到我们的手机运行的日志报告。
有如图所示的日志打印之后我们就会发现我们就可以运行了,点击Run
之后会提示我们的手机安装我们刚才刚写的Apk
,不过我的手机提示安装时验证超时
,不能直接安装,苦恼,以后选手机也要选个正常的。关于Android Studio
安装Apk
失败的原因可以参考这篇文章,既然我们不能直接安装Apk
,我们就使用adb
直接来安装
安装好应用之后我们在Xposed
框架中勾选我们刚才的模块,然后我们重启一下Xposed
框架,就可以啦
这一步只是说明Xposed
框架已经认出了我们写的程序。但先别高兴太早——虽然框架已经觉得他是一个Xposed
模块了,但我们自己心里清楚,这个模块还啥都不会干呢。下一步,我们让这个模块长点本事。
3、搞定XposedBridgeApi-xx.jar 与 build.gradle
我们知道,Xposed
模块主要功能是用来Hook
其他程序的各种函数。但是,如何让前一步中的那个“一穷二白”的模块长本事呢?那就要引入 XposedBridgeApi.jar
这个包,你可以理解为一把兵器,模块有了这把宝刀才能施展出Hook
本领。很多以前的老教程都需要手动下载诸如XposedBridgeApi-54.jar
、 XposedBridgeApi-82.jar
等jar
包,然后手工导入到libs
目录里,才能走下一步道路,而这些jar
没有官方的渠道来安装,通常只是一个传一个的,都不知道变成了什么版本。其实在最新的AndroidStudio 3.1
以后,我们完全不用这么麻烦,只需要多写一行代码,就让AndroidStuido
自动给我们配置XposedBridgeApi.jar
!下面操作开始:
在 “项目名称/app/src/main/”
目录下找到build.gradle
,在图示位置加上:
repositories {jcenter()}
compileOnly 'de.robv.android.xposed:api:82'compileOnly 'de.robv.android.xposed:api:82:sources'
这句代码是告诉AndroidStuido
使用jcenter
作为代码仓库,从这个仓库里远程寻找 de.robv.android.xposed:api:82
这个API
。这个网上很少有Xposed
教程介绍它的!(我们不用自己找XposedBridgeApi.jar
了。注意!此处要用compileOnly
这个修饰符!网上有些写的是provide
,但是现在已经停用了!坑人啊!)
写完之后, build.gradle
会提示文件已经修改,是否同步。点击 “sync now”
,同步即可:
等待依赖构建完成
【Ps:如果网络不通,或者同步不畅,就不要进行第三步的repositories { jcenter()}
这个步骤了,改做这个步骤:手动下载XposedBridgeApi-82.jar
,拖放到“项目名称/app/libs/”
里面(不是网上说的单独建立lib
文件夹,那是很久以前的故事了!),然后右键“Add As Library”
自行添加这个jar
包。而compileOnly ‘de.robv.android.xposed:api:82′
和 compileOnly ‘de.robv.android.xposed:api:82:sources’
这两句仍然照常添加。】
好了,我们现在已经搞好了所有的准备工作。下一步,就要开始“施展刀法”(编写hook
代码)了。
4、实现hook
操作的具体代码
在“施展刀法”(编写hook
代码)之前,我们先要立一个靶子。在界面上画一个按钮,并在MainAcitiviy
里写代码如下:
package com.example.wx;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MainActivity extends AppCompatActivity {private Button button;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button = (Button) findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {Toast.makeText(MainActivity.this, toastMessage(), Toast.LENGTH_SHORT).show();}});}public String toastMessage() {return "我未被劫持";}}
而在页面布置的文件中,也就是activity_main.xml
中增加如下红框的代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ySdXfIgk-1572537350083)(https://upload-images.jianshu.io/upload_images/3029445-f19b8a5b73ea663f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
这个靶子很简单:MainActivity
界面有个按钮,点击按钮后会弹出一个toast
提示,该提示的内容由toastMessage()
方法提供,而toastMessage()
的返回值为“我未被劫持”
。
现在,我们已经做好了我们的App
了,下面我们正式开始“施展刀法”(编写hook
代码) 来hook
我们的MainActivity
并修改这个类的toastMessage()
方法,让它的返回值为“你已被劫持”
:
5、在MainActivity的同级路径下新建一个类“HookTest.java”
package com.example.wx;import de.robv.android.xposed.IXposedHookLoadPackage;import de.robv.android.xposed.XC_MethodHook;import de.robv.android.xposed.XposedBridge;import de.robv.android.xposed.XposedHelpers;import de.robv.android.xposed.callbacks.XC_LoadPackage;public class HookTest implements IXposedHookLoadPackage {public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {if (loadPackageParam.packageName.equals("com.example.root.xposd_hook_new")) {XposedBridge.log(" has Hooked!");Class clazz = loadPackageParam.classLoader.loadClass("com.example.root.xposd_hook_new.MainActivity");XposedHelpers.findAndHookMethod(clazz, "toastMessage", new XC_MethodHook() {protected void beforeHookedMethod(MethodHookParam param) throws Throwable {super.beforeHookedMethod(param);//XposedBridge.log(" has Hooked!");}protected void afterHookedMethod(MethodHookParam param) throws Throwable {param.setResult("你已被劫持");}});}}}
由代码可知,我们是通过IXposedHookLoadPackage
接口中的handleLoadPackage
方法来实现Hook
并篡改程序的输出结果的。代码中“com.example.wx”
是目标程序的包名,”com.example.wx.MainActivity”
是想要Hook的类,“toastMessage”
是想要Hook
的方法。我们在afterHookedMethod
方法(用来定义Hook了目标方法之后的操作)中,修改了toastMessage()
方法的返回值为“你已被劫持”。在完成代码编写之前,说一下为什么要Hook toastMessage
这个方法,我们先用Jadx
查看一下我们Apk
的源代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7We7NbAk-1572537350087)(https://upload-images.jianshu.io/upload_images/3029445-b82133c743da51f1.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
这个源码是没有经过混淆的,所以我们可以看到这个源码和我们之前写的一样,我们根据项目结构可以判断出我们需要Hook
的函数。
OK,以上用来hook
的代码编写完毕,让我们进行下一步操作。
6、最后一步,添加入口点
右键点击 “main ”
文件夹 , 选择new –> Folder –>Assets Folder
,新建assets
文件夹:
然后右键点击 assets
文件夹, new–> file
,文件名为xposed_init
(文件类型选text
),并在其中写上入口类的完整路径(就是自己编写的那一个Hook
类),这样,Xposed
框架就能够从这个xposed_init
读取信息来找到模块的入口,然后进行Hook
操作了:
好了,曙光就在前面!最后选择禁用Instant Run
: 单击 File -> Settings -> Build, Execution, Deployment -> Instant Run
,把勾全部去掉。
我们重新之前的安装Xposed
模块的方法,运行模块,点击,奇迹出现~
大功告成!!!
结语
从上面的实战中我们可以发现Hook
的基本原理以及步骤,重新看看我们之前说的四大步,Hook
的关键其实我们需要知道针对哪个模块的哪个方法进行Hook
1、让手机上的xposed框架知道我们安装的这个程序是个xposed模块。2、模块里要包含有xposed的API的jar包,以实现下一步的hook操作。3、这个模块里面要有对目标程序进行hook操作的方法。4、要让手机上的xposed框架知道,我们编写的xposed模块中,哪一个方法是实现hook操作的。
像我们这个例子很简单,没有特意的进行代码混淆
以及程序入口改写
等等,我们寻找还是很简单的,一般市面上的App
都是有很多反Xposed
的行为,我们其实要学习的还有很多,这个小教程就当做个小入门吧。
下一篇文章和最近工作上的需求有关系,针对的是2019.10.28
之后搜狗微信关闭了在某些公众号内搜索的功能,所以我们想要获取最新的公众号文章就不能采取搜狗微信这个渠道了,网上有很多教程都在谈论其他的方法,相比较来说,还是Hook
这个渠道是最实际的,我们将会在之后的文章里详细谈论,大家可以期待一下~
注意: 项目已经完成,想要获得源码可以关注下面的微信号,回复“hook入门”
即可获得项目地址以及现成的Apk
号主介绍
前两年在二线大厂工作,目前在创业公司搬砖
接触方向是爬虫和云原生架构方面
有丰富的反爬攻克经验以及云原生二次开发经验
其他诸如数据分析、黑客增长也有所涉猎
做过百余人的商业分享以及多次开办培训课程
目前也是CSDN博客专家和华为云享专家
震惊 | 只需3分钟!极速部署个人Docker云平台
深入理解Python的TLS机制和Threading.local()
我为什么不建议你使用Python3.7.3?
下一代容器架构已出,Docker何去何处?看看这里的6问6答!!
公众号内回复“私藏资料”即可领取爬虫高级逆向教学视频以及多平台的中文数据集
万物皆可Hook!重新捡起Hook神器-Xposed框架相关推荐
- android hook技术-Xposed框架 帮你轻松应对支付宝2016晒账单
一.支付宝2016年账单. 最近几天微信朋友圈充斥着各式的支付宝2016账单,对于程序员屌丝来说打开发现年度消费9W+,和他们动辄十几万的消费没得比,细看更有80%的消费还都是还信用卡,顿时万念俱灰啊 ...
- 万物皆可 Hook,探究 Xposed 框架 Hook 原理
作者 |俞家欢 低头需要勇气,抬头需要实力 引言 平时用着 Android 手机,喜欢折腾的同学或多或少都接触过 Xposed 框架,解锁.Root.刷包,一气呵成.本文将从原理和实践两部分带大家了解 ...
- 胡歌:万物皆有裂痕,那是光照进来的地方
文/麦大人 01 留学沉寂了一年多的胡歌,今冬携<猎场>再次进入我们的视野. 未播前,这部剧已做了很多宣传工作,片花和剧透都少的可怜,目的就是为了吊足人们的胃口. 后来还因播出平台和制作方 ...
- 万物皆可embedding,AI 应用神器 Milvus 登顶数据库顶会 SIGMOD
点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 AI 科技评论报道 编辑 | 陈大鑫 想象一下,一位计算神经科学家正 ...
- 万物皆可JOJO:这个GAN直接让马斯克不做人啦 !Demo在线可玩!
来源:量子位 这下真的是万物皆可JOJO化了! 本来就神采飞扬的马斯克,下一刻更是仿佛要直接"我不做人啦!" 世界名画蒙娜丽莎神秘优雅的微笑,似乎也变得JO灼了起来-- 再来个同一 ...
- DeepFake 新高度:一阶运动模型让“万物皆可动”
2020-04-26 18:17 导语:万物皆可动 作者 | 蒋宝尚 编辑 | 丛 末 DeepFake一方面被骂作"AI毒瘤",另一方面在B站上大行其道.最近,这项技术又用在了在 ...
- 梅宏院士:软件定义的未来——万物皆可互联,一切均可编程 | CNCC 2017
作者:杨文 摘要:结合当下的人工智能热潮,梅宏教授认为我们正在进入一个软件定义的时代.软件定义的技术本质是把原先一体化的硬件设施打破,将基础硬件虚拟化并提供标准化的基本功能,然后通过管控软件,控制其基 ...
- quicklook不能预览office_万物皆可格!给空格键施加神奇魔法的神器软件—快速预览工具QuicklookPC软件...
大家好,我是元力.今天给大家带来一款电脑端使用的超级神奇的软件.只需要选中文件,然后点击空格键,即可预览文件. 支持大部分格式,比如word.excel.pdf.图片.视频甚至图片的源文件等等.真正实 ...
- 万物皆可JOJO:这个GAN直接让马斯克不做人啦 | Demo可玩
博雯 发自 凹非寺 量子位 报道 | 公众号 QbitAI 这下真的是万物皆可JOJO化了! 本来就神采飞扬的马斯克,下一刻更是仿佛要直接"我不做人啦!" 世界名画蒙娜丽莎神秘优雅 ...
- Nature:万物皆可“编程”,结构材料也能实现数据存储,华人科学家一作
晗峰 发自 凹非寺 量子位 报道 | 公众号 QbitAI 最新的Nature研究向我们展示了,原来直接原来用力学的方法也能存储信息,这打破了机械装置和数字存储终端存在的界限. 熟悉计算机编程的朋友 ...
最新文章
- 探索“老药新用”最短路径:亚马逊AI Lab开源大规模药物重定位知识图谱DRKG
- java支持iSCSI协议,ISCSI协议
- 程序员辞职卖卷饼:4天挣1个月工资!摆摊真那么赚钱?
- Jmeter之逻辑控制器操作
- mgg mysql_MYSQL基础命令
- 3d激光雷达开发(八叉树)
- IIS7.5标识介绍
- 基于C语言的个人信息管理系统
- html css开关按钮样式,纯CSS实现开关按钮
- css内联样式!important
- 【实验技术笔记】细胞表型检测之细胞凋亡(Hoechst染色 + PI染色 + TUNEL 染色 + Annexin V-PI 双染)
- The Curious Case of Neural Text Degeneration
- 黄梅一中高考2021成绩查询,2020年黄冈高考成绩出炉!这些高分考生太棒了!
- 事件分发(EventDispatcher)模式
- Linux-mdadm命令实现软RAID
- 怎么在线对图片进行压缩不改变清晰度
- ABP学习笔记:领域服务 和 应用服务 区别
- 教资初级中学计算机真题,初中信息技术教资面试真题:VB程序设计语言的操作环境...
- 一句话可以彻底改变一个人的命运
- 2018 WAIC大咖云集,七牛云“视觉智能,瞳鉴未来”论坛开启在即
热门文章
- 从拉格朗日插值法到范德蒙行列式
- 省市区三级联动插件(v-distpicker)
- DevOps ACA 软件代码与质量管理(六)
- Django 开发收银系统六
- 一些嵌入式开发有用的github上的开源代码库
- 利用nginx搭建静态资源服务器,把服务器本地文件对外可直接访问
- 计算机视觉基础教程笔记索引
- oracle当天是这个月的第几周,oracle_oracle查看当前日期是第几个星期的方法,系统当前时间是多少周,就是 - phpStudy...
- java poi 读合并单元格的内容,poi合并单元格,poi合并单元格并设置内容居中
- C语言全局变量和局部变量的范围以及区别