arm64大约支持280个系统调用,我们平时使用的这些系统调用,到底工作原理是什么,调用后又是到哪里实现的呢,这篇文章初步了解下内核系统调用的流程,并告诉跟踪这个流程的方法。
废话不多说,如上就是linux的系统调用关系图:
1.绝大部分用户态系统调用接口,都经过glibc库,最终到内核是sys_xx实现函数完成功能并返回用户态;
2.少量glibc不支持的API可通过其他方式直接到内核sys_xx实现函数完成功能并返回用户态;
3.存在少量系统调用glibc内部实现,但是实现流程使用内核关键函数,比如malloc;
举例说明如何跟踪
open()函数
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void main()
{open("xx", O_CREAT);
}
以上是open的系统调用,可以使用gcc open.c -o open命令编译成二进制。
ldd open
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f53081a5000)
从上可知最终到系统libc库
查看libc库的open:
nm -D /lib/x86_64-linux-gnu/libc.so.6 |grep open
00000000000f7030 W open
00000000000f7030 W __open
接下来需要下载glibc库的源码,然后
git checkout glibc-2.9
vim io/open.cint
__open (file, oflag)const char *file;int oflag;
{int mode;if (file == NULL){__set_errno (EINVAL);return -1;}if (oflag & O_CREAT){va_list arg;va_start(arg, oflag);mode = va_arg(arg, int); va_end(arg);}__set_errno (ENOSYS);return -1;
}
如何glibc库经过初步的参数检查,会调用到内核的系统调用sys_open()
->include/linux/syscalls.h
->sys_open -> do_sys_open
->fs/open.c
->long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
系统调用 malloc
cat test.c
#include <stdio.h>
#include <malloc.h>void main()
{void *c = (void*)malloc(10);free(c);
}
如上
ldd test
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f53081a5000)nm -D /lib/x86_64-linux-gnu/libc.so.6 |grep malloc
0000000000084130 T __libc_malloc
0000000000084130 T malloc
glibc源码中
find . -name malloc.c
./malloc/malloc.c
具体malloc在glibc的功能实现可以查看如下博客,我这里不再详细说明,毕竟不深究这块。https://introspelliam.github.io/2018/05/21/pwn/malloc%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E2%80%94_int_malloc/
PS:近期太忙,没时间写博客了~~~~~