文章目录
  1. 1. 预备知识
    1. 1.1. Hook原理
    2. 1.2. Hook的分类
  2. 2.  快速Hook代码搭建之cydia substrate
    1. 2.1. 函数钩子
    2. 2.2. 简单例子
    3. 2.3. Java反射

预备知识

Hook原理

Hook技术无论对安全软件还是恶意软件都是十分关键的一项技术,其本质就是劫持函数调用。但是由于处于Linux用户态,每个进程都有自己独立的进程空间,所以必须先注入到所要Hook的进程空间,修改其内存中的进程代码,替换其过程表的符号地址。在Android中一般是通过ptrace函数附加进程,然后向远程进程注入so库,从而达到监控以及远程进程关键函数挂钩。从Android的开发来说,Android系统本身就提供给了我们两种开发模式,基于Android SDK的Java语言开发,基于AndroidNDK的Native C/C++语言开发。所以,我们在讨论Hook的时候就必须在两个层面上来讨论。对于Native层来说Hook的难点其实是在理解ELF文件与学习ELF文件上,特别是对ELF文件不太了解的读者来说;对于Java层来说,Hook就需要了解虚拟机的特性与Java上反射的使用。

Hook的分类

  1. Java层的API Hook
  2. Native层So库Hook
  3. 全局hook

 快速Hook代码搭建之cydia substrate

函数钩子

函数钩子,顾名思义,就是对于函数进行挂钩,可以影响整个函数的执行,挂钩后,注入的代码就可以接管整个函数,修改函数的参数,返回值等。会玩的,还能够修改整个函数的行为,这个是真正的只有想不到,没有做不到!

简单例子

函数挂钩的方法如下:找到要挂钩的类,找到要挂钩的函数,然后对目标函数进行挂钩重写。例子来源于官网,地址http://www.cydiasubstrate.com/id/20cf4700-6379-4a14-9bc2-853fde8cc9d1/ 可分为以下几步:

  1. 安装cydiasubustrateAPK,下载地址如下:http://www.cydiasubstrate.com/
  2. 导入lib文件 substrate-api.jar。将substrate-qpi.jar拷贝到lib下,然后右键lib,选择Add As Library.

添加完以后我们可以看到MS的一个类,这个类有一些方法可以供我们使用

  1. AndroidManifest.xml文件修改。创建一个CydiaEntry的类,作为钩子的入口函数,将CydiaEntry写入一个value。当然我们还需要一uses-permission,也就是写入权限。

  1. 入口类编写,如上面就是f8.CydiMain这个文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package f8.cydia;
import com.saurik.substrate.MS;
import java.lang.reflect.Method;
public class CydiaEntry {
static void initialize(){
MS.hookClassLoad("android.content.res.Resources", new MS.ClassLoadHook() {
@Override
public void classLoaded(Class<?> resources) {
Method getColor;
try {
getColor = resources.getDeclaredMethod("getColor",Integer.TYPE);
}catch (Exception e){
getColor = null;
}
if(getColor !=null){
final MS.MethodPointer old = new MS.MethodPointer();
MS.hookMethod(resources,getColor,new MS.MethodHook(){
@Override
public Object invoked(Object o, Object... objects) throws Throwable {
return (int)old.invoke(res,args)& 0x0000ff00|0x00ff0000;
}
},old);
}
}
});
}
}

Java反射

Java可以通过反射的方法去获取类以及它的成员。反射相当于提供一些函数,让我们在不知道原始类的定义的情况下,去修改类中的成员的属性,值等。方法如下:
所有类的都是继承自object的,所以都可以使用object的方法。也可以强制转换为Object。所以,遇到无法表达出来的对象时,直接用object即可。

获取对象的类:

1
2
Object obj =”123”
Class clazz = pbj.getClass();

获取类中的方法:

1
2
3
4
Method[] mPuMethods = clazz.getMethods(); //获取公有的方法
Method[] mDeclareMethods = clazz.getDeclareMethods(); //获取类声明中的所有方法
Field[] mPbFields = clazz.getFields(); //获取public的Field
Field[] mDeclareFields = clazz.getDeclaredFields(); //获取申明的所以Field

使用对应的不是以s后缀的函数可以获取特定的函数或者field。

1
Method.invoke(obj,arg);

域操作

1
2
field.set(obj,”1”);
field.get(obj);

访问权限设置(域与方法一样,控制是否可以直接访问,其实相当于public属性)

1
2
field.isAccessible();
field.setAccessible(true);

其余的函数,可以获取函数的名称,还有其他种种信息

1
2
3
field.getName():
field.toString();
Class.forName(“android.view.Menu”);

文章目录
  1. 1. 预备知识
    1. 1.1. Hook原理
    2. 1.2. Hook的分类
  2. 2.  快速Hook代码搭建之cydia substrate
    1. 2.1. 函数钩子
    2. 2.2. 简单例子
    3. 2.3. Java反射