这个Hook
不是邓紫棋要给你唱的Hook
哦!而是在程序界流传的强大秘技-Hook
函数,Hook
原意是指钩子
,它表示的就是在某个函数的上下文作自定义的处理来实现咱们想要的黑科技
。 在不少技术领域都存在的这种Hook
技术,好比下面这些:java
在Python
的Web框架
中,如Django
,Flask
都存在这种Hook
技术,能够在请求的上下文
,应用的上下文
作自定义操做。android
在Scrapy
框架中,能够自定义MiddlerWare
,在请求
,解析
的时候作自定操做。编程
在K8S
编排框架中,咱们也能够在执行某些函数的上下文中插入Hook
函数,这也是和Web
框架同理 而今天咱们讲解的是关于Android
的Hook
技术,而有一款神器可以帮助咱们快速地开发Hook
模块,也就是Xposed
框架。其实网上的关于Xposed
模块编写的教程可谓是一抓一大把。但因为时间的推移,不少工具和方法都发生了变化(如Eclipse
退出安卓编程舞台,AndroidStudio
不断升级致使其一些设置也随之变化等)也正所以,网上的教程每每有一些时限性,好比现现在 provide
这个关键字已经被舍弃了却仍有人在用,还有些说要把jar
包放到lib
文件夹而非libs
文件夹……种种错误或者落伍的教程对新手产生了很大的误导。以前也搞过一阵子Xposed
框架,而今天在从新部署环境的时候参考某些教程的时候也遇到了不少的坑,因此想从新结合最新的配套工具写个小教程,主要讲解的如下两个方面:segmentfault
Xposed
框架介绍以及原理api
Xposed
框架实战bash
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 模块,要额外多完成如下四个硬性任务:微信
一、让手机上的xposed框架知道咱们安装的这个程序是个xposed模块。
二、模块里要包含有xposed的API的jar包,以实现下一步的hook操做。
三、这个模块里面要有对目标程序进行hook操做的方法。
四、要让手机上的xposed框架知道,咱们编写的xposed模块中,哪个方法是实现hook操做的。
复制代码
这就引出我即将要介绍的四大件(与前四步一一对照):网络
一、AndroidManifest.xml
二、XposedBridgeApi-xx.jar 与 build.gradle
三、实现hook操做的具体代码
四、xposed_Init
复制代码
牢记以上四大件,按照顺序一个一个实现,就能完成咱们的第一个Xposed模块编写。以上的原理咱们大体就介绍这么多,下面咱们实战开始吧!架构
Xposed
框架实战IDE
是
Android Studio
,首先打开
AndroidStudio
(以版本
3.4.2
为例,还在用老版本的请升级),创建一个工程,提示咱们选择“
Activity
”,那就选一个
Empty Activity
吧。(这个是模块的界面,随意选择便可)。
Xposed
模块 咱们能够把项目查看方式设置为Project
模式,以方便查看。而后在 “项目名称/app/src/main/
”目录下找到AndroidManifest.xml
,打开这个文件,并在指定位置插入如下三段代码:app
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposeddescription"
android:value="微信hook" />
<meta-data
android: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
模块了,但咱们本身内心清楚,这个模块还啥都不会干呢。下一步,咱们让这个模块长点本事。
咱们知道,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”
,同步便可:
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
代码)了。
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;
@Override
protected 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
中增长以下红框的代码
MainActivity
界面有个按钮,点击按钮后会弹出一个
toast
提示,该提示的内容由
toastMessage()
方法提供,而
toastMessage()
的返回值为
“我未被劫持”
。 如今,咱们已经作好了咱们的
App
了,下面咱们正式开始“施展刀法”(编写
hook
代码) 来
hook
咱们的
MainActivity
并修改这个类的
toastMessage()
方法,让它的返回值为
“你已被劫持”
:
“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
的源代码
Hook
的函数。 OK,以上用来
hook
的代码编写完毕,让咱们进行下一步操做。
右键点击 “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
一、让手机上的xposed框架知道咱们安装的这个程序是个xposed模块。
二、模块里要包含有xposed的API的jar包,以实现下一步的hook操做。
三、这个模块里面要有对目标程序进行hook操做的方法。
四、要让手机上的xposed框架知道,咱们编写的xposed模块中,哪个方法是实现hook操做的。
复制代码
像咱们这个例子很简单,没有特地的进行代码混淆
以及程序入口改写
等等,咱们寻找仍是很简单的,通常市面上的App
都是有不少反Xposed
的行为,咱们其实要学习的还有不少,这个小教程就当作个小入门吧。 下一篇文章和最近工做上的需求有关系,针对的是2019.10.28
以后搜狗微信关闭了在某些公众号内搜索的功能,因此咱们想要获取最新的公众号文章就不能采起搜狗微信这个渠道了,网上有不少教程都在谈论其余的方法,相比较来讲,仍是Hook
这个渠道是最实际的,咱们将会在以后的文章里详细谈论,你们能够期待一下~
“hook入门”
便可得到项目地址以及现成的Apk
前两年在二线大厂工做,目前在创业公司搬砖
接触方向是爬虫和云原生架构方面
有丰富的反爬攻克经验以及云原生二次开发经验
其余诸如数据分析、黑客增加也有所涉猎
作过百余人的商业分享以及屡次开办培训课程
目前也是CSDN博客专家和华为云享专家
深刻理解Python的TLS机制和Threading.local()
下一代容器架构已出,Docker何去何处?看看这里的6问6答!!
公众号内回复“私藏资料”便可领取爬虫高级逆向教学视频以及多平台的中文数据集