片段
- 1 #include <stdio.h>
-
2 #include <ctype.h>
-
3 #include <assert.h>
-
4
-
5 int my_atoi( const char *s )
-
6 {
-
7 int ret = 0;
-
8
-
9 assert( NULL );
-
10 while( *s != '\0' && isdigit(*s) ){
-
11 const int dig = *s - '0';
-
12 ret *= 10;
-
13 ret += dig;
-
14 ++s;
-
15 }
-
16 return ret;
-
17 }
-
18
-
19 int main( int argc , char **argv )
-
20 {
-
21 printf("\"123\" = %d\n" , my_atoi("123"));
-
22 printf("\"4294967297\" = %d\n" , my_atoi("4294967297"));
-
23
-
24 return 0;
-
25 }
- 05:46:41-xuk@localhost:~/svn/goodbyeworld/binary-hacks/43$gcc main.c
-
05:47:09-xuk@localhost:~/svn/goodbyeworld/binary-hacks/43$./a.out
-
"123" = 123
-
"4294967297" = 1
(signed) int 最大正整数范围 0x7fffffff ( 2147483647 dec ) . 第二次调用my_atoi()的参数大于0x7fffffff , 所以产生溢出 .
在编译时加上 -ftrapv参数 , 运行时检测到溢出后 , 会产生SIGABRT , 进程终止 .
- 05:47:11-xuk@localhost:~/svn/goodbyeworld/binary-hacks/43$gcc -ftrapv -g main.c
-
05:48:01-xuk@localhost:~/svn/goodbyeworld/binary-hacks/43$./a.out
-
"123" = 123
-
Aborted
用gdb运行程序 , 在产生SIGABRT程序终止后 , 看backtrace , 就可以知道源码在哪里产生整数溢出 .
- 05:48:02-xuk@localhost:~/svn/goodbyeworld/binary-hacks/43$gdb a.out
-
GNU gdb Fedora (6.8-29.fc10)
-
Copyright (C) 2008 Free Software Foundation, Inc.
-
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
-
This is free software: you are free to change and redistribute it.
-
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
-
and "show warranty" for details.
-
This GDB was configured as "i386-redhat-linux-gnu"...
-
(gdb) r
-
Starting program: /home/xuk/svn/goodbyeworld/binary-hacks/43/a.out
-
"123" = 123
-
-
Program received signal SIGABRT, Aborted.
-
0x00110416 in __kernel_vsyscall ()
-
(gdb) bt
-
#0 0x00110416 in __kernel_vsyscall ()
-
#1 0x00555460 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
-
#2 0x00556e28 in abort () at abort.c:88
-
#3 0x08048603 in __mulvsi3 ()
-
#4 0x080484cd in my_atoi (s=0x804870c "7") at main.c:12
-
#5 0x08048555 in main () at main.c:22
-
(gdb)
阅读(5077) | 评论(1) | 转发(0) |