Skip to main content
 首页 » 编程设计

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

2024年08月06日15webabcd

我试图在对一些 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 

请您参考如下方法:

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,请注意,指令(非负 rel32 寻址模式和 32 位立即数)和数据。

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