My code:
.section .data
name: .string "/bin/sh"
args:
.string "-c"
.string "ls"
.section .text
.globl _start
_start:
pushq $0
pushq name
movq $59, %rax
movq %rsp, %rdi
pushq $0
pushq args
movq %rsp, %rsi
movq $0, %rdx
syscall
I know that the second argument of execve
is array of chars.
How to do this in assembly avoiding this:
execve("./payload", ["./payload"], 0x7ffc291fd160 /* 40 vars */) = 0
execve("/bin/sh", [0x736c00632d], NULL) = -1 EFAULT (Bad address)
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xfffffffffffffff2} ---
+++ killed by SIGSEGV +++
Segmentation fault
The
execve
system call has signatureThe argument vector is an array of strings, that is, a pointer to an array of pointers to arrays of characters. You however supplied a pointer to an array of characters, which is incorrect and will not work. To fix this, add an array of pointers referring to your arguments:
See how now
args
is a NULL-terminated array of pointers to the arguments. Also note that the first argument (at index 0) is conventionally the program name itself. It won't work as expected to pass an actual option there.I have also simplified the code by loading the addresses of the strings directly using a
lea
instruction instead of the roundabout way you used.