首页 > 其他分享 >【Abyss】Android 平台应用级系统调用拦截框架

【Abyss】Android 平台应用级系统调用拦截框架

时间:2024-09-19 09:26:52浏览次数:7  
标签:PR Abyss 调用 处理 SYS INTERCEPT Android vpid

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

☞ Github ☜ 

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

01. 说明

tracee:ptrace附加的进程,通常为目标应用进程。

tracer: 用来ptrace其他进程的进程,在该进程里处理系统调用。

本框架利用AndroidProvider组件启动拦截处理的服务进程,进程启动后创建独立的一个线程循环处理所有拦截的系统调用回调。由于本工程只是演示方案的可行性并打印日志,所以业务逻辑处理比较简单,可以根据需要的自行扩展。

若要接入具体业务,可能需要改成多线程的方式进行处理,提升稳定性。不过我们实测多线切换也有一定损耗,性能提升有限,但确实稳定性有提升,防止某个处理耗时导致应用所有进程阻塞。

02. 处理流程

应用进程tracee被附加流程如下:

tracer过程如下:

说明: 使用fork()的目的是为了让工作线程去附加。ptrace有严格的限制,只有执行附加attach的线程才有权限操作对应tracee的寄存器。

03. 系统调用处理

03.01 忽略库机制

由于业务的需要,为了提升性能,我们需要忽略某些库中的系统调用,如:libc.so

find_libc_exec_maps()中找到libc.so可执行代码在maps中的内存地址区间,需要处理的系统调用:

//enable_syscall_filtering()    
FilteredSysnum internal_sysnums[] = {
    { PR_ptrace,		FILTER_SYSEXIT },
    { PR_wait4,		FILTER_SYSEXIT },
    { PR_waitpid,		FILTER_SYSEXIT },
    { PR_execve,		FILTER_SYSEXIT },
    { PR_execveat,		FILTER_SYSEXIT },
    {PR_readlinkat,   FILTER_SYSEXIT}, //暂时没有处理
};

set_seccomp_filters针对不同的arch,设置系统调用的ebpf。不同架构的ebpf语句会填充到一起,ebpf的组成伪代码如下:

for (每一种架构) {
	start_arch_section;
	for (每一个当前架构下的系统调用)
    	add_trace_syscall;
   end_arch_section;
}
finalize_program_filter;

start_arch_section;// 架构相关处理的ebpf,包括libc筛选的语句
add_trace_syscall;// 增加匹配要处理系统调用的ebpf语句
end_arch_section;// 尾部的ebpf语句(语句含义:匹配到系统调用则返回)
finalize_program_filter;// 最后面的ebpf语句,杀死其他异常情况下的线程

最终,调用如下语句,设置ebpf

status = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &program);

03.02 PR_ptrace

因为一个tracee只能有一个tracer,所以需要处理该系统调用,在应用本身使用了ptrace的时候进行仿真。

系统调用进入前,将系统调用替换为PR_void,不做真正的ptrace,后续仿真。

退出系统调用后,针对ptrace的仿真。针对请求是PTRACE_ATTACHPTRACE_TRACEME等做各种不同的处理。同时也处理PTRACE_SYSCALLPTRACE_CONTPTRACE_SETOPTIONSPTRACE_GETEVENTMSG等各种ptrace操作。

ptrace有各种各样的请求,完整的处理逻辑比较复杂(我们还在消化中)。

03.03 PR_wait4、PR_waitpid

配合PR_ptrace使用,如果当前的tracee不是一个tracer,则不处理直接透传给系统。或者wait的第一个参数不为-1,则去集合里找看等待的这个线程是否存在并且是否是当前处理线程的tracee,如果不是,则不处理直接透传给系统。

处理的逻辑如下:

系统调用进入前,将系统调用替换为PR_void,不实际传给内核。

退出系统调用后,仿真tracerwait的处理逻辑。主要为基于当前处理的这个tracer(代码里定义为ptracer),去遍历它的tracee,看是否有事件需要被处理,如有,则填充好寄存器,唤醒当前正在被处理的这个tracer

03.04 PR_execve、PR_execveat

主要是在USE_LOADER_EXE开启时,将native程序替换为使用一个固定的loader来加载程序。

03.05 拦截日志

E INTERCEPT/SYS: vpid 2: got event 7057f
E INTERCEPT: vpid 2,secomp_enabled 0,
E INTERCEPT/SYS: (null) info: vpid 2: sysenter start: openat(0xffffff9c, 0xb4000073c72fcd60, 0x0, 0x0, 0xb4000073c72fcd88, 0xb4000073c72fcde8) = 0xffffff9c [0x7367d45e80, 0]
E INTERCEPT/SYS: vpid 2: open path:/system/fonts/NotoSansMalayalamUI-VF.ttf
E INTERCEPT/SYS: syscall_number:216
E INTERCEPT/SYS: vpid 2,openat: /system/fonts/NotoSansMalayalamUI-VF.ttf
E INTERCEPT/SYS: (null) info: vpid 2: sysenter end: openat(0xffffff9c, 0xb4000073c72fcd60, 0x0, 0x0, 0xb4000073c72fcd88, 0xb4000073c72fcde8) = 0xffffff9c [0x7367d45e80, 0]
E INTERCEPT/SYS: vpid 2: open path:/system/fonts/NotoSansMalayalamUI-VF.ttf
E INTERCEPT/SYS: (null) info: vpid 2: restarted using 7, signal 0, tracee pid 32222,app_pid 32162

