在 Linux 64 位中处理命令行 [英] Process command line in Linux 64 bit

查看:30
本文介绍了在 Linux 64 位中处理命令行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<前>.section .text.globl _start_开始:movl %esp, %ebpmovl $4, %eax # 写movl $1, %ebx # 标准输出movl 4(%ebp), %ecx #程序名地址(argv[0])movl $5, %edx # 硬编码长度整数 $0x80movl $1, %eaxmovl $0, %ebx整数 $0x80

这个程序正在运行.当我将其转换为 64 位并在 Linux 64 中运行时,它不打印任何内容:

<前>.section .text.globl _start_开始:movq %rsp, %rbpmovq $4,%raxmovq $1, %rbxmovq 8(%rbp), %rcx # 程序名称地址?movq $5,%rdx整数 $0x80movq $1, %raxmovq $0, %rbx整数 $0x80

我的错误在哪里?

解决方案

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

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

第二个系统调用 exit 工作正常,因为在这种情况下截断为 32 位不会造成任何伤害.

<小时>

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

  • 使用syscall,而不是int 0x80;
  • 使用了不同的寄存器:参见这里;
  • 系统调用号也不同:参见这里.

这是您的代码的工作版本:

.section .text.globl _start_开始:movq %rsp, %rbpmovq $1, %raxmovq $1, %rdimovq 8(%rbp), %rsi # 程序名称地址?movq $5,%rdx系统调用movq 60 美元,%raxmovq $0, %rdi系统调用

I have problems accessing the process command line from Linux 64 bit Assembly program. To reproduce this with minimal code, I made this 32-bit program which prints first 5 characters of the program name:

.section .text

.globl _start
_start:
 movl  %esp, %ebp

 movl $4, %eax        # write
 movl $1, %ebx        # stdout
 movl 4(%ebp), %ecx   # program name address (argv[0])
 movl $5, %edx        # hard-coded length
 int  $0x80

 movl $1, %eax
 movl $0, %ebx
 int  $0x80

This program is working. When I translate it to 64 bit and run in Linux 64, it doesn't print anything:

.section .text

.globl _start
_start:
 movq  %rsp, %rbp

 movq $4, %rax
 movq $1, %rbx
 movq 8(%rbp), %rcx       # program name address ?
 movq $5, %rdx
 int  $0x80

 movq $1, %rax
 movq $0, %rbx
 int  $0x80

Where is my mistake?

解决方案

You are loading the correct address into %rcx.

int 0x80 then invokes the 32-bit syscall interface. That truncates the address to 32 bits, which makes it incorrect. (If you use a debugger and set a breakpoint just after the first int 0x80, you will see that it returns with -14 in %eax, which is -EFAULT.)

The second syscall, exit, works OK because the truncation to 32 bits doesn't do any harm in that case.


If you want to pass a 64-bit address to a system call, you will have to use the 64-bit syscall interface:

  • use syscall, not int 0x80;
  • different registers are used: see here;
  • the system call numbers are different as well: see here.

Here is a working version of your code:

.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

这篇关于在 Linux 64 位中处理命令行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