【问题标题】:assembly system call non-effective汇编系统调用无效
【发布时间】:2016-10-14 10:54:47
【问题描述】:

我想用以下内容打印 AAAA:

BITS 32;

;write;
 push 0x41414141;
 pop ecx        ;
 mov eax, 4     ; write is syscall 4 for Ubuntu 32-bit
 mov ebx, 1     ; stdout
 mov edx, 4     ;
 int 0x80       ;

;exit;
 mov eax, 1     ;
 mov ebx, 0     ;
 int 0x80       ;

然而,一旦组装和链接,这段代码只会退出,没有错误,有什么问题?

【问题讨论】:

  • int 80h 通话使用了哪些文档?它对ecx 论点说了什么? (顺便说一句,在汇编中“;”的意思是“评论”..你为什么在每一行都放空评论?..你不必)
  • ecx 应该包含一个指向字符串的指针。 0x80 表示高于 ascii 限制一位,因此进入操作系统。
  • 0x80 值是 128,如您所说,超出了经典的 7 位 ASCII。但这对int 指令没有任何影响,它可以为从 0 到 255 的任何 8 位数字调用中断过程(int 3 还具有特殊的专用单字节操作码,由调试器用于断点),不关心它与ASCII的关系。它关心的是中断向量表,其中元素 [0x80] 处的地址必须指向某个有效的处理程序(在这种情况下,我想是 linux OS)。如果 Linux 将使用 0x41 处理程序,您将改为使用int 'A'...:D
  • int 80h 是 Linux 系统调用。将 4 放入 EAX 告诉由中断调用的系统调用执行 SYS_WRITE 函数(ebx 充当要写入的文件句柄,ecx 充当指向要写入的内存的指针,edx 充当要写入的字节)。我不知道 ASCII 表是如何参与其中的,除非是一个有趣的事实。
  • 当一个键被按下时,电流会进入 cpu 上的相应引脚,cpu 根据纳米电路所遵循的路径,将比特流排列到寄存器中。第 8 位超出了 ascii 范围,所以当我得知它是系统调用时,0x80 让我印象深刻。我刚刚完成了一本名为“黑客,利用的艺术”的书,其中解释了有关堆栈和寄存器的许多内容,但仍然有很多困惑需要解决。顺便说一句,我可以让代码工作。再见。

标签: assembly x86 system-calls 32-bit


【解决方案1】:

快速修复您的代码:

push 0x41414141 ; put 'AAAA' into stack memory
mov ecx,esp     ; pointer to the 'AAAA'
mov eax, 4      ; write is syscall 4 for 32-bit Linux
mov ebx, 1      ; stdout
mov edx, 4
int 0x80
add esp,4      ; restore stack

没有解释,因为您应该首先检查我在评论中提出的问题,然后修复将是显而易见的,或者您将不得不询问一些您不了解的特定问题...

如果您使用 strace ./my_program 运行原始代码,您会看到 write() return -EFAULT,因为您传递了错误的地址。始终使用strace 来调试进行系统调用且行为不符合您预期的程序。

【讨论】:

  • 谢谢,我忘记了指针和它所产生的区别,这很明显。
猜你喜欢
  • 2016-01-16
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 2018-10-01
相关资源
最近更新 更多