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

由于我们虚拟化产品的需求,需要支持在普通的Android手机运行。我们需要搭建覆盖应用从上到下各层的应用级拦截框架,而Abyss作为系统SVC指令的调用拦截,是我们最底层的终极方案。
01. 说明
tracee: 被ptrace附加的进程,通常为目标应用进程。
tracer: 用来ptrace其他进程的进程,在该进程里处理系统调用。
本框架利用Android的Provider组件启动拦截处理的服务进程,进程启动后创建独立的一个线程循环处理所有拦截的系统调用回调。由于本工程只是演示方案的可行性并打印日志,所以业务逻辑处理比较简单,可以根据需要的自行扩展。
若要接入具体业务,可能需要改成多线程的方式进行处理,提升稳定性。不过我们实测多线切换也有一定损耗,性能提升有限,但确实稳定性有提升,防止某个处理耗时导致应用所有进程阻塞。
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_ATTACH、PTRACE_TRACEME等做各种不同的处理。同时也处理PTRACE_SYSCALL、PTRACE_CONT、PTRACE_SETOPTIONS、PTRACE_GETEVENTMSG等各种ptrace操作。
ptrace有各种各样的请求,完整的处理逻辑比较复杂(我们还在消化中)。
03.03 PR_wait4、PR_waitpid
配合PR_ptrace使用,如果当前的tracee不是一个tracer,则不处理直接透传给系统。或者wait的第一个参数不为-1,则去集合里找看等待的这个线程是否存在并且是否是当前处理线程的tracee,如果不是,则不处理直接透传给系统。
处理的逻辑如下:
系统调用进入前,将系统调用替换为PR_void,不实际传给内核。
退出系统调用后,仿真tracer里wait的处理逻辑。主要为基于当前处理的这个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
【Abyss】Android 平台应用级系统调用拦截框架的更多相关文章
- (转)android平台phonegap框架实现原理
(原文)http://blog.csdn.net/wuruixn/article/details/7405175 android平台phonegap框架实现原理 分类: Android2012-03- ...
- Android平台免Root无侵入AOP框架Dexposed使用详解
Dexposed是基于久负盛名的开源Xposed框架实现的一个Android平台上功能强大的无侵入式运行时AOP框架. Dexposed的AOP实现是完全非侵入式的,没有使用任何注解处理器,编织器或者 ...
- Android平台利用OpenCL框架实现并行开发初试
http://www.cnblogs.com/lifan3a/articles/4607659.html 在我们熟知的桌面平台,GPU得到了极为广泛的应用,小到各种电子游戏,大到高性能计算,多核心.高 ...
- Android平台dalvik模式下java Hook框架ddi的分析(2)--dex文件的注入和调用
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/77942585 前面的博客<Android平台dalvik模式下java Ho ...
- Android平台dalvik模式下java Hook框架ddi的分析(1)
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/75710411 一.前 言 在前面的博客中已经学习了作者crmulliner编写的, ...
- Android 快速开发框架:推荐10个框架:afinal、ThinkAndroid、andBase、KJFrameForAndroid、SmartAndroid、dhroid..
对于Android初学者以及对于我们菜鸟,这些大神们开发的轻量级框架非常有用(更别说开源的了). 下面转载这10个框架的介绍:(按顺序来吧没有什么排名). 一. Afinal 官方介绍: Afina ...
- 随笔之Android平台上的进程调度探讨
http://blog.csdn.net/innost/article/details/6940136 随笔之Android平台上的进程调度探讨 一由来 最近在翻阅MediaProvider的时候,突 ...
- [置顶] 深入理解android之IPC机制与Binder框架
[android之IPC机制与Binder框架] [Binder框架.Parcel.Proxy-Stub以及AIDL] Abstract [每个平台都会有自己一套跨进程的IPC机制,让不同进程里的两个 ...
- 【流媒体开发】VLC Media Player - Android 平台源码编译 与 二次开发详解 (提供详细800M下载好的编译源码及eclipse可调试播放器源码下载)
作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42707293 转载请注明出处 : http://blog.csd ...
- Android 平台 Native 代码的崩溃捕获机制及实现
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/g-WzYF3wWAljok1XjPoo7w 一.背景 ...
随机推荐
- Nuxt.js头部魔法:轻松自定义页面元信息,提升用户体验
扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长 useHead 函数概述 useHead是一个用于在 Nuxt 应用中自定义页面头部属性的函数.它由Unhead库提供支持,允许开发者以编 ...
- Prometheus 基于Python Django实现Prometheus Exporter
基于Python Django实现Prometheus Exporter 需求描述 运行监控需求,需要采集Nginx 每个URL请求的相关信息,涉及两个指标:一分钟内平均响应时间,调用次数,并且为每个 ...
- ABC347
A link 很简单 遍历,判断模\(k\)是否为\(0\),如果为\(0\),输出\(a_i/k\). 点击查看代码 #include<bits/stdc++.h> using name ...
- 关于@Mapper与@MapperScan
o.m.s.mapper.ClassPathMapperScanner : Skipping MapperFactoryBean with name 'gggDao' and 'com.xxx.dao ...
- RESTful服务与swagger
一开始刚学springboot的时候 restful服务+swagger一点都看不懂,现在知识学了一些,再回头看这些东西就简单很多了. 自己跟视频做了一个零件项目,里面写了一些零零散散的模块,其中在视 ...
- python获取引用对象的个数
python获取引用对象的个数 使用sys.getrefcount()来获取当前对象被引用了多少次,返回的结果比实际大1 import sys class A: pass a = A() #创建实例对 ...
- HIC simple process
1,什么是Hic数据? Hi-C是研究染色质三维结构的一种方法.Hi-C技术源于染色体构象捕获(Chromosome Conformation Capture, 3C)技术,利用高通量测序技术,结合生 ...
- 7月24号python:库存管理
7月24号python:库存管理 题目: 仓库管理员以数组 stock 形式记录商品库存表.stock[i] 表示商品 id,可能存在重复.原库存表按商品 id 升序排列.现因突发情况需要进行商品 ...
- 【PostgreSQL】01 环境搭建
[PostgreSQL数据库安装] 数据库本体就没下本机了,直接挂服务器的Docker上面跑 docker pull postgres:9.4 创建容器并运行: docker run --name p ...
- ubuntu系统grub修复(win+ubuntu双系统环境),修复无法启动问题 boot-repair
相关: https://help.ubuntu.com/community/Boot-Repair ================================================== ...