Author Topic: Linux execve & Arrays  (Read 16926 times)

evilmaniac

  • Guest
Linux execve & Arrays
« on: August 04, 2009, 03:41:26 PM »
Hello & thank you in advance~

I have been trying to perform a simple execve("/usr/bin/wget",("/usr/bin/wget","--help"),NULL); through assembly and unfortunately, I have only been able to pass the first value of the second argument (note that the second argument is an array). The second part of the array is totally ignored.

CODE:

section .data
   ARGV1:      db "/usr/bin/wget",0
         db "--help",0

shell:      db "/usr/bin/wget",0
         dd 0
         dd 0

section .text
   global _start

_start:


   mov ebx, shell      ; move address of shell into ebx

mov eax, ARGV0      ; move address of ARGV1 into eax
   mov [ebx+14], eax   ; move address of ARGV1 (from eax) and place into shell
   lea ecx, [ebx+14]   ; fill ecx with value of shell+14

mov eax, 0      ; NULL eax
   mov [ebx+18], eax   ; NULL last 4 bytes of shell
   lea edx, [ebx+18]   ; fill edx with value of shell+18

mov eax,11      ; eax = 0xBh // execve
   int 80h         ; kernel call

mov eax,1      ; eax = 0x1h // exit
   mov ebx,0      ; no error
   int 80h         ; kernel call

evilmaniac

  • Guest
Re: Linux execve & Arrays
« Reply #1 on: August 04, 2009, 03:45:19 PM »
mov eax, ARGV0 ; move address of ARGV1 into eax

(pretend its  ARGV1 on line 17 >_>; sorry for the mistake)

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Linux execve & Arrays
« Reply #2 on: August 04, 2009, 05:40:37 PM »
Hi evilmaniac,

How evil are ya? :)

I pretended "ARGV1" was named "ARGV0", actually... And put an "ARGV1" label on the "--help" string. The array you want in ecx wants to be the addresses of the "filename"(argv[0]) and command line parameter(s) string(s)  - zero-terminated - not the strings themselves. This rather sloppy modification of your code seems to work:


section .data
   ARGV0:      db "/usr/bin/wget",0
   ARGV1      db "--help",0

shell:      db "/usr/bin/wget",0
         dd 0
         dd 0

argarray dd ARGV0, ARGV1, 0

section .text
   global _start

_start:


   mov ebx, shell      ; move address of shell into ebx

mov ecx, argarray
    xor edx, edx ; ignore environment for now

mov eax,11      ; eax = 0xBh // execve
   int 80h         ; kernel call

mov eax,1      ; eax = 0x1h // exit
   mov ebx,0      ; no error
   int 80h         ; kernel call

We probably could/should do better with envp - point edx at the "real" environment or provide a "fake" one in the same form as the "args" array. Simply passing zero seems to work, but probably isn't "right". To really be a "shell", we should be execveing "bash" or so, passing it "wget" and its parameters, no? This would allow bash to expand wildcards in filenames, etc. (I think). I suspect the "exit" is redundant - I don't think execve returns. If we want to continue after running it, I think we need to "fork" and do the execve in the child. It's spitting up wget's "help" now, anyway.

Best,
Frank