微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