首页
社区
课程
招聘
[原创]【Abyss】Android平台BPF和SECCOMP的SVC指令拦截
发表于: 2025-1-23 13:38 33176

[原创]【Abyss】Android平台BPF和SECCOMP的SVC指令拦截

2025-1-23 13:38
33176

Android平台从上到下,无需ROOT/解锁/刷机,应用级拦截框架的最后一环 —— SVC系统调用拦截。

☞ Github: https://www.github.com/iofomo/abyss ☜ 

由于我们虚拟化产品的需求,需要支持在普通的Android手机运行。我们需要搭建覆盖应用从上到下各层的应用级拦截框架,而Abyss作为系统SVC指令的调用拦截,是我们最底层的终极方案。

源码位置:d66K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6A6L8$3k6G2L8h3!0Q4x3V1k6S2j5Y4W2K6M7#2)9J5c8Y4c8J5k6h3g2Q4x3V1k6E0j5h3W2F1i4K6u0r3M7%4k6U0k6i4t1`.

01. 说明

Seccomp(Secure Computing Mode):

SeccompLinux 内核的一个安全特性,用于限制进程可以执行的系统调用。它通过过滤系统调用,防止恶意程序执行危险操作。Seccomp 通常与 BPF 结合使用,以实现更灵活的过滤规则。

BPF(Berkeley Packet Filter):

BPF 是一种内核技术,最初用于网络数据包过滤,但后来被扩展用于更广泛的用途,包括系统调用过滤。BPF 程序可以在内核中运行,用于检查和过滤系统调用。

02. 主要流程

首先,配置 BPF 规则,如下我们配置了目标系统调用号的拦截规则,不在这个名单内的就放过,这样可以实现仅拦截我们关心的系统调用(即函数),提升拦截效率和稳定性。

1
2
3
4
5
6
7
8
9
10
11
12
13
static void doInitSyscallNumberFilter(struct sock_filter* filter, unsigned short& i) {
    // Load syscall number into accumulator
    filter[i++] = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr)));
    // config target syscall
    // add more syscall here ...
//    filter[i++] = BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_openat, 5, 0);
//    filter[i++] = BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_getcwd, 4, 0);
//    filter[i++] = BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_chdir, 3, 0);
//    filter[i++] = BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execve, 2, 0);
    filter[i++] = BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_openat, 1, 0);
 
    filter[i++] = BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW);
}

然后,我们需要过滤掉一些系统库和自身库,防止写入死循环。

  • 自身实现库的过滤【必须】
  • vdso 的过滤【必须】
  • linker 的过滤【可选,提效】
  • libc 的过滤【可选,提效】

通过解析进程 maps 中对应库地址区间,配置跳过此区间的系统调用规则。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static void doInitSyscallLibFilterByAddr(struct sock_filter* filter, unsigned short& i, const uintptr_t& start, const uintptr_t& end) {
    // Load syscall lib into accumulator
#if defined(__arm__)
    filter[i++] = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, instruction_pointer));
    filter[i++] = BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, start, 0, 2);
    filter[i++] = BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, end, 1, 0);
    filter[i++] = BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW);
#else // __aarch64__
    filter[i++] = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, instruction_pointer) + 4));
    filter[i++] = BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, (uint32_t)(start >> 32), 0, 4);
    filter[i++] = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, instruction_pointer)));
    filter[i++] = BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, (uint32_t)start, 0, 2);
    filter[i++] = BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, (uint32_t)end, 1, 0);
    filter[i++] = BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW);
#endif
}

其次,应用以上配置。


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

收藏
免费 6
支持
分享
最新回复 (20)
雪    币: 105
活跃值: (5096)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
66666666666
2025-1-24 12:05
0
雪    币: 2731
活跃值: (3162)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3

这个项目如何 导入自己的项目中进行测试  ? 大佬 有 api使用的说明不?  (未看真切 答案在 开头    把源码 直接复制到自己的项目中就行了 文章 中也说明的很清楚  我看的是大佬之前的 文章  没发现 这个篇是新的 )

最后于 2025-2-5 19:09 被逆天而行编辑 ,原因:
2025-2-5 19:03
0
雪    币: 2731
活跃值: (3162)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
大佬 为什么 你给的demo 有日志显示  而我导入的源码 进的项目 却提示 内核不支持
2025-2-5 20:19
0
雪    币: 231
活跃值: (776)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
逆天而行 这个项目如何 导入自己的项目中进行测试  ? 大佬 有 api使用的说明不?&nbs ...
你可以直接将svcer模块源码导入到你工程就可以
2025-2-5 20:23
0
雪    币: 231
活跃值: (776)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
逆天而行 大佬 为什么 你给的demo 有日志显示 而我导入的源码 进的项目 却提示 内核不支持 [em_010]
你的内核版本多少?这个是有版本要求的,你可以看初始化函数有内核版本检测,基本上最近几年的系统都应该支持的
2025-2-5 20:24
0
雪    币: 2731
活跃值: (3162)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
Tiony.bo 你的内核版本多少?这个是有版本要求的,你可以看初始化函数有内核版本检测,基本上最近几年的系统都应该支持的

