一尘不染

Linux 64位中的进程命令行

linux

我从Linux 64位汇编程序访问进程命令行时遇到问题。为了用最少的代码重现该代码,我制作了一个32位程序,该程序打印程序名的前5个字符:

.section .text

.globl _开始
_开始:
 move%esp,%ebp

 movl $ 4,%eax#写
 movl $ 1,%ebx#stdout
 movl 4(%ebp),%ecx#程序名称地址(argv [0])
 movl $ 5,%edx#硬编码长度
 整数$ 0x80

 movl $ 1,%eax
 movl $ 0,%ebx
 整数$ 0x80

该程序正在运行。当我将其转换为64位并在Linux 64上运行时,它不会显示任何内容:

.section .text

.globl _开始
_开始:
 movq%rsp,%rbp

 movq $ 4,%rax
 movq $ 1,%rbx
 movq 8(%rbp),%rcx#程序名称地址
 movq $ 5,%rdx
 整数$ 0x80

 movq $ 1,%rax
 movq $ 0,%rbx
 整数$ 0x80

我的错误在哪里?


阅读 321

收藏
2020-06-07

共1个答案

一尘不染

您正在将正确的地址加载到中%rcx

int 0x80然后调用32位syscall接口。这会将地址截断为32位,这使它不正确。(如果您使用调试器并在第一个调试器之后设置一个断点int 0x80,则会看到它返回-14 in %eax,即-EFAULT。)

第二个syscall exit可以正常工作,因为在这种情况下,截断为32位不会造成任何损害。


如果要将64位地址传递给系统调用,则必须使用64位syscall接口:

  • 使用syscall而不是int 0x80;
  • 使用了不同的寄存器:请参见此处
  • 系统电话号码也不同:请参见此处

这是您的代码的有效版本:

.section .text

.globl _start
_start:
 movq  %rsp, %rbp

 movq $1, %rax
 movq $1, %rdi
 movq 8(%rbp), %rsi       # program name address ?
 movq $5, %rdx
 syscall

 movq $60, %rax
 movq $0, %rdi
 syscall
2020-06-07