显示标签为“反汇编”的博文。显示所有博文
显示标签为“反汇编”的博文。显示所有博文

2012年4月23日星期一

关于缓冲区溢出攻击的一次小测试

我们写C/C++程序的时候,用scanf,gets,strcpy什么的,编译总会有warning,这个函数是不安全的云云。到现在才明白这个所谓的不安全是怎么回事,这个关于C的历史遗留问题真的有够严重的。。。
不安全的代码,产生的bug就不是bug那么简单了,而是exploit。这个buffer overflow attack (缓冲区溢出攻击)在安全界的知名度是不言而喻的,基本上属于最经典的漏洞之一。各种利用工具和shellcode何其多哉!

抱着亲身了解下缓冲区溢出攻击的过程,顺便体验下linux下强大的gdb的心态,就拿gets()写了个小程序练下手。

//attack.c
#include<stdio.h>
int main()
{
char s[8];
gets(s);
printf(s);
return 0;
}


生成的attack可执行文件用objdump反汇编:

080483f4 <main>:
 80483f4: 55                    push   %ebp
 80483f5: 89 e5                 mov    %esp,%ebp
 80483f7: 83 e4 f0              and    $0xfffffff0,%esp
 80483fa: 83 ec 20              sub    $0x20,%esp
 80483fd: 8d 44 24 18           lea    0x18(%esp),%eax
 8048401: 89 04 24              mov    %eax,(%esp)
 8048404: e8 fb fe ff ff        call   8048304 <gets@plt>
 8048409: 8d 44 24 18           lea    0x18(%esp),%eax
 804840d: 89 04 24              mov    %eax,(%esp)
 8048410: e8 0f ff ff ff        call   8048324 <printf@plt>
 8048415: b8 00 00 00 00        mov    $0x0,%eax
 804841a: c9                    leave  
 804841b: c3                    ret    
 804841c: 90                    nop
 804841d: 90                    nop
 804841e: 90                    nop
 804841f: 90                    nop



2012年4月15日星期日

某个C程序的汇编代码解释

偶然看到Allan Ruin大大的某post,原意大概是:子函数内的局部变量没有初始化的话,其值应该是任意的,函数返回后会释放内存。但是为什么第二次调用的时候i的值会是777呢?之前没遇到过类似问题,毕竟是现实中不会出现的情况。但通过汇编代码大概可以研究一下的吧?
这段时间刚好在看CSAPP的GAS语法汇编,恰好拿来练手的说。


C代码如下: 版权属于Allan Ruin :)
#include <stdio.h>
void foo(void)
{
int i;
printf("%d\n", i);
i = 777;
}
int main(void)
{
foo();
foo();
return 0;
}


ouput:
3
777


gcc -s lg_test.c

汇编代码如下



.file "lg_test.c"
.section .rodata             ;read only data segment
.LC0:
.string "%d\n"               ;printf() function's first parameter
.text
.globl foo
.type foo,@function


foo:
1  pushl %ebp              ;save old  %ebp
2  movl %esp, %ebp         ;new %ebp point to old %ebp (i.e. frame pointer)
3  subl $40, %esp          ;allocate 40 bytes on stack
4  movl $.LC0, %eax        ;move the string"%d\n" to %eax
5  movl -12(%ebp), %edx    ;use -12(%ebp) as i's value and save in %edx
6  movl %edx, 4(%esp)      ;set -12(%ebp) as the second parameter,push in stack
7  movl %eax, (%esp)       ;set  %eax( i.e. "%d\n" ) as the first parameter
8  call printf             ;call printf function(you can assume that 
                           ;it doesn't affect the existing stack frame)
9  movl $777, -12(%ebp)    ;NOTE:  -12 (%ebp) has changed
10 leave                   ;i.e.  movl %ebp, %esp ;    pop %ebp ;      
11 ret                     ;return    i.e.  pop %eip ;