安卓逆向 - Frida Hook(抓包实践)

安卓逆向 - 基础入门教程

本文转自小馒头yy 并作补充

一、引言

上篇文章:安卓逆向 - 基础入门教程_小馒头yy的博客-CSDN博客 介绍了Frida的安装、基本使用,今天我们来看看Frida常用Hook和基于Frida抓包实践。

二、Frida常用 Hook脚本

1、hook java.net.URL

1
2
3
4
5
6
7
8
function hook1() {
var URL = Java.use('java.net.URL');
URL.$init.overload('java.lang.String').implementation = function (a) {
console.log('加密前:' + a)
showStacks()
this.$init(a)
}
}

2、hook okhttp3 HttpUrl

1
2
3
4
5
6
7
8
9
10
function hookOkhttp3() {
var Builder = Java.use('okhttp3.Request$Builder');
Builder.url.overload('okhttp3.HttpUrl').implementation = function (a) {
console.log('a: ' + a)
var res = this.url(a);
showStacks()
console.log("res: " + res)
return res;
}
}

3、hook okhttp3 addHeader

1
2
3
4
5
6
7
8
9
10
11
function hook() {
var Builder = Java.use("okhttp3.Request$Builder");
Builder["addHeader"].implementation = function (str, str2) {
console.log("key: " + str)
console.log("val: " + str2)
showStacks()
var result = this["addHeader"](str, str2);
console.log("result: " + result);
return result;
};
}

4、打印堆栈

1
2
3
4
5
function showStacks() {
Java.perform(function () {
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
});
}

5、hook Base64

1
2
3
4
5
6
7
8
9
function hookBase() {
// Base64
var Base64Class = Java.use("android.util.Base64");
Base64Class.encodeToString.overload("[B", "int").implementation = function (a, b) {
var rc = this.encodeToString(a, b);
console.log(">>> Base64 " + rc);
return rc;
}
}

6、hook HashMap

1
2
3
4
5
6
7
8
function hookMap() {
var Build = Java.use("java.util.HashMap");
Build["put"].implementation = function (key, val) {
console.log("key : " + key)
console.log("val : " + val)
return this.put(key, val)
}
}

三、某麦网抓包实践

本篇以某麦网帖子详情接口,演示如何基于Frida hook抓包

1、安装某麦网8...apk

2、搭建Frida hook 环境,注入 hook java.net.URL脚本

3、点进帖子详情打印出如下堆栈,我们可以根据打印出的信息,跟栈分析该接口的请求头。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
https://acs.m.taobao.com/gw/mtop.damai.wireless.discovery.detail.get/1.4/?source=10101&version=6000168&type=originaljson&data=%7B%22contentId%22%3A%2211088650%22%2C%22appType%22%3A%221%22%2C%22source%22%3A%2210101%22%2C%22osType%22%3A%222%22%2C%22pageSize%22%3A%2230%22%2C%22pageIndex%22%3A%221%22%2C%22version%22%3A%226000168%22%2C%22channel_from%22%3A%22damai_market%22%7D&appType=1&osType=2&channel_from=damai_market
java.lang.Exception
at java.net.URL.<init>(Native Method)
at tb.yy0.m(Taobao:1)
at anet.channel.request.a.p(Taobao:2)
at anet.channel.session.TnetSpdySession.w(Taobao:18)
at anetwork.channel.unified.NetworkTask.sendRequest(Taobao:6)
at anetwork.channel.unified.NetworkTask.run(Taobao:44)
at anetwork.channel.unified.UnifiedRequestTask$a.proceed(Taobao:15)
at com.taobao.orange.sync.NetworkInterceptor.intercept(Taobao:30)
at anetwork.channel.unified.UnifiedRequestTask$a.proceed(Taobao:7)
at anetwork.channel.unified.UnifiedRequestTask$3.run(Taobao:2)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)

4、使用Jadx打开某麦网apk

从at tb.yy0.m(Taobao:1)跟栈分析

image

根据调用栈往上走,定位到如下位置,注意这行代码:

1
ALog.f("awcn.TnetSpdySession", "", aVar.n(), "request headers", aVar.g());

image

代码注释很清楚了 request headers,我们跟进 hook aVar.g() 这个方法

1
2
3
public Map<String, String> g() {
return Collections.unmodifiableMap(this.f);
}

hook之,对象输出可以使用 JSONObject转一下

1
var JSONObject = Java.use("com.alibaba.fastjson.JSONObject");
1
2
3
4
5
6
7
8
9
function hook6() {
var JSONObject = Java.use("com.alibaba.fastjson.JSONObject");
var a = Java.use("anet.channel.request.a");
a["g"].implementation = function () {
var result = this["g"]();
console.log("result : " + JSONObject.toJSON(result).toString());
return result;
};
}

打印出如下内容:

image

请求 URL、 请求方法这边都写得很清楚啦。

image

收工!