我使用的piexl 5  内核版本 是 4.19 观察 大佬的源码 发现最低 需要 5.9    我观察源码,发现原理 与这篇文章 相似 基于seccomp+sigaction的Android通用svc hook方案 - 软件逆向板块 - 逆想技术论坛 - Powered by Discuz! 我尝试编写类似的代码 结合大佬项目  发现大佬对 多架构做了 支持 我拿来直接用   没做什么 线程判断   做的app内 全局 hook   就能够实现 我的需求 对文件进行 io重定向

最后于 2025-2-6 13:02 被逆天而行编辑 ,原因:
2025-2-6 13:01
0
雪    币: 2731
活跃值: (3162)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
还有一点点 的疑惑  大佬 对  __NR_rt_sigaction 和 __NR_prctl   的仿真 我确实 看的不大懂   大佬有相关的文章 吗  ?  我确实 没找到 相关资料
2025-2-6 13:06
0
雪    币: 231
活跃值: (776)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
逆天而行 Tiony.bo 你的内核版本多少?这个是有版本要求的,你可以看初始化函数有内核版本检测,基本上最近几年的系统都应该支持的 我使 ...
这个要做好检测和考虑处理好进程fork的问题
2025-2-13 09:42
0
雪    币: 231
活跃值: (776)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
逆天而行 还有一点点 的疑惑 大佬 对 __NR_rt_sigaction 和 __NR_prctl 的仿真 我确实 看的不大懂 大佬有相关的文章 吗 ? 我确实 没找到 相关资料
这个是为了解决应用的普通检测逻辑不出错,挺简单的实现,实际上各大加固和安全模块检测更为深度,这里只是给出实现思路,所谓商业化还需要花精力实现这部分
2025-2-13 09:43
0
雪    币: 205
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
小白问下这个东西需要手机root吗
2025-2-15 13:52
0
雪    币: 231
活跃值: (776)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
yazigegeda 小白问下这个东西需要手机root吗
不需要,应用级的
2025-2-16 10:34
0
雪    币: 24
活跃值: (1734)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
这个其实会遇到点问题,就是有的App也会注册 SIGSYS的信号监听,不知道 up 有没有遇到过相似的~
2025-2-16 15:12
0
雪    币: 50
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
Tiony.bo 这个是为了解决应用的普通检测逻辑不出错,挺简单的实现,实际上各大加固和安全模块检测更为深度,这里只是给出实现思路,所谓商业化还需要花精力实现这部分
安卓低版本和高版本都不太兼容
2025-2-17 03:17
0
雪    币: 231
活跃值: (776)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
dreameriii 这个其实会遇到点问题,就是有的App也会注册 SIGSYS的信号监听,不知道 up 有没有遇到过相似的~
所以源码里面做了简单的仿真,不干扰APP的正常使用,大家可以继续按照需要完善
2025-2-17 11:34
0
雪    币: 231
活跃值: (776)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
mb_rewimxhj 安卓低版本和高版本都不太兼容
低版本是不支持,高版本肯定没问题的
2025-2-17 11:35
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17

6666666

最后于 2025-2-19 15:48 被xdcs100编辑 ,原因:
2025-2-18 19:04
0
雪    币: 2731
活跃值: (3162)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
18
佬 我看你这个项目里面的app 使用的proot 的源码  我觉得这样的方式很牛 为啥 svcer不使用这样的方式呢?
2025-2-23 10:54
0
雪    币: 231
活跃值: (776)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
逆天而行 佬 我看你这个项目里面的app 使用的proot 的源码 我觉得这样的方式很牛 为啥 svcer不使用这样的方式呢?
项目中包含两种方案,一种是proot,另一种就是现在的svcer
2025-3-7 11:09
1
雪    币: 2731
活跃值: (3162)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
20
Tiony.bo 项目中包含两种方案,一种是proot,另一种就是现在的svcer
多谢解惑
2025-3-7 13:47
0
雪    币: 384
活跃值: (2698)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
21
佬,我用你的项目测试,如果不填ESvcerHookerMode_IgnoreLibc,拦截openat, app必崩,但是我自己尝试用SECCOMP实现,是能正常拦截的,这是有什么bug么,我测试了好几次都这样,忽略libc就正常
1天前
0
游客
登录 | 注册 方可回帖
返回