Linux系统调用跟踪分析

林弋力
224
原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/

实验目的

选择系统调用进行分析
理解系统调用工作机制

实验步骤

下载并编译内核

wget wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.2tar.xz

xz -d linux-5.0.2.tar.xz

tar -xvf linux-5.0.2.tar 

git clone https://github.com/mengning/menu.git

安装编译工具

sudo apt install build-essential flex bison libssl-dev libelf-dev   libncurses-dev

配置内核

cd linux-5.0.2
make i386_defconfig
make menuconfig
make -j 8

在这里插入图片描述

cd ../menu

进入Menu目录,修改Makefile文件
将内核版本改为对应的版本
编译make rootfs 生成一个镜像文件 rootfs.img
启动该镜像

qemu-system-i386 -kernel arch/x86/boot/bzImage -initrd rootfs.img

在这里插入图片描述

跟踪系统调用分析

qemu-system-i386 -kernel linux-5.0.2/arch/x86/boot/bzImage -initrd rootfs.img -S -s -append nokaslr
cd linuxkernel/linux-5.0.2

gdb

(gdb)vmlinux

(gdb) target remote:1234

在这里插入图片描述
跟踪分析的系统调用为24:getuid

跟踪测试函数

//getuid.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char const *agrv[])
{
    uid_t uid;
    uid=getuid();
    printf("The current user ID:%d\n",uid);

    return 0;
}

测试结果:
在这里插入图片描述
使用嵌入汇编的方式把系统调用展示如图:
在这里插入图片描述
可以看出,系统调用执行了内核的封装例程。
用户进程只需要把相应的调用号放入eax寄存器,内核就在内核态完成相应的计算,把用户所要求的结果返给用户进程,参与其他运算。

实验总结

当调用一个系统调用时,CPU从用户态切换到内核态并执行一个system_call和系统调用内核函数。在Linux中通过执行int 0x80来触发系统调用,内核为每个系统调用分配一个系统调用号,用户态进程必须明确指明系统调用号,并使用EAX寄存器来传递。
系统调用可能需要参数,但是不能通过像用户态进程函数中将参数压栈的方式传递,因为用户态和内核态有不同的堆栈,必须使用寄存器EBX、ECX、EDX、ESI、EDI、EBP来传递参数。若参数较多,则把指向内存的指针存入寄存器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值