Frida Hook Java

Frida spawn启动app,Hook System类

Frida spawn启动app

  • 有时候app启动好后,我们需要Hook的地方流程就已经结束了,所以我们需要用spawn来启动app,在app启动时就把Hook脚本注入到进程

  • frida -U --no-pause -f com.tlamb96.spetsnazmessenger -l hook.js

  • -U指USB连接的物理设备

  • --no-pause:默认情况下,Frida 在注入脚本后会暂停目标进程,需手动恢复(如调用 resume())。此参数让应用在注入后 立即自动运行,无需手动干预。

  • -f:启动(spawn)一个新的目标进程

  • -l:指定要注入的脚本

hook System:

  • var System = Java.use("java.lang.System");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var System = Java.use("java.lang.System");
console.log(System);
//frida -U --no-pause -f com.tlamb96.spetsnazmessenger -l hook.js
//hook System,
System.getProperty.overload('java.lang.String').implementation = function (key) {
var result = this.getProperty(key);
result = "Russia";
console.log("System.getProperty:", key, result);
return result;
};
System.getenv.overload('java.lang.String').implementation = function (key) {
var result = this.getProperty(key);
result = "RkxBR3s1N0VSTDFOR180UkNIM1J9Cg==";
console.log("System.getenv:", key, result);
return result;
};

Hook构造函数

hook 构造函数:

  • this.$init(i, str, str2, z);
1
2
3
4
5
6
7
var a = Java.use("com.tlamb96.kgbmessenger.b.a");
//hook 构造函数
a.$init.implementation = function (i, str, str2, z) {
this.$init(i, str, str2, z);
console.log("a.$init:", i, str, str2, z);
print_stack(); //打印了调用栈
};

打印调用栈,new一个实例与销毁

打印调用栈:

  • Frida并不自带打印调用栈的API,但可以通过调用java本身的代码打印调用栈

  • 在java中打印调用栈:通过主动抛出一个异常,然后给异常打印它的调用栈

  • new一个Exception的实例:.$new("print_stack"),里边的print_stack是随便取的

  • 获取调用栈:.getStackTrace(),安卓自带的

  • 把实例的对象析构掉:instance.$dispose();

1
2
3
4
5
6
7
8
9
function print_stack() {
Java.perform(function () {
var Exception = Java.use("java.lang.Exception");
var instance = Exception.$new("print_stack");
var stack = instance.getStackTrace();
console.log(stack);
instance.$dispose();
});
}

动态加载自己的dex并使用

动态加载自己的dex:

  • 运行写好的java程序生成.class文件
  • 生成jar文件:jar -cvf ddex.jar com/example/androiddemo/DecodeUtils.class
  • 使用dx将jar转dex文件:/Android/sdk/build-tools/28.0.3/dx --dex --output=ddex.dex ddex.jar
  • push到/data/local/tmp/里,chmod 777加权限
  • 一般在最前面加载,以保证后面可以使用:
    • var ddex2 = Java.openClassFile("/data/local/tmp/ddex2.dex");
    • ddex2.load();
    • 调用我们自己的dex中的方法:var DecodeUtils = Java.use("com.example.androiddemo.DecodeUtils");DecodeUtils.decode_p()DecodeUtils.r_to_hex()
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
jar -cvf ddex.jar com/example/androiddemo/DecodeUtils.class
/Users/yang/Library/Android/sdk/build-tools/28.0.3/dx --dex --output=ddex.dex ddex.jar
*/
var ddex2 = Java.openClassFile("/data/local/tmp/ddex2.dex");

Java.perform(function () {
//frida动态加载了dex
ddex2.load();
var DecodeUtils = Java.use("com.example.androiddemo.DecodeUtils");
console.log("DecodeUtils.decode_p:", DecodeUtils.decode_p());
console.log("r to hex", DecodeUtils.r_to_hex());
}

Hook.js完整代码

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
function hook_java() {
//var ddex = Java.openClassFile("/data/local/tmp/ddex.dex");
//frida动态加载了dex
/*
jar -cvf ddex.jar com/example/androiddemo/DecodeUtils.class
/Users/yang/Library/Android/sdk/build-tools/28.0.3/dx --dex --output=ddex.dex ddex.jar
*/
var ddex2 = Java.openClassFile("/data/local/tmp/ddex2.dex");

Java.perform(function () {
//frida动态加载了dex
ddex2.load();
var DecodeUtils = Java.use("com.example.androiddemo.DecodeUtils");
console.log("DecodeUtils.decode_p:", DecodeUtils.decode_p());
console.log("r to hex", DecodeUtils.r_to_hex());

var System = Java.use("java.lang.System");
console.log(System);
//frida -U --no-pause -f com.tlamb96.spetsnazmessenger -l hook.js
//hook System,
System.getProperty.overload('java.lang.String').implementation = function (key) {
var result = this.getProperty(key);
result = "Russia";
console.log("System.getProperty:", key, result);
return result;
};

System.getenv.overload('java.lang.String').implementation = function (key) {
var result = this.getProperty(key);
result = "RkxBR3s1N0VSTDFOR180UkNIM1J9Cg==";
console.log("System.getenv:", key, result);
return result;
};

var a = Java.use("com.tlamb96.kgbmessenger.b.a");
//hook 构造函数
a.$init.implementation = function (i, str, str2, z) {
this.$init(i, str, str2, z);
console.log("a.$init:", i, str, str2, z);
print_stack(); //打印了调用栈
};

var MessengerActivity = Java.use("com.tlamb96.kgbmessenger.MessengerActivity");
MessengerActivity.a.implementation = function (str) {
console.log("MessengerActivity.a:", str);
var result = this.a(str);
console.log("MessengerActivity.a:", str, result);
return result;
};
});
}

function print_stack() {
Java.perform(function () {
var Exception = Java.use("java.lang.Exception");
var instance = Exception.$new("print_stack");
var stack = instance.getStackTrace();
console.log(stack);
instance.$dispose();
});
}


function main() {
hook_java();
}

setImmediate(main);