如何获取第一个命令行参数并将其放入内存中的静态缓冲区?

问题描述 投票:0回答:1

我想把第一个长度为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。

linux assembly x86 x86-64 gas
1个回答
3
投票

你不需要把字符串本身的内容复制到数据缓冲区。将字符串的值保存在 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系统调用的惯例是:

  • 参数依次进入%rdi, %rsi, %rdx, %rcx, %r8, 和 %r9中.
  • Syscall #进入%rax。
  • 然后进行 syscall 指令
  • 返回值以%rax为单位
  • %rcx和%r11被破坏,其余的寄存器被保留下来

syscalls的引用是 此处.


0
投票

解决了!

.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.

© www.soinside.com 2019 - 2024. All rights reserved.