E/INTERCEPT/SYS: (null) info: vpid 3: sysenter start: close(0x90, 0x0, 0x7492d0d088, 0x6, 0x73b7b82860, 0x73b7b82880) = 0x90 [0x73633faae0, 0]
E/INTERCEPT/SYS: syscall_number:41
E/INTERCEPT/SYSW: noting to do,sn:41
E/INTERCEPT/SYS: (null) info: vpid 3: sysenter end: close(0x90, 0x0, 0x7492d0d088, 0x6, 0x73b7b82860, 0x73b7b82880) = 0x90 [0x73633faae0, 0]
E/INTERCEPT/SYS: (null) info: vpid 3: restarted using 7, signal 0, tracee pid 32223,app_pid 32162
E/INTERCEPT/SYS: vpid 3: got event 7057f

04. 附

额外模块:

由于本框架会在原应用中增加一个处理进程,并且会trace到应用进程中,因此在实际使用时,还需要对新增进程和trace痕迹进行隐藏,防止与应用检测模块冲突,支持完整的应用自身trace调用的仿真。

这是附加的应用对抗模块,后面会作为单独文章分享给大家。

参考项目:

https://github.com/proot-me/proot

https://github.com/termux/proot

标签:PR,Abyss,调用,处理,SYS,INTERCEPT,Android,vpid
From: https://www.cnblogs.com/iofomo/p/18419810

相关文章

  • Android实践:读取和处理SRTM HGT高程数据文件
            在深入探讨如何在Android应用中读取和处理SRTMHGT高程数据文件之前,我们先对SRTM数据及其格式有一个更全面的了解,并详细探讨每一步的实现细节和最佳实践。一、SRTMHGT数据概述        SRTM(ShuttleRadarTopographyMission)是一项由美国宇航局(NASA)......
  • Android优化:耗电量优化
            在移动应用开发领域,随着智能手机功能的日益强大,用户对电池续航能力的关注也达到了前所未有的高度。Android应用由于其复杂的交互设计、频繁的网络通信、以及多样化的传感器使用,往往成为电量消耗的主要源头。因此,优化Android应用的耗电量,提升电池续航能力,已成为......
  • MySQL 触发器的创建、使用及在 Java 中的调用
    在数据库管理中,MySQL的触发器是一种强大的工具,它可以在特定的数据库事件发生时自动执行一系列操作。同时,我们还可以在Java应用程序中与这些触发器进行交互,实现更复杂的业务逻辑。今天,我们就来一起探讨如何在MySQL中创建和使用触发器,并在Java中调用它们。一、MySQL中创建和......
  • android高程数据如何读取
    在Android中读取高程数据,通常涉及到地理信息系统(GIS)的应用,特别是当你需要处理像SRTM(ShuttleRadarTopographyMission)这样的数据集时。SRTM数据通常是HGT格式的16位整数栅格数据,每个文件代表了特定纬度和经度范围内的高程信息。下面是一些步骤和注意事项,帮助你在Android应用中读......
  • select系统调用(实现I/O复用)
    API在一段指定时间内,监听用户感兴趣的文件描述符上的可读、可写、异常事件。intselect(intnfds,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,structtimeval*timeout);文件描述符集合fd_set是一个用于管理文件描述符集合的结构体。select调用......
  • 大项目函数调用详解
    os.path.relpath是什么os.path.relpath是Python中os.path模块的一个函数,用于获取两个路径之间的相对路径。作用:os.path.relpath(path,start)会返回从start目录到path目录的相对路径。如果不指定start,则默认从当前工作目录计算。path:目标路径,表示你想获取相对路径......
  • Pyhton调用R语言rpy2包概要
    随着深度学习、大数据和AI的发展,Python的热度持续上升,引发了关于选择Python还是R的讨论。作为数据分析工具,两者各有优缺点。在特定领域,如生态学,R仍被广泛应用,而Python则更多用于日常办公自动化,如批量处理文档和Excel。由于数据处理占用了我们大量时间,很多人希望数据分析操作能够集......
  • Ubuntu 64系统编译android arm64-v8a 的openssl静态库libssl.a和libcrypto.a
    #!/bin/bash#Cross-compileenvironmentforAndroidonARM64andx86##ContentslicensedunderthetermsoftheOpenSSLlicense#http://www.openssl.org/source/license.html##Seehttp://wiki.openssl.org/index.php/FIPS_Library_and_Android#andhttp:......
  • 进一步认识系统调用write()和read()
    简介write函数ssize_twrite(intfd,constvoid*buf,size_tcount);fd:文件描述符,表示要写入的文件或设备buf:指向要写入的数据的缓冲区count:要写入的字节数返回值:成功时返回写入的字节数;失败时返回-1read函数ssize_tread(intfd,void*buf,size_tcount);fd:文......
  • 菜鸟笔记之PWN入门(1.1.2)C程序调用过程与函数栈变化(32位 vs 64位)(Intel)
    本文使用Intel的32位为例子进行举例。64位本质上和32位类似,主要区别在于函数参数的调用方式,文章结尾会简要提及。重新回顾一下栈pop和push指令//将0x50的压入栈push0x50//将esp指向的数据放入指定的寄存器中pop寄存器名字比如:popeax执行之后eax的值就变成了0x50......