我想把第一个长度为4的命令行参数放进缓冲区,我可以通过.NET技术获取其中的每一个字符。
.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的字符串放到我的缓冲区中?我的系统是x64-Linux和GAS。
你不需要把字符串本身的内容复制到数据缓冲区。将字符串的值保存在 16(%rsp)
在一个QWORD大小的变量中,你可以随意使用它来进行系统调用。在C语言中,这将是与
char lcomm[4];
strcpy(lcomm, argv[1]);
open(lcomm, ...);
和
char *plcomm;
plcomm = argv[1];
open(plcomm, ...);
第二种也同样有效。
另外,你的缓冲区有一个固定的4字节大小。如果命令行参数超过了这个大小,你的代码就会溢出缓冲区,并有可能崩溃。
也就是说,如果你认真学习汇编,你最终应该弄清楚如何写一个 strcpy
-类似循环。)
编辑了一些汇编代码。上次我检查了一下,文件名在syscall中是RDI,而不是RSI。
mov 16(%rsp), %rdi # File name
mov $0, %rsi # Flags: O_RDONLY, but substitute your own
mov $0, %rdx # Mode: doesn't matter if the file exists
mov $2, %rax # Syscall number for open
syscall
# %rax is the file handle now
为了便于将来参考,x86_64系统调用的惯例是:
syscall
指令syscalls的引用是 此处.
解决了!
.code64
.global _start
.text
_start:
mov 16(%rsp), %rdi # File name from command-line first arg
mov $0, %rsi # Flags: O_RDONLY, but substitute your own
mov $0, %rdx # Mode: doesn't matter if the file exists
mov $2, %rax # Syscall number for open
syscall
mov %rax , %rbx
mov $60, %rax
syscall
tnx to Seva Alekseyev.