首页
社区
课程
招聘
Vibe了一个Binder监控App行为的小玩具
发表于: 2026-7-5 21:35 3601

Vibe了一个Binder监控App行为的小玩具

2026-7-5 21:35
3601

Vibe了一个Binder消息跟踪小玩具. 本质上是在大佬的基础上做了一些拓展和完善. 测了一些厂商的App,发现用来做行为检测还算不错,能给逆向分析提供一些"灵感". 于是放出来大家一起玩儿.

null-luo佬的btrace只做了Binder的请求监控,但是我们在实际逆向分析过程中除了看请求也有看响应内容的需求.尤其是在做风控对抗时,不看响应难以判断这个Binder请求是否暴露了什么痕迹.

Binder请求是可以分为oneway(只调用无响应)和twoway(调用完了还有响应内容)的. oneway请求自然是只抓请求就可以,但是twoway请求,除了App发起调用时的一次Binder调用,目标返回响应其实也是一次Binder调用.

举个例子:

App调用PMS的getPackageInfo方法时, App会先把参数通过Binder消息发送给PMS,而后这个发送Binder消息的线程变成同步阻塞状态. 当PMS把响应Binder消息返回过来以后,App的线程才会继续向下执行.

每一个Binder消息都会经过binder_transaction,而这个函数的第4个参数就是reply标志位.如果标志位被置1,就证明当前的消息是一个relpy的消息.

但是只能判断出reply对于我们的需求还远远不够,只有把请求和响应一一对应起来,我们才能知道这一次Binder调用的真实情况.

这里我通过debug_id来将两个请求帧关联起来. debug_id是内核在创建每一笔事务时分配的编号,全局唯一而且稳定,一笔事务从request到reply自始至终都是同一个debug_id.

twoway请求中的reply消息,在到达binder_transaction函数时结构体内已经有了debug_id,直接读就行.

reply是服务端(比如PMS)处理完请求以后发回来的,这个时候服务端线程的thread->transaction_stack上还挂着当初那笔request的binder_transaction对象(内核里管它叫in_reply_to), debug_id就是它的一个属性.

沿用btrace在binder_transaction入口的Hook点,可以直接拿到请求Parcel消息内容,但request的struct binder_transaction结构体要到函数体里才被内核创建出来,所以这里我又加了两个Hook点来关联出来request的Parcel内容和debug_id.

首先是在binder_transaction上挂了一个raw_tracepoint. tracepoint的触发点在函数体里,这时候相关结构体已经建好了,debug_id能读到.

但这又带出一个新问题: 入口kprobe上报的"事件本体"和raw_tracepoint上报的debug_id是分两次发出去的,单次直接发的话会因为ebpf的限制而导致ebpf加载失败. 所以这里又加了第二个Hook点,来关联前后的Parcel消息和debug_id.

单个request的入口kprobe和raw_tracepoint,跑在同一个线程、同一次函数调用里,中间不会切走. 所以在入口处先分配一个cookie写进pending_map[tid],实现Parcel和中间态的映射,等raw_tracepoint触发时,按当前tid把中间态cookie取回来,和debug_id一起上报.

到这里两条路径就都打通了:

两条帧都带上了debug_id以后,最终的App端只要看谁和谁的debug_id相等,就能把一次twoway调用的request和reply重新拼回一对.

btrace受限于纯Golang的原因,只能用离线跑再持久化的方式来解析包名&方法名. 这里我补齐了动态反射的能力,还额外加了App私有的AIDL解析.

Binder消息中自带了调用方和被调用方的UID,有了这个信息就可以得到基础包名信息.而进一步的接口名和方法名就需要进一步对Parcel内容进行解析了.

这里我兼容了Android O / Android P / Android Q+ 三种格式的Binder消息. 同时针对于系统驱动的HIDL做了单独适配,如果还是不能覆盖,则会采用所谓的"启发式"推理,根据数据格式大致推测一个结构. 这个不保准,所以会单独标注出来.


[招生]科锐逆向工程师培训(2026年7月3日实地,远程教学同时开班, 第56期)!

收藏
免费 0
打赏
分享
最新回复 (48)
雪    币: 159
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
看看
2026-7-5 21:38
0
雪    币: 7745
活跃值: (24956)
能力值: ( LV12,RANK:550 )
在线值:
发帖
回帖
粉丝
3
看看
2026-7-5 21:50
0
雪    币: 4477
活跃值: (7547)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
看看
2026-7-5 22:21
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
tql
2026-7-5 22:49
0
雪    币: 88
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
不错,能监视解析就能修改
2026-7-6 00:39
0
雪    币: 88
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
但还有getinstalledPackages这种返回一大堆的帧包的情况要注意
2026-7-6 00:41
0
雪    币: 2352
活跃值: (2837)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
的情况要注意
2026-7-6 00:45
0
雪    币: 2352
活跃值: (2837)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
compose
2026-7-6 00:46
0
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
向大佬学习
2026-7-6 08:00
0
雪    币: 1560
活跃值: (5408)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
11
666
2026-7-6 08:05
0
雪    币: 725
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
看看
2026-7-6 09:47
0
雪    币: 427
活跃值: (1935)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
6666
2026-7-6 10:05
0
雪    币: 7062
活跃值: (7150)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
66
2026-7-6 10:10
0
雪    币: 105
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
感谢分享
2026-7-6 10:21
0
雪    币: 3557
活跃值: (7175)
能力值: ( LV11,RANK:185 )
在线值:
发帖
回帖
粉丝
16
1
2026-7-6 10:36
0
雪    币: 2478
活跃值: (2770)
能力值: (RANK:140 )
在线值:
发帖
回帖
粉丝
17
好东西,有空的时候得试试
2026-7-6 10:44
0
雪    币: 1741
活跃值: (7763)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
18
1
2026-7-6 10:52
0
雪    币: 1059
活跃值: (1340)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
666
2026-7-6 11:17
0
雪    币: 227
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
666
2026-7-6 12:01
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
666
2026-7-6 13:03
0
雪    币: 51
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
22
tql
2026-7-6 14:04
0
雪    币: 158
活跃值: (5266)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
向大佬学习 
2026-7-6 15:34
0
雪    币: 1698
活跃值: (2798)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
向大佬学习 
2026-7-6 17:30
0
雪    币: 4364
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25
6666
2026-7-6 19:12
0
游客
登录 | 注册 方可回帖
返回