Skip to content

Latest commit

 

History

History
179 lines (148 loc) · 6.02 KB

200602171802.txt.md

File metadata and controls

179 lines (148 loc) · 6.02 KB

标题: 快速定位出问题的源码行

创建: 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

#endif

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 (显示帧号)

ChildEBP RetAddr

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