如何在64位(linux)的asm中将argv参数传递给execv

时间:2019-05-08 19:09:41

标签: assembly x86-64

在64位代码上调用/bin/bash时,我试图传递参数。我无法使用.data部分,这对我来说有点棘手。我看过各种代码示例,但都不清楚(这里是初学者)。我想调用的是/bin/bash -c id

当我尝试将第二个参数保留为空时,我的代码有效,但是当我添加第二个参数时,出现以下错误:

execve("/bin/bash", [0x7361622f6e69622f, 0x646920632d2068, 0x7361622f6e69622f, 0x68], NULL) = -1 EFAULT (Bad address)

编译为:nasm -f elf64 -o test.o test.asm;ld -o test test.o

section .text 
  global _start

_start:
  mov rax,59                     
  lea rdi,[rel bin]             
  lea rsi,[rel msg]
  syscall                       

align 8
  msg db '/bin/bash -c /bin/id',0
  bin db '/bin/bash',0

1 个答案:

答案 0 :(得分:3)

execve的第二个参数是字符串指针(char **char *argv[])的数组的地址。您已为其指定了单个字符串(char *)的地址。

另外,execve(2)也使用第三个参数,即环境列表。如手册页所述,argv和/或envp可以为NULL,Linux将其视为一个空列表(内存中指向NULL的有效指针)。

它应该是这样:

      mov rax, 59
      lea rdi, [rel bin]
      lea rsi, [rel args]
      xor edx, edx             ; Linux accepts NULL instead of a pointer to NULL
      syscall


; section   .rodata
      align 8
args  dq bin, arg1, arg2, 0

arg1  db '-c',0
arg2  db '/bin/id',0
bin   db '/bin/bash',0

如果要编写Shellcode,请注意,它在指令(非负0寻址模式和32位立即数)和数据中都包含多个rel32字节。

如果您不编写shellcode(要与代码和数据一起提取为平面二进制文件),请将数据放在单独的部分中,最好是.rodata用于只读数据。

相关问题