[英]Reverse engineering assembly code to C
有人可以为我提供帮助,帮助您拆卸下面的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*/
}
我读了一些有关gdb的内容,但是在这种情况下我不知道如何使用它。
PS:我在x86-32 Ubuntu Linux机器上。
该代码最有可能调用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 */;
sys_execve()
希望运行包含文件的字符串的寄存器。 sys_execve()
需要命令行参数 sys_execve()
函数是我们希望调用的函数 您已经有内联代码的汇编代码,它在注释中。 所以这部分有点令人困惑。
最后一条语句将buf
强制转换为函数指针,然后调用代码。 这是漏洞利用的实际用途。 (据我所知)它也是未定义的行为,并且在防止执行随机内存区域的环境中不起作用。
C可以做到这一点,但是据我所知,没有反向编译器可以解决这个问题。
此代码进行系统调用。 那就是int $0x80
是什么。 它前面的那一行说它是系统调用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
如果此代码是为某些恶意目的而设计的,这不会令我感到惊讶。 这是一种将一些未知代码引入程序并让计算机执行它的方法。
程序集所做的是构建一个参数列表,以传递给操作系统调用以执行二进制文件( /bin/sh
)。
这两行将/bin/sh
压入堆栈。
pushl $0x68732f2f
pushl $0x6e69622f
这些行根据调用约定将指向/bin/sh
的指针放在参数寄存器中。
movl %esp, %ebx
pushl %eax
pushl %ebx
movl %esp, %ecx
cdq
该行将系统调用号11放置在寄存器中,作为中断的参数。
movb $0x0b, %al
最后一行调用操作系统。
int $0x80
C代码中的这一行只是将缓冲区强制转换为函数指针,然后调用该函数。
(( void (*)( )) buf )( );
请注意,这曾经是利用软件的常见方法,但是可以将类似的方法用于JIT编译代码。
我首先以为第3行和第4行正在设置/ bin / sh,但出于第二个想法,对于某些XI来说可能不是sh / bin / X。 实际上,// sh部分看起来几乎像一个注释?
我的直觉是,系统调用第11行是exec系统调用,而前面的几行正在为exec调用设置args。
我冒昧地猜测您要谨慎运行此代码;)
您可能要研究Hex-Rays拆装器,它可以(某种程度上)将机器代码/汇编器(两者等效)转换为C。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.