跟踪分析Linux内核5.0系统86号调用处理过程

跟踪分析Linux内核5.0系统86号调用处理过程


学号末位:186
原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/

实验背景

跟踪分析Linux内核5.0系统调用处理过程
选择系统调用号后两位与学号后两位相同的系统调用进行跟踪分析
分析系统调用、保护现场与恢复现场、系统调用号及参数传递过程

实验步骤

1.安装配置Linux5.0.1内核

  1. 官网下载Linux5.0.1内核,解压到/usr/linux-5.0.1目录下;

Linux内核

  1. 配置内核编译参数:

sudo make menuconfig;配置内核编译参数

  1. 编译内核

make -j8;
完成界面

  1. 制作根文件系统;

mkdir ~/LinuxKernel
cd ~/LinuxKernel/
mkdir rootfs
git clone https://github.com/mengning/menu.git
cd menu/
gcc -o init linktable.c menu.c test.c -m32 -static -pthread
cd …/rootfs/
cp …/menu/init .
find . | cpio -o -Hnewc |gzip -9 > …/rootfs.img

  1. 启动MenuOS:

qemu-system-i386 -kernel bzImage -initrd rootfs.img;

启动MenuOS

  1. 跟踪调试内核启动

qemu-system-i386 -kernel bzImage -initrd rootfs.img -S -s -append nokaslr;

  1. 建立与qemu调试端口的attach

cd Desktop/linux-5.0.1
gdb
(gdb)file vmlinux
(gdb)target remote:1234
(gdb)break start_kernel
(gdb) c建立与qemu调试端口的attach

  1. 开始跟踪系统调用。

2.跟踪系统调用

  1. 如图所示,学号尾数186对应的86号系统调用函数为uselib:

系统调用

  1. 函数int uselib(const char *library),功能是选择要使用的二进制函数库

系统调用uselib()用于加载要使用的共享库
通过调用进程。它有一个路径名。地址在哪里
在库本身中找到要加载的。库可以有任何
可识别的二进制格式。
uselib

  1. 在test.c中添加代码块

在test.c中添加代码块

  1. 对uselib在gdb中进行断点运行

因为在断点执行中发生了堆栈的入栈出栈,多处函数的跳转与引用,此处仅列出部分调用。在这里插入图片描述
堆栈相关
堆栈中跳转到内核相关地址,调用函数

  1. 相关代码

SYSCALL_DEFINE1(uselib, const char __user *, library)
{
struct linux_binfmt *fmt;
struct file *file;
struct filename *tmp = getname(library);
int error = PTR_ERR(tmp);
static const struct open_flags uselib_flags = {
.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
.acc_mode = MAY_READ | MAY_EXEC,
.intent = LOOKUP_OPEN,
.lookup_flags = LOOKUP_FOLLOW,
};
if (IS_ERR(file))
goto out;
error = -EINVAL;
if (!S_ISREG(file_inode(file)->i_mode))
goto exit;
error = -EACCES;
if (path_noexec(&file->f_path))
goto exit;
fsnotify_open(file);
error = -ENOEXEC;
read_lock(&binfmt_lock);
list_for_each_entry(fmt, &formats, lh) {
if (!fmt->load_shlib)
continue;
if (!try_module_get(fmt->module))
continue;
read_unlock(&binfmt_lock);
error = fmt->load_shlib(file);
read_lock(&binfmt_lock);
put_binfmt(fmt);
if (error != -ENOEXEC)
break;
}
read_unlock(&binfmt_lock);
exit:
fput(file);
out:
return error;
}

  1. 实验总结
    1.系统调用uselib()用于加载调用进程要使用的共享库。它有一个路径名。要加载的地址在库本身中找到。库可以具有任何可识别的二进制格式。
    2.uselib()是特定用于Linux的,不在打算移植的程序中使用。早期libc启动代码使用uselib()加载共享库,在二进制文件的名称数组中找到名称。自libc 4.3.2以来,启动代码放弃尝试在这些名称前面加上“/usr/lib”、“/lib”和“”。在libc 4.3.4和更高版本中,这些名称在ld_library_path中的目录中查找,如果没有找到,则尝试使用前缀“/usr/lib”、“/lib”和“/”
    3.系统调用通常通过函数进行调用,它们通常都需要定义一个或几个参数。系统调用通常会通过一个long类型的返回值来表示成功或者错误

致谢

本文完成于2019.3.19日,谢谢观看。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值