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