You can put the argv
array onto the stack and load the address of it into rsi
. The first member of argv
is a pointer to the program name, so we can use the same address that we load into rdi
.
xor edx, edx ; Load NULL to be used both as the third
; parameter to execve as well as
; to push 0 onto the stack later.
push "-aal" ; Put second argument string onto the stack.
mov rax, rsp ; Load the address of the second argument.
mov rcx, "/bin//ls" ; Load the file name string
push rdx ; and place a null character
push rcx ; and the string onto the stack.
mov rdi, rsp ; Load the address of "/bin//ls". This is
; used as both the first member of argv
; and as the first parameter to execve.
; Now create argv.
push rdx ; argv must be terminated by a NULL pointer.
push rax ; Second arg is a pointer to "-aal".
push rdi ; First arg is a pointer to "/bin//ls"
mov rsi, rsp ; Load the address of argv into the second
; parameter to execve.
This also corrects a couple of other problems with the code in the question. It uses an 8-byte push for the file name, since x86-64 doesn’t support 4-byte push, and it makes sure that the file name has a null terminator.
This code does use a 64-bit push with a 4-byte immediate to push “-aal” since the string fits in 4 bytes. This also makes it null terminated without needing a null byte in the code.
I used strings with doubled characters as they are in the question to avoid null bytes in the code, but my preference would be this:
mov ecx, "X-al" ; Load second argument string,
shr ecx, 8 ; shift out the dummy character,
push rcx ; and write the string to the stack.
mov rax, rsp ; Load the address of the second argument.
mov rcx, "X/bin/ls" ; Load file name string,
shr rcx, 8 ; shift out the dummy character,
push rcx ; and write the string onto the stack.
Note that the file name string gets a null terminator via the shift, avoiding the extra push. This pattern works with strings where a doubled character wouldn’t work, and it can be used with shorter strings, too.