简体   繁体   English

将工程汇编代码反向转换为C

[英]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? 有人可以为我提供帮助,帮助您拆卸下面的shell代码(在注释部分),并向我解释最后一行代码的作用吗?

# 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. 我读了一些有关gdb的内容,但是在这种情况下我不知道如何使用它。

PS : I am on an x86-32 Ubuntu Linux machine. PS:我在x86-32 Ubuntu Linux机器上。

The code is most probably making a call to the sys_execve() kernel function 该代码最有可能调用sys_execve()内核函数

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 */;
  1. Line 1 is setting the eax register to zero and will be used as a null string terminator 第1行将eax寄存器设置为零,并将其用作空字符串终止符
  2. Lines 2, 3 and 4 are using the stack as a temporary buffer to store the null terminated ASCII string "/bin/ sh"; 第2、3和4行将堆栈用作临时缓冲区,以存储以null结尾的ASCII字符串“ / bin / sh”; since the stack grows in decreasing order, the characters are reversed, that's why the terminator is pushed first. 由于堆栈以递减的顺序增长,因此字符被颠倒了,这就是为什么终止符首先被压入的原因。
  3. Line 5 is loading into ebx the current value of the stack pointer, which at this moment points to the address of the first character of the string we formed on the previous steps. 第5行将堆栈指针的当前值加载到ebx中,该指针此刻指向我们在前面的步骤中形成的字符串的第一个字符的地址。 Ebx is the register where sys_execve() expects the string with the file to be run. ebx是sys_execve()希望运行包含文件的字符串的寄存器。
  4. Line 6, and 7 are again using the stack as a temporary buffer to hold an empty null-terminated ASCII string 第6行和第7行再次使用堆栈作为临时缓冲区来保存空的以 null终止的ASCII字符串
  5. Line 8 is loading into ecx the address of this empty string where sys_execve() expects the command line parameters 第8行将这个空字符串的地址加载到ecx中,其中sys_execve()需要命令行参数
  6. Line 9, no idea of its purpose 第9行,不知道其用途
  7. Line 10, loads decimal value 11 to AL register, specifying that the sys_execve() function is the one we wish to call 第10行,将十进制值11加载到AL寄存器,指定sys_execve()函数是我们希望调用的函数
  8. Line 11 triggers interrput 0x80 - its handler is the code that will actually perform the sys_execve() call for us 第11行触发输入0x80-它的处理程序是将实际为我们执行sys_execve()调用的代码

You already have the diassembly for the inline code, it's in the comments. 您已经有内联代码的汇编代码,它在注释中。 So that part is a bit confusing. 所以这部分有点令人困惑。

The final statement casts buf into a function pointer, and calls the code. 最后一条语句将buf强制转换为函数指针,然后调用代码。 This is the actual use of the exploit. 这是漏洞利用的实际用途。 It's also (as far as I know) undefined behavior, and will not work in environments that protect against executing random areas of memory. (据我所知)它也是未定义的行为,并且在防止执行随机内存区域的环境中不起作用。

C can do this, but there's no reverse-compiler that can figure this out, to my knowledge. C可以做到这一点,但是据我所知,没有反向编译器可以解决这个问题。

This code makes a system call. 此代码进行系统调用。 That's what int $0x80 is. 那就是int $0x80是什么。 The line before it says it is system call 11. The rest of the instructions set up arguments to it. 它前面的那一行说它是系统调用11。其余的指令为其设置了参数。

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. 这是一种将一些未知代码引入程序并让计算机执行它的方法。

What the assembly does is build an argument list to pass to an operating system call to execute a binary ( /bin/sh ). 程序集所做的是构建一个参数列表,以传递给操作系统调用以执行二进制文件( /bin/sh )。

These two lines push /bin/sh onto the stack. 这两行将/bin/sh压入堆栈。

pushl $0x68732f2f
pushl $0x6e69622f

These lines place the pointer to /bin/sh in an argument register according to the calling convention . 这些行根据调用约定将指向/bin/sh的指针放在参数寄存器中。

movl  %esp, %ebx
pushl %eax
pushl %ebx
movl  %esp, %ecx
cdq

This line places the system call number, 11, in a register as an argument to the interrupt. 该行将系统调用号11放置在寄存器中,作为中断的参数。

movb  $0x0b, %al

The last line calls into the operating system. 最后一行调用操作系统。

int   $0x80

This line in the C code just casts the buffer to a function pointer, and calls the function. C代码中的这一行只是将缓冲区强制转换为函数指针,然后调用该函数。

(( void (*)( )) buf )( );

Note, this used to be a common way to exploit software, however a similar method can be used to JIT compile code. 请注意,这曾经是利用软件的常见方法,但是可以将类似的方法用于JIT编译代码。

I first thought lines 3 and 4 are setting up /bin/sh, but on second thoughts it might be sh /bin/X for some XI can't quite make out. 我首先以为第3行和第4行正在设置/ bin / sh,但出于第二个想法,对于某些XI来说可能不是sh / bin / X。 In fact the // sh part looks almost like a comment?? 实际上,// sh部分看起来几乎像一个注释?

My hunch is that the system call, line 11, is the exec system call, and that the preceding lines are setting up the args for the exec call. 我的直觉是,系统调用第11行是exec系统调用,而前面的几行正在为exec调用设置args。

I would hazard a guess that you want to be v careful running this code ;) 我冒昧地猜测您要谨慎运行此代码;)

You might want to investigate the Hex-Rays disassembler, it can (sort of) convert machine code/assembler (the two are equivalent) into C. 您可能要研究Hex-Rays拆装器,它可以(某种程度上)将机器代码/汇编器(两者等效)转换为C。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM