首页
社区
课程
招聘
[原创]【从源码过反调试】中间篇-给安卓12内核增加个syscall
发表于: 2022-11-25 16:09 20987

[原创]【从源码过反调试】中间篇-给安卓12内核增加个syscall

2022-11-25 16:09
20987

在给android 12增加个syscall,没想到这里面涉及东西还挺多的,网上的东西都太老古董了(尤其是bionic这里),中间踩了不少坑。单独开篇帖子记录下怎么给android 12添加个syscall。(现在依旧还是有问题,printk的日志dmesg看不到)
环境:lineageos 19.1
编译环境:Ubuntu 20.04

############
实际上我操作的顺序是本篇倒着来的,正序写比较方便观看

############

bionic调用gensyscall.py,从SYSCALL.TXT中读文件,判断哪些函数要生成syscall的汇编指令
图片描述
图片描述
在unistd.h中添加syscall id,跟着别的写就行了,sys_antidebug_update是linux内核自定义函数,下面会提到
图片描述
比如我在这里加了__antidebug_update函数,将会调用linux内核里的antidebug_update函数,在arm64架构下的。
这句话的含义
return_type func_name[|alias_list]:syscall_name[:socketcall_id] arch_list

生成的结果在
图片描述
图片描述

生成了这个函数的汇编,就可以在代码里以extern c的方式直接调用__antidebug_update函数(其实就是syscall),我这里不想改makefile直接用了一个现成的内核cpp。
图片描述
然后添加libc的导出符号,在这个路径下,编译即可直接调用libc的函数实现封装好的syscall
图片描述
bionic工具生成的map文件在这里能看到
图片描述

syscall的编号_NR_xxx在bionic里面是从external\kernel-headers\original\uapi\asm-generic\unistd.h拷贝过来的,所以要改这个文件,直接改include下的是没用的。这里我加了限定arm64生成syscall的宏,在下面linux内核里要做同样的限定。
图片描述

如果不想给arm的libc导出自己的函数,只想在arm64导出,函数声明这里一定要加上预编译宏。我在unistd.h里已经加了限定arm64架构才会生成antidebug_update的宏,这里如果不加,bionic那么就会尝试arm架构的antidebug_update syscall汇编,因为找不到而报错。

图片描述
后面再user层就可以先用extern c 声明下 aadebug,然后直接调用了。

先看异常分发,kernel\xiaomi\sm8250\arch\arm64\kernel\entry.S
调用syscall会产生中断,在arm64的汇编是svc,中断产生异常后,进入svc handler
图片描述
在kernel\xiaomi\sm8250\arch\arm64\kernel\syscall.c下,我复制一段关键代码

总结起来就一句话,

编译时生成syscall_table,根据id索引到handler的地址(所以hook syscall函数可以直接替换这个syscall_table[id]寻址得到的函数地址,主要是要找到syscall_table的地址,和call回原函数处理)
所以要添加个syscall,就需要做两件事,定义个handler(SYSCALL_DEFINEx 宏包起来的声明,x是参数数量,具体看其他函数实现就知道了),增加个NR_ID(如果上面第1点也做了需要bionic的NR_ID和linux的NR_ID一致)并声明syscall。

添加完后build编译不报错,刷机,这里可以直接写个demo验证下
图片描述
用 aarch64-linux-gnu-gcc 编译(ubuntu 可以直接apt装arm的交叉编译工具),不要忘记-static选项,刷机到手机上运行下,可以看到函数逻辑是走了的。
传入参数123,return 123+100 ,所以syscall没有问题。
图片描述
但我就是看不到printk打的日志去哪了,打算封装个函数把日志写到文件去了。
unistd.h到处都是,看的人都晕了...

修改源码重新编译,时间成本比较大,安装驱动(.ko)是比较常用的了,有需要就syscall hook下,毕竟扩展性比较好,我也试过,内核编译选项把强制校验签名关了,可以随便安装未签名的驱动了,但同样是printk打不出来日志。不过自己的环境定制内核还是最方便的,本着目的就是“一劳永逸”。

 
 
# <sys/resource.h>
int __antidebug_update:antidebug_update(pid_t) arm64
int getrusage(int, struct rusage*all
int __getpriority:getpriority(int, id_t)  all
# <sys/resource.h>
int __antidebug_update:antidebug_update(pid_t) arm64
int getrusage(int, struct rusage*all
int __getpriority:getpriority(int, id_t)  all
 
 
asmlinkage void el0_svc_handler(struct pt_regs *regs)
{
    sve_user_discard();
    el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table);
}
 
static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
               const syscall_fn_t syscall_table[])
{   
    unsigned long flags = current_thread_info()->flags;
 
    regs->orig_x0 = regs->regs[0];
    regs->syscallno = scno;
 
        ...
    invoke_syscall(regs, scno, sc_nr, syscall_table);
        ...
}
static long __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
{
    return syscall_fn(regs);
}
 
static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
               unsigned int sc_nr,
               const syscall_fn_t syscall_table[])
{
    long ret;
    if (scno < sc_nr) {
        syscall_fn_t syscall_fn;
        syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
        ret = __invoke_syscall(regs, syscall_fn);
    } else {
        ret = do_ni_syscall(regs, scno);
    }
 
    regs->regs[0] = ret;
}
asmlinkage void el0_svc_handler(struct pt_regs *regs)
{
    sve_user_discard();
    el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table);
}
 
static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
               const syscall_fn_t syscall_table[])
{   
    unsigned long flags = current_thread_info()->flags;
 
    regs->orig_x0 = regs->regs[0];

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

最后于 2022-11-25 16:20 被xxxlion编辑 ,原因:
收藏
免费 6
支持
分享
最新回复 (3)
雪    币: 1657
活跃值: (924)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
yyds
2023-1-10 21:52
0
雪    币: 27
活跃值: (1638)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
tql,我这菜鸟只希望有个rom可以刷
2023-1-13 04:09
0
雪    币: 2055
活跃值: (418)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
菜鸟还要加倍学习!
2023-1-13 09:24
0
游客
登录 | 注册 方可回帖
返回
//