在Linux 64位处理命令行

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

.section .text

.globl _start

_开始:

movl%esp,%ebp

movl $ 4,%eax#写入

movl $ 1,%ebx#stdout

movl 4(%ebp),%ecx#程序名称地址(argv [0])

movl $ 5,%edx#硬编码的长度

int $ 0x80

movl $ 1,%eax

movl $ 0,%ebx

int $ 0x80

这个程序正在工作。 当我将它翻译成64位并在Linux 64上运行时,它不会打印任何内容

.section .text

.globl _start

_开始:

movq%rsp,%rbp

movq $ 4,%rax

movq $ 1,%rbx

movq 8(%rbp),%rcx#程序名称地址?

movq $ 5,%rdx

int $ 0x80

movq $ 1,%rax

movq $ 0,%rbx

int $ 0x80

我的错误在哪里?

编译器使用本地variables而不调整RSP

将值插入数组并显示,nasm

无法运行与libc链接的可执行文件

虚拟处理器和高级networkingLinux和Windows

Linux如何保护内存?

从组件中读取文件

在x86 nasm中分割时浮点exception

x86 – 获取方向标志(DF)的当前状态

在Windows中分析崩溃:错误消息告诉我们什么?

哪些寄存器在Linux的用户空间受到保护?

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

int 0x80然后调用32位系统调用接口。 这将地址截断为32位,这使得它不正确。 (如果你使用一个调试器并在第一个int 0x80后面设置一个断点,你会发现它返回的时候是-14,在%eax中是-EFAULT 。)

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

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

使用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

如X86_64 ABI所述 :使用syscall指令而不是int $0x80 。 内核在64位中使用不同的寄存器作为系统调用参数,为系统调用函数分配的编号也在i386和x86_64之间变化。

一个例子 – 在德国,对不起 – 可以在这里找到:

http://zygentoma.de/codez/linux_assembler.PHP

相关文章

可以认为OpenFeign是Feign的增强版,不同的是OpenFeign支持S...
为进一步规范小程序交易生态、提升用户购物体验、满足用户在...
云原生之使用Docker部署Dashdot服务器仪表盘
本文主要描述TensorFlow之回归模型的基本原理
1.漏洞描述Apache Druid 是一个集时间序列数据库、数据仓库和...
内部类(当作类中的一个普通成员变量,只不过此成员变量是cl...