asm_execve.s:
.section .data file_to_run: .ascii \"/bin/sh\" .section .text .globl main main: pushl %ebp movl %esp, %ebp subl $0x8, %esp
The execve
system call is being called, but you are indeed passing it bad parameters.
(You can see this by running your executable using strace.)
There are three problems:
.ascii
does not 0-terminate the string. (You might get lucky, as there is nothing following it in your .data
section in this example, but that's not guaranteed...) Add a 0, or use .asciz
(or .string
) instead.
movl file_to_run, %edi
moves the value pointed to by the file_to_run
symbol into %edi
, i.e. the first 4 bytes of the string (0x6e69622f
). The address of the string is just the value of the symbol itself, so you need to use the $
prefix for literal values: movl $file_to_run, %edi
. Similarly, you need to say movl $file_to_run, %ebx
a few lines further down. (This is a common source of confusion between AT&T syntax and Intel syntax!)
The parameters are placed on the stack in the wrong order: -0x8(%ebp)
is a lower address than -0x4(%ebp)
. So the address of the command string should be written to -0x8(%ebp)
, the 0 should be written to -0x4(%ebp)
, and the leal
instruction should be leal -8(%ebp), %ecx
.
Fixed code:
.section .data
file_to_run:
.asciz "/bin/sh"
.section .text
.globl main
main:
pushl %ebp
movl %esp, %ebp
subl $0x8, %esp # array of two pointers. array[0] = file_to_run array[1] = 0
movl $file_to_run, %edi
movl %edi, -0x8(%ebp)
movl $0, -0x4(%ebp)
movl $11, %eax # sys_execve
movl $file_to_run, %ebx # file to execute
leal -8(%ebp), %ecx # command line parameters
movl $0, %edx # environment block
int $0x80
leave
ret