【Java入门】缓冲区溢出编程心得
前言:网上关于缓冲区溢出的资料也有很多,但我在阅读过程中发现介绍的都不是很明了,而且各网站也只是转贴老外的那篇译文而已,不仅内容有缺损,而且程序也无法调通,因为GCC版本不一样.经过几天的琢磨,终于明白了真正的原理,特地写出来分享.
测试环境:
$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-24)
$ gdb -v
GNU gdb Red Hat Linux (6.0post-0.20031117.6rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu".
$ uname -a
Linux candy 2.4.21-9.EL #1 Thu Jan 8 17:03:13 EST 2004 i686 athlon i386 GNU/Linux
实例:
网上和我的这个实例雷同的也有,但是他们的是无易做图确实现的.因为关键的跳转代码没有计算正确.(GCC版本问题,呵呵)
/************
* a.c
************/
void function(void)
{
char buffer[5];
int* ret;
ret=buffer+28;
(*ret)+=10;
}
void main()
{
int x;
x=0;
function();
x=1;
printf("%d
",x);
return;
}
/*end*/
懂C语言的人都会认为最后的输出结果是1,可惜输出结果为0.为什么呢?请听解释.
实例分析:
相关堆栈的基础知识我就不罗嗦了,网上的介绍很多.
关键问题在于如何确定源代码
ret=buffer+28;
(*ret)+=10;
中的28 和 10
编译(会有warning,不用管他.)
$gcc -g -o a a.c //加上-g 用来在gdb中调试
$gdb a
(gdb)disas main //得到反汇编代码 如下:
Dump of assembler code for function main:
0x08048366
0x08048367
0x08048369
0x0804836c
0x0804836f
0x08048374
0x08048376
0x0804837d
0x08048382
0x08048389
0x0804838c
0x0804838f
0x08048394
0x08048399
0x0804839c
0x0804839d
End of assembler dump.
(gdb)disas function
Dump of assembler code for function function:
0x08048348
0x08048349
0x0804834b
0x0804834e
0x08048351
0x08048354
0x08048357
0x0804835a
0x0804835d
0x0804835f
0x08048362
0x08048364
0x08048365
End of assembler dump.
可以得知当main中执行 0x0804837d
继续使用gdb
(gdb) l //显示源代码(因为编译时用了 -g 参数)
5
6 ret=buffer+28;
7 (*ret)+=10;
8 }
9
10 void main()
11 {
12 int x;
13
14 x=0;
(gdb)b 6 // 在关键处下断点 观察内存的值
Breakpoint 1 at 0x804834e: file a.c, line 6.
(gdb)b 7
Breakpoint 2 at 0x8048357: file a.c, line 7.
(gdb)r
Breakpoint 1, function () at rr.c:6
6 ret=buffer+28;
(gdb)i reg //观察寄存器的值 (注意ebp esp eip)
eax &nb补充:软件开发 , Java ,