Search code examples
cassemblydisassemblyshellcode

Reverse engineering assembly code to C


Would someone please provide me with assistance disassembling the shell code below (in the comment section) and also explain to me the role of the last line of code?

# include <stdlib .h>
# include <stdio .h>
# include <string .h>
const char code [] =
  "\x31\xc0"       /* Line  1: xorl  %eax, %eax */
  "\x50"           /* Line  2: pushl %eax */
  "\x68""// sh"    /* Line  3: pushl $0x68732f2f */
  "\x68""/bin"     /* Line  4: pushl $0x6e69622f */
  "\x89\xe3"       /* Line  5: movl  %esp, %ebx */
  "\x50"           /* Line  6: pushl %eax */
  "\x53"           /* Line  7: pushl %ebx */
  "\x89\xe1"       /* Line  8: movl  %esp, %ecx */
  "\x99"           /* Line  9: cdq */
  "\xb0\x0b"       /* Line 10: movb  $0x0b, %al */
  "\xcd\x80"       /* Line 11: int   $0x80 */;

  int main (int argc , char ** argv ) {
     char buf [ sizeof ( code )];
     strcpy (buf , code );
     (( void (*)( )) buf )( ); /*I don't understand what this line is for*/
  }

I read a little bit about gdb but I don't know how to use it in this case.

P.S : I am on an x86-32 Ubuntu Linux machine.


Solution

  • C can do this, but there's no reverse-compiler that can figure this out, to my knowledge.

    This code makes a system call. That's what int $0x80 is. The line before it says it is system call 11. The rest of the instructions set up arguments to it.

    xorl  %eax, %eax     ; clear the 32-bit A register to 0
    pushl %eax           ; push 32-bit 0 on the stack
    
    pushl $0x68732f2f    ; push two 32-bit constants on the stack
    pushl $0x6e69622f
    
    movl  %esp, %ebx     ; copy the stack pointer into the 32-bit B register
    pushl %eax           ; push another 0
    pushl %ebx           ; push the stack pointer
    movl  %esp, %ecx     ; copy the stack pointer into the 32-bit C register
    cdq                  ; A already has 0. This also sets D to zero, 32-bit
    
    movb  $0x0b, %al     ; move a constant 11 into the lower 8 bits of the A register
    int   $0x80          ; and do the system call
    

    It wouldn't surprise me if this code is designed for some nefarious purpose. It is a way to introduce some unknown code into a program, and get the computer to execute it.