标签:require pts sso for 存储器 new 记录 rap roc
[toc]
- 找一个系统调用,系统调用号为学号最后2位相同的系统调用(我的学号尾号为66,故记录66号调用)
- 通过汇编指令触发该系统调用
- 通过gdb跟踪该系统调用的内核处理过程
- 重点阅读分析系统调用入口的保存现场、恢复现场和系统调用返回,以及重点关注系统调用过程中内核堆栈状态的变化
写一篇博客记录实验过程并总结分析系统调用的工作机制。
发行版本:Ubuntu 18.04.4 LTS
处理器:Intel? Core? i7-8850H CPU @ 2.60GHz × 3
图形卡:Parallels using AMD? Radeon pro 560x opengl engine
GNOME:3.28.2
sudo apt install build-essential
sudo apt install qemu # install QEMU
sudo apt install libncurses5-dev bison flex libssl-dev libelf-dev
# 下载
sudo apt install axel
axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.34.tar.xz
xz -d linux-5.4.34.tar.xz
tar -xvf linux-5.4.34.tar
#配置
make defconfig #Default configuration is based on ‘x86_64_defconfig‘
make menuconfig
#打开debug相关选项
Kernel hacking --->
Compile-time checks and compiler options --->
[*] Compile the kernel with debug info
[*] Provide GDB scripts for kernel debugging [*] Kernel debugging
#关闭KASLR,否则会导致打断点失败
Processor type and features ---->
[] Randomize the address of the kernel image (KASLR)
make -j$(nproc)
# 测试?下内核能不能正常加载运?,因为没有?件系统终会kernel panic
qemu-system-x86_64 -kernel arch/x86/boot/bzImage # 此时应该不能正常运行
4. 制作根文件系统
# 下载
axel -n 20 https://busybox.net/downloads/busybox-1.31.1.tar.bz2
tar -jxvf busybox-1.31.1.tar.bz2
#配置
cd busybox-1.31.1
make menuconfig
# 记得要编译成静态链接,不用动态链接库。
Settings --->
[*] Build static binary (no shared libs)
# 然后编译安装,默认会安装到源码目录下的 _install 目录中。
make -j$(nproc) && make install
1 mkdir rootfs
2 cd rootfs
3 cp ../busybox-1.31.1/_install/* ./ -rf
4 mkdir dev proc sys home
5 sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} dev/
1 #!/bin/sh
2 mount -t proc none /proc mount -t sysfs none /sys
3 echo "Wellcome MengningOS!"
4 cd home
5 /bin/sh
1 chmod +x init
1 find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
1 qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz
asm volatile(
"movq %1, %%rdi\n\t" // 将第一个参数放入 rdi 寄存器
"movq %2, %%ecx\n\t" // 将第二个参数放入 ecx 寄存器
"movq %3, %%ebx\n\t" // 将第三个参数放入 ebx 寄存器
"movq %4, %%rsi\n\t" // 将第四个参数放入 rsi 寄存器
"movl $0x42, %eax\n\t" //传递系统调用号
"syscall\n\t" //系统调用
"movq %%rax, %0\n\t" // 将函数处理结果返回给 res 变量中
:"=m"(res)
:"a"(&x), "b"(&y),"c"(&z),"d"(&k)
);
gcc testSemctl.c -o testSemctl -static
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
1 qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz -S -s -nographic -append "console=ttyS0"
cd linux-5.4.34
# 启动
gdb vmlinux
target remote:1234
# 在semctl调用处打断点
b __x64_sys_semctl
SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg)
{
return ksys_semctl(semid, semnum, cmd, arg, IPC_64);
}
#ifdef CONFIG_X86_64
__visible void do_syscall_64(unsigned long nr, struct pt_regs *regs)
{
struct thread_info *ti;
enter_from_user_mode();
local_irq_enable();
ti = current_thread_info();
if (READ_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY)
nr = syscall_trace_enter(regs);
if (likely(nr < NR_syscalls)) {
nr = array_index_nospec(nr, NR_syscalls);
regs->ax = sys_call_table[nr](regs);
#ifdef CONFIG_X86_X32_ABI
} else if (likely((nr & __X32_SYSCALL_BIT) &&
(nr & ~__X32_SYSCALL_BIT) < X32_NR_syscalls)) {
nr = array_index_nospec(nr & ~__X32_SYSCALL_BIT,
X32_NR_syscalls);
regs->ax = x32_sys_call_table[nr](regs);
#endif
}
syscall_return_slowpath(regs);
}
#endif
/*
* Try to use SYSRET instead of IRET if we‘re returning to
* a completely clean 64-bit userspace context. If we‘re not,
* go to the slow exit path.
*/
movq RCX(%rsp), %rcx
movq RIP(%rsp), %r11
cmpq %rcx, %r11 /* SYSRET requires RCX == RIP */
jne swapgs_restore_regs_and_return_to_usermode
系统调?的执?,也就是?户程序触发系统调?之后,CPU及内核执?系统调? 的过程
int $0x80是CPU压栈?些关键寄存器,接着内核负责保存现场,系统调?内核 函数处理完后恢复现场,最后通过iret出栈哪些CPU压栈的关键寄存器。
sysenter和syscall都借助CPU内部的MSR寄存器来查找系统调?处理??,可 以快速切换CPU的指令指针(eip/rip)到系统调?处理??,但本质上还是中 断处理的思路,压栈关键寄存器、保存现场、恢复现场,最后系统调?返回。
x86-64引?了swapgs指令,类似快照的?式将保存现场和恢复现场时的CPU寄 存器也通过CPU内部的存储器快速保存和恢复,近?步加快了系统调?。
标签:require pts sso for 存储器 new 记录 rap roc
原文地址:https://www.cnblogs.com/femery/p/12965576.html