标题: 快速定位出问题的源码行
创建: 2006-02-17 14:34 更新: 链接: http://scz.617.cn/misc/200602171802.txt
目录:
☆ 问题程序
☆ cdb.exe
☆ 快速定位出问题的源码行
☆ 参考资源
☆ 问题程序
/*
- For x86/EWindows XP SP1 & VC 7
- cl x.c /Fex.exe /nologo /Os /G6 /Gz /Gs65536 /W3 /WX /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /link /RELEASE
- cl x.c /Fex.exe /Zi /Fax.asm /Fdx.pdb /nologo /Od /Oi /Gz /Gs65536 /W3 /WX /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /link /RELEASE */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h>
#pragma comment( linker, "/INCREMENTAL:NO" ) #pragma comment( linker, "/merge:.rdata=.text" ) #pragma comment( linker, "/subsystem:console" )
static void * Calloc ( size_t nelem, size_t elsize ) { void *buf = NULL;
if ( NULL == ( buf = calloc( nelem, elsize ) ) )
{
fprintf( stderr, "calloc() failed\n" );
exit( EXIT_FAILURE );
}
return( buf );
} /* end of Calloc */
static void usage ( char arg ) { fprintf ( stderr, "Usage: %s <len_a> <len_b>\n", arg ); exit( EXIT_FAILURE ); } / end of usage */
static void vulfunc ( unsigned int len_a, unsigned int len_b ) { unsigned char *buf_a = NULL; unsigned char *buf_b = NULL;
buf_a = ( unsigned char * )Calloc( len_a, 1 );
buf_b = ( unsigned char * )Calloc( len_b, 1 );
CopyMemory( buf_a, buf_b, len_a );
free( buf_b );
buf_b = NULL;
free( buf_a );
buf_a = NULL;
return;
} /* end of vulfunc */
int __cdecl main ( int argc, char * argv[] ) { unsigned int len_a, len_b;
if ( 3 != argc )
{
usage( argv[0] );
}
len_a = ( unsigned int )strtoul( argv[1], NULL, 0 );
len_b = ( unsigned int )strtoul( argv[2], NULL, 0 );
vulfunc( len_a, len_b );
return( EXIT_SUCCESS );
} /* end of main */
#if 0
x.exe 0xE000 8
vunlfunc()调用CopyMemory()时没有检查第三形参len_a的有效性,尽管buf_a足够大, 但buf_b不够大,内存复制过程中可能出现内存访问违例。
接下来就以x.c为例讲解如何利用cdb.exe快速定位出问题的源码行。
☆ cdb.exe
cdb.exe来自"Debugging Tools for Windows"([1]),这个程序一直在更新中,请随 时下载最新版本。
cdb.exe -version cdb version 6.6.0003.5
☆ 快速定位出问题的源码行
关键就两点,一是编译时指定"/Zi /Fd... /Od /Oi",二是用"lsa eip 0,1"定位源 码行。
cl x.c /Fex.exe /Zi /Fdx.pdb /nologo /Od /Oi /Gz /Gs65536 /W3 /WX /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /link /RELEASE cdb.exe -g -G -hd -o -lines x.exe 0xE000 8 (f18.898): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=00370fe8 ebx=7ffdf000 ecx=00002ffa edx=0000e000 esi=00373000 edi=00412060 eip=00401cba esp=0012febc ebp=0012fecc iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00010206 x!vulfunc+0x40: 00401cba f3a5 rep movsd ds:00373000=???????? es:00412060=00000000 0:000> lsa eip 0,1 45: CopyMemory( buf_a, buf_b, len_a ); 0:000> ls 40,10 40: unsigned char *buf_a = NULL; 41: unsigned char *buf_b = NULL; 42: 43: buf_a = ( unsigned char * )Calloc( len_a, 1 ); 44: buf_b = ( unsigned char * )Calloc( len_b, 1 ); 45: CopyMemory( buf_a, buf_b, len_a ); 46: free( buf_b ); 47: buf_b = NULL; 48: free( buf_a ); 49: buf_a = NULL; 0:000>
可用如下命令查看当前调用栈回溯:
0:000> kp (与kP类似,单行显示) ChildEBP RetAddr 0012fecc 00401c50 x!vulfunc(unsigned int len_a = 0xe000, unsigned int len_b = 8)+0x40 [y:\x\x.c @ 45] 0012fee4 00402493 x!main(int argc = 3, char ** argv = 0x00371408)+0x50 [y:\x\x.c @ 65] 0012ffc0 77e8141a x!mainCRTStartup(void)+0x170 [f:\vs70builds\9466\vc\crtbld\crt\src\crt0.c @ 259] 0012fff0 00000000 kernel32!BaseProcessStart+0x23 0:000> kP (与kp类似,多行显示) ChildEBP RetAddr 0012fecc 00401c50 x!vulfunc( unsigned int len_a = 0xe000, unsigned int len_b = 8)+0x40 [y:\x\x.c @ 45] 0012fee4 00402493 x!main( int argc = 3, char ** argv = 0x00371408)+0x50 [y:\x\x.c @ 65] 0012ffc0 77e8141a x!mainCRTStartup(void)+0x170 [f:\vs70builds\9466\vc\crtbld\crt\src\crt0.c @ 259] 0012fff0 00000000 kernel32!BaseProcessStart+0x23 0:000> kb (固定显示三个形参) ChildEBP RetAddr Args to Child 0012fecc 00401c50 0000e000 00000008 0000e000 x!vulfunc+0x40 [y:\x\x.c @ 45] 0012fee4 00402493 00000003 00371408 00371430 x!main+0x50 [y:\x\x.c @ 65] 0012ffc0 77e8141a 00000000 00000000 7ffdf000 x!mainCRTStartup+0x170 [f:\vs70builds\9466\vc\crtbld\crt\src\crt0.c @ 259] 0012fff0 00000000 00402323 00000000 78746341 kernel32!BaseProcessStart+0x23 0:000> kn (显示帧号)
00 0012fecc 00401c50 x!vulfunc+0x40 [y:\x\x.c @ 45] 01 0012fee4 00402493 x!main+0x50 [y:\x\x.c @ 65] 02 0012ffc0 77e8141a x!mainCRTStartup+0x170 [f:\vs70builds\9466\vc\crtbld\crt\src\crt0.c @ 259] 03 0012fff0 00000000 kernel32!BaseProcessStart+0x23 0:000> r ebp ebp=0012fecc 0:000> dd ebp l 4 0012fecc 0012fee4 00401c50 0000e000 00000008
☆ 参考资源
[ 1] Debugging Tools for Windows - Overview http://www.microsoft.com/whdc/ddk/debugging/default.mspx
Install Debugging Tools for Windows 32-bit Version
http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx