【问题标题】:Assembly on Minix在 Minix 上组装
【发布时间】:2014-03-16 07:35:10
【问题描述】:

我已经在 Windows7 64 位的 VMWare 中安装了 Minix 3。我正在尝试在此 VM 上练习组装。刚开始,我尝试了一个简单的程序将数字加载到 eax 和 ebx 并调用 o/s 来终止程序。

.globl _start:
.section .text
_start:
movl $1, %eax
movl $0, %ebx
int $0x80

编译器和链接器不会引发任何错误或警告,但是当我运行可执行文件时,我会得到

PM: coredump signal 11 for 282 / <program name>
memory fault

这是由于主机是 64 位机器造成的吗?是因为 minix 有不同的 o/s 调用吗?我已经尝试在网上专门搜索 minix o/s 调用,我找到了特定 o/s 调用的解决方案,但没有 o/s 调用表。有人可以在这里指出我正确的方向吗?

【问题讨论】:

  • 我猜你的意思是“来自 i386 Linux 的不同系统调用”,因为这就是 int 0x80 /​​ eax=1 将调用 sys_exit 的地方。

标签: assembly x86 minix


【解决方案1】:

给你:

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 来实现的:

通过一些逆向工程来解决这个问题

看看像/bin/cat 这样的简单静态链接可执行文件如何在Minix 上实现_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 汇编程序转储结束。

【讨论】:

  • 这就是 Linus 讨厌 MINIX 的原因。
  • @mcandre:天哪,如果大多数 Minix 代码编译成这样的话,我也会从头开始编写自己的操作系统。系统调用是否真的需要将堆栈对齐 16,或者这是编译器设置的产物,例如 libc 的 -mpreferred-stack-boundary=4 -mincoming-stack-boundary=2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-17
  • 1970-01-01
相关资源
最近更新 更多