Assembly sys_execve system call

asm_execve.s:

  .section .data
 file_to_run:
 .ascii "/ 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, -0x4 (% ebp)   
     movl $ 0, -0x8 (% ebp)

     movl $ 11,% eax # sys_execve
     movl file_to_run,% ebx # file to execute       
     leal -4 (% ebp),% ecx # command line parameters
     movl $ 0,% edx # environment block
     int $ 0x80              

     leave
     ret

Makefile:

  NAME = asm_execve
 $ (NAME): $ (NAME) .s
     gcc -o $ (NAME) $ (NAME) .s

The program is running, but sys_execve is not called:

  alex@alex32 : ~ / project $ make
 gcc -o asm_execve asm_execve.s
 alex@alex32 : ~ / project $ ./asm_execve 
 alex@alex32 : ~ / project $ 

Expected Result:

  alex@alex32 : ~ / project $ ./asm_execve 
 $ exit
 alex@alex32 : ~ / project $

This build program should work like the following C code:

  char * data [2];
 data [0] = "/ bin / sh"; 
 data [1] = NULL;
 execve (data [0], data, NULL);

Is there something wrong with the system call parameters?

+4
source share
2 answers

The execve system call is called, but you are really passing bad parameters to it.

(You can see this by running your executable using strace .)

There are three problems:

  • .ascii does not 0-line terminate. (You might be lucky, since in this example there is nothing in your .data section, but this is not guaranteed ...) Add 0 or use .asciz (or .string ) instead.

  • movl file_to_run, %edi moves the value indicated by the file_to_run symbol to %edi , i.e. the first 4 bytes of the string ( 0x6e69622f ). The address of the string is just the value of the character itself, so you need to use the $ prefix for the literal values: movl $file_to_run, %edi . Similarly, you need to say movl $file_to_run, %ebx few lines further. (This is a common source of confusion between AT & T syntax and Intel syntax!)

  • Parameters are -0x8(%ebp) stack in the wrong order: -0x8(%ebp) is a lower address than -0x4(%ebp) . Thus, the command line address should be written in -0x8(%ebp) , the value 0 should be written in -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 
+9
source

You do not need to load anything in other arguments. If you do this in x86, the following simple code will also work:

 .global _main .section .text .data file_to_run: .asciz "/bin/sh" .section .text .globl main _main: pushl %ebp movl %esp, %ebp movl $11, %eax # sys_execve movl $file_to_run, %ebx # file to execute movl $0, %ecx # Null value will work too movl $0, %edx # Null will works too int $0x80 leave ret 

This will open the shell terminal after calling the system call.

+1
source

Source: https://habr.com/ru/post/1397201/


All Articles