安卓逆向学习(一)
从万能的淘宝买了一个谷歌手机。无root不安卓,安装好Xpose的框架,准备学习逆向,“玩”手机!
1.什么是hook
Hook 就是在事件传送到终点前截获并监控事件的传输,像个钩子钩上事件一样,并且能够在钩上事件时,处理一些自己特定的事件。Hook 的这个本领,使它能够将自身的代码「融入」被勾住(Hook)的程序的进程中,成为目标进程的一个部分。
需要注意的是hook方法的作用,是将v已有的点击事件,替换成我们代理的点击事件。所以,在v还没有点击事件的时候进行hook,是没用的。
2.什么是Xposed
Xposed框架是一款可以在不修改APK的情况下影响程序运行(修改系统)的框架服务。不需要修改安卓源文件,而是通过分析程序运行来拦截并影响运行情况。具体需要把安卓apk逆向后然后分析代码,定位到具体的类,方法等,然后通过xposed来拦截修改方法等。
通过替换 /system/bin/app_process 程序控制 Zygote 进程,使得 app_process 在启动过程中会加载 XposedBridge.jar 这个 Jar 包,从而完成对 Zygote 进程及其创建的 Dalvik 虚拟机的劫持。 Xposed 在开机的时候完成对所有的 Hook Function 的劫持,在原 Function 执行的前后加上自定义代码。

补充知识——java反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法。
反射就是把java类中的各种成分映射成一个个的Java对象
3. hook的使用流程——“偷梁换柱”
a. 根据需求确定 要hook的对象
Hook 的选择点:尽量静态变量和单例,因为一旦创建对象,它们不容易变化,非常容易定位。
b. 寻找要hook的对象的持有者,拿到要hook的对象
(持有:B类 的成员变量里有 一个是A的对象,那么B就是A的持有者,如下)
1 | class B{ A a;} |
c. 定义“要hook的对象”的代理类,并且创建该类的对象
d. 使用上一步创建出来的对象,替换掉要hook的对象

举个栗子
1 | View v = findViewById(R.id.tv); |
是view
的点击事件,toast
了一段话,现在要求,不允许改动这个OnClickListener
,要在toast
之前添加日志打印 Log.d(...)
第一步:根据需求确定 要hook的对象;
我们的目的是在OnClickListener
中,插入自己的逻辑.所以,确定要hook
的,是v.setOnClickListener()
方法的实参。第二步:寻找要hook的对象的持有者,拿到要hook的对象\
进入v.setOnClickListener
源码:发现我们创建的OnClickListener
对象被赋值给了getListenerInfo().mOnClickListener1
2
3
4
5
6public void setOnClickListener( OnClickListener l){
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}getListenInfo()代码如下:
1
2
3
4
5
6
7ListenerInfo getListenerInfo() {
if (mListenerInfo != null) {
return mListenerInfo;
}
mListenerInfo = new ListenerInfo();
return mListenerInfo;
}一个View对象中只存在一个
ListenerInfo
对象,进入ListenerInfo内部:发现OnClickListener
对象 被ListenerInfo所持有.1
2
3
4
5static class ListenerInfo {
...
public OnClickListener mOnClickListener;
...
}到这里为止,完成第二步,找到了点击事件的实际持有者:
ListenerInfo
.
1 | // 得到view的mListenerInfo对象,这个对象就是点击事件的持有者 |
1 | //要从这里面拿到当前的点击事件对象,得到原始的 mOnClickListener 对象 |
- 第三步:定义“要
hook
的对象”的代理类,并且创建该类的对象
我们要hook
的是View.OnClickListener
对象,所以创建一个类 实现View.OnClickListener
接口.
1 | static class ProxyOnClickListener implements View.OnClickListener { |
然后,new
出它的对象待用。
1 | ProxyOnClickListener proxyOnClickListener = new ProxyOnClickListener(onClickListenerInstance); |
- 第四步:使用上一步创建出来的对象,替换掉要hook的对象,达成
偷梁换柱
的最终目的.
利用反射,将我们创建的代理点击事件对象,传给这个view
field.set(mListenerInfo, proxyOnClickListener);
4.使用XPosed进行hook
a. 首先第一步先进行配置,在清单文件AndroidManifest里 Application作用域里加上如下配置:
1 | <meta-data |
b. 第二步,在main目录下(java、res同级目录)创建assets文件夹,在该文件夹下新建一个xposed_init文件(该文件名称固定为xposed_init),该文件用于放置hook的入口,里面是一个路径(比如我的是com.blues.cracktest.XposedInit,XposedInit就是我hook的入口,这个类后面会提及)。
c. 第三步,新建一个类,这里就叫它XposedInit好了,让它实现(implements) IXposedHookLoadPackage 这个接口 ,在handleLoadPackage回调方法中进行拦截操作即可,而具体的拦截操作是借助XposedHelpers.findAndHookMethod方法和XposedBridge.hookMethod方法实现的,这两个方法也是比较简单的,从参数含义可以看到,主要是Hook的类名和方法名,然后还有一个就是拦截的回调方法,一般是拦截之前做什么的一个beforeHookedMethod方法和拦截之后做什么的一个afterHookedMethod方法。

参考:
https://www.jianshu.com/p/74c12164ffca?tdsourcetag=s_pcqq_aiomsg
https://www.jianshu.com/p/4f6d20076922
https://www.jianshu.com/p/9be58ee20dee