干得好:
minix-exit.S
.section .text
.global _start
_开始:
/* _exit(17) */
和 $0xfffffff0, %esp
低于 $0x40, %esp
movl $17, 0x18(%esp) /* 退出状态 */
lea 0x10(%esp), %ebx
movl $1, 0x04(%ebx) /* 在 include/minix/callnr.h 中退出 */
movl $0, %eax /* PM_PROC_NR in include/minix/com.h */
movl $0x3, %ecx /* SENDREC in include/minix/ipcconst.h */
int $33 /* sys/arch/i386/include/asm.h 中的 IPCVEC_ORIG */
构建并运行:
$ clang -nostdlib minix-exit.S -o minix-exit
$ ./minix-退出;回声$?
17
我发现弄清楚 Minix 3 的系统调用实现的最简单方法是在阅读代码之前进行一些逆向工程:
调用顺序
Minix 作为一个微内核,坚持将系统调用结构化为可以发送给不同管理器的消息。exit()
通过发送EXIT
到PM_PROC_NR
:
通过一些逆向工程来解决这个问题
看看一个简单的静态链接可执行文件是如何在 Minix 上/bin/cat
实现的。_exit()
dis.gdb
设置分页 0
文件 /bin/cat
设置登录
反汇编_exit
反汇编_syscall
x/a 0x8072678
反汇编_sendrec_orig
退出
跑:
gdb -q -x dis.gdb
GDB 输出
函数_exit的汇编代码转储:
0x0805b780 : 推送 %ebp
0x0805b781 : 移动 %esp,%ebp
0x0805b783 : 和 $0xfffffff0,%esp
0x0805b789 : 低于 $0x40,%esp
0x0805b78c : 移动 0x8(%ebp),%eax
0x0805b78f : 移动 %eax,0x18(%esp)
0x0805b793 : lea 0x10(%esp),%eax
0x0805b797 : 移动 %eax,0x8(%esp)
0x0805b79b : 移动 $0x1,0x4(%esp)
0x0805b7a3 : 移动 $0x0,(%esp)
0x0805b7aa : 调用 0x805dfc0
0x0805b7af : 调用 0x805b7af
0x0805b7b4 : nopw %cs:0x0(%eax,%eax,1)
0x0805b7c0 : jmp 0x805b7c0
汇编程序转储结束。
函数系统调用的汇编代码转储:
0x0805dfc0 : 推送 %ebp
0x0805dfc1 : 移动 %esp,%ebp
0x0805dfc3 : 推送 %esi
0x0805dfc4 : sub $0xc,%esp
0x0805dfc7 : 移动 0xc(%ebp),%eax
0x0805dfca : 移动 0x10(%ebp),%esi
0x0805dfcd : 移动 %eax,0x4(%esi)
0x0805dfd0 : 移动 %esi,0x4(%esp)
0x0805dfd4 : 移动 0x8(%ebp),%ecx
0x0805dfd7 : 移动 %ecx,(%esp)
0x0805dfda : 调用 *0x8072678
0x0805dfe0 : 测试 %eax,%eax
0x0805dfe2 : 0x805dfe9
0x0805dfe4 : 移动 %eax,0x4(%esi)
0x0805dfe7 : jmp 0x805dfec
0x0805dfe9 : 移动 0x4(%esi),%eax
0x0805dfec : 测试 %eax,%eax
0x0805dfee : jns 0x805e000
0x0805dff0 : 移动 %eax,%esi
0x0805dff2 : 否定 %esi
0x0805dff4 : 调用 0x805e010
0x0805dff9 : 移动 %esi,(%eax)
0x0805dffb : 移动 $0xffffffff,%eax
0x0805e000 : 添加 $0xc,%esp
0x0805e003 : 弹出 %esi
0x0805e004 : 弹出 %ebp
0x0805e005 : 回复
汇编程序转储结束。
0x8072678:0x805e100
函数 _sendrec_orig 的汇编代码转储:
0x0805e100 : 推送 %ebp
0x0805e101 : 移动 %esp,%ebp
0x0805e103 : 推送 %ebx
0x0805e104 : 移动 0x8(%ebp),%eax
0x0805e107 : 移动 0xc(%ebp),%ebx
0x0805e10a : 移动 $0x3,%ecx
0x0805e10f : 整数 $0x21
0x0805e111 : 弹出 %ebx
0x0805e112 : 弹出 %ebp
0x0805e113 : 恢复
0x0805e114 : lea 0x0(%esi),%esi
0x0805e11a : lea 0x0(%edi),%edi
汇编程序转储结束。