Skip to content

2.19 在GDB里如何搜索内存

https://scz.617.cn/unix/201201181429.txt

A: scz@nsfocus 2012-01-18 14:29


/ * gcc -Wall -pipe -O3 -s -o findtest findtest.c /

define _GNU_SOURCE

include

include

include

static unsigned char buf[] = "51201314";

int main ( int argc, char * argv[] ) { unsigned char *p;

p   = memmem( buf, sizeof( buf ), "1314", 4 );
printf( "%.*s\n", 4, p );
return( EXIT_SUCCESS );

} / end of main /

$ gcc -Wall -pipe -O3 -o findtest findtest.c $ gdb -n ./findtest GNU gdb (GDB) 7.0.1-debian (gdb) b *main (gdb) r (gdb) i r esp ebp eip esp 0xbfffd47c 0xbfffd47c ebp 0xbfffd4f8 0xbfffd4f8 eip 0x80483e0 0x80483e0

(gdb) x/s &buf 0x804961c : "51201314"

$ ps auwx | grep findtest root 3919 0.0 0.9 14496 7044 pts/0 S+ 14:41 0:00 gdb -n ./findtest root 3923 0.0 0.0 1532 288 pts/0 T 14:41 0:00 /tmp/findtest root 3944 0.0 0.0 3944 736 pts/1 R+ 14:43 0:00 grep findtest $ cat /proc/3923/maps 08048000-08049000 r-xp 00000000 08:01 378873 /tmp/findtest 08049000-0804a000 rw-p 00000000 08:01 378873 /tmp/findtest b7e8a000-b7e8b000 rw-p b7e8a000 00:00 0 b7e8b000-b7fcb000 r-xp 00000000 08:01 769046 /lib/i686/cmov/libc-2.11.2.so b7fcb000-b7fcd000 r--p 0013f000 08:01 769046 /lib/i686/cmov/libc-2.11.2.so b7fcd000-b7fce000 rw-p 00141000 08:01 769046 /lib/i686/cmov/libc-2.11.2.so b7fce000-b7fd1000 rw-p b7fce000 00:00 0 b7fe2000-b7fe4000 rw-p b7fe2000 00:00 0 b7fe4000-b7fe5000 r-xp b7fe4000 00:00 0 [vdso] b7fe5000-b8000000 r-xp 00000000 08:01 1046552 /lib/ld-2.11.2.so b8000000-b8001000 r--p 0001a000 08:01 1046552 /lib/ld-2.11.2.so b8001000-b8002000 rw-p 0001b000 08:01 1046552 /lib/ld-2.11.2.so bffea000-c0000000 rw-p bffea000 00:00 0 [stack]

就本例而言,至少有三种办法搜索内存。

在GDB中调用被调试进程空间中的memmem()函数:

(gdb) p/x memmem( 0x08048000, 0x2000, "5120", 4 ) 0x804861c (gdb) p/x memmem( 0x08049000, 0x1000, "5120", 4 ) 0x804961c (gdb)

GDB 7.x开始支持find命令:

(gdb) find /b /10 0x08048000, 0x0804a000, 0x35, 0x31, 0x32, 0x30 0x804861c 0x804961c 2 patterns found. (gdb) find /b /10 0x08048000, 0x0804a000, 0x31, 0x33, 0x31, 0x34 0x8048500 0x8048620 0x8049500 0x8049620 4 patterns found.

过去的很多年里,我个人一直用define自己实现内存搜索:


define find1 set $count=0 set $address=$arg0 while (((unsigned int)$count<(unsigned int)$arg3)&&((unsigned int)$address<=(unsigned int)$arg1)) if ((unsigned char )$address==(unsigned char)$arg4) set $count=$count+1 x/1bx $address end set $address=$address+$arg2 end end document find1 find1 end define find2 set $count=0 set $address=$arg0 while (((unsigned int)$count<(unsigned int)$arg3)&&((unsigned int)$address<=(unsigned int)$arg1)) if ((unsigned short int )$address==(unsigned short int)$arg4) set $count=$count+1 x/1hx $address end set $address=$address+$arg2 end end document find2 find2 end define find4 set $count=0 set $address=$arg0 while (((unsigned int)$count<(unsigned int)$arg3)&&((unsigned int)$address<=(unsigned int)$arg1)) if ((unsigned int )$address==(unsigned int)$arg4) set $count=$count+1 x/1wx $address end set $address=$address+$arg2 end end document find4 find4 end define find8 set $count=0 set $address=$arg0 while (((unsigned int)$count<(unsigned int)$arg3)&&((unsigned int)$address<=(unsigned int)$arg1)) if ((unsigned long long )$address==(unsigned long long)$arg4) set $count=$count+1 x/1gx $address end set $address=$address+$arg2 end end document find8 find8 end define fill1 set $count=0 set $address=$arg0 while ((unsigned int)$count<(unsigned int)$arg1) set (unsigned char )$address=(unsigned char)$arg2 set $address=$address+1 set $count=$count+1 end end document fill1 fill1

end define fill2 set $count=0 set $address=$arg0 while ((unsigned int)$count<(unsigned int)$arg1) set (unsigned short int )$address=(unsigned short int)$arg2 set $address=$address+2 set $count=$count+1 end end document fill2 fill2
end define fill4 set $count=0 set $address=$arg0 while ((unsigned int)$count<(unsigned int)$arg1) set (unsigned int )$address=(unsigned int)$arg2 set $address=$address+4 set $count=$count+1 end end document fill4 fill4
end define fill8 set $count=0 set $address=$arg0 while ((unsigned int)$count<(unsigned int)$arg1) set (unsigned long long )$address=(unsigned long long)$arg2 set $address=$address+8 set $count=$count+1 end end document fill8 fill8
end


(gdb) help find4 find4 (gdb) help find8 find8 (gdb) find4 0x08048000 0x0804a000 4 10 0x34313331 0x8048500: 0x34313331 0x8048620: 0x34313331 0x8049500: 0x34313331 0x8049620 : 0x34313331 (gdb) find8 0x08048000 0x0804a000 4 10 0x3431333130323135 0x804861c: 0x3431333130323135 0x804961c : 0x3431333130323135