【发布时间】:2020-05-22 14:29:48
【问题描述】:
我想将第一个长度为 4 的命令行参数放入缓冲区。我可以通过以下方式获取它的每个字符:
.code64
.global _start
.bss
.lcomm mybuf , 4
.text
_start:
mov 16(%rsp) , %rsi # argv[1]
movzx (%rsi) , %ebx # first char of argv[1]
movzx 1(%rsi) , %ebx # second char of argv[1]
movzx 2(%rsi) , %ebx # third char of argv[1]
movzx 3(%rsi) , %ebx # fourth char of argv[1]
xor %rax , %rax
inc %rax
int $0x80
但是如何将长度为 4 的整个字符串放入我的缓冲区中呢?我的系统是带有 GAS 的 x64-Linux。
【问题讨论】:
-
你试过类似
mov (%rsi), %ebx; mov %ebx, mybuf(%rip)的东西吗? -
你想对那个字符串做什么?除非你想修改它,否则你可以在它所在的地方使用它。
16(%rsp)是它的地址,它已经被空终止了。 -
那是因为
int 0x80用于 32 位系统调用。如果您使用syscall进行系统调用,则可以使用 64 位指针,它们可以指向堆栈或您想要的任何其他位置。 -
@Ston17 请注意,您真的不应该在 64 位代码中使用
int $0x80。相反,正如 Nate Eldredge 所说,使用syscall。请注意,系统调用号和寄存器在那里是不同的。 -
@Ston17 重新定位缓冲区并不重要。使用
mybuf(%rip)代替mybuf来生成rip相对寻址模式。rip不是正常意义上的基址寄存器。是的,您可以使用普通汇编中的syscall指令。看来你有很多困惑。最好从汇编教程开始,而不是在 Stack Overflow 上随机提问。
标签: linux assembly x86 x86-64 gnu-assembler