直接插上CGfsb伪代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| int __cdecl main(int argc, const char **argv, const char **envp) { int buf; // [esp+1Eh] [ebp-7Eh] int v5; // [esp+22h] [ebp-7Ah] __int16 v6; // [esp+26h] [ebp-76h] char s; // [esp+28h] [ebp-74h] unsigned int v8; // [esp+8Ch] [ebp-10h]
v8 = __readgsdword(0x14u); setbuf(stdin, 0); setbuf(stdout, 0); setbuf(stderr, 0); buf = 0; v5 = 0; v6 = 0; memset(&s, 0, 0x64u); puts("please tell me your name:"); read(0, &buf, 0xAu); puts("leave your message please:"); fgets(&s, 100, stdin); printf("hello %s", &buf); puts("your message is:"); printf(&s); if ( pwnme == 8 ) { puts("you pwned me, here is your flag:\n"); system("cat flag"); } else { puts("Thank you!"); } return 0; }
|
我要调试的是printf指令,这里有两个,我们先调试第一个 printf(“hello %s”, &buf);
我们将断点先下在第一个断点处,名字输入sakura,信息填message,回车
你会在backtrace处发现两个栈帧,__libc_start_main栈帧和main栈帧
注意这个时候的栈信息,栈里面先把sakura对应的地址和格式化字符串分别入栈
通过step指令由main栈帧进入printf栈帧
此时的backtrace是
此时的栈是
其中栈中的第一行为返回地址,这是创建printf栈帧后才出现的,其余两个参数不变。
我们再输入frame f 1
使程序回到main栈帧,重复执行上述断点
你会发现,返回地址无了。
注意
gdb调试时,要分清哪些是地址,哪些是数据,其中字符串信息的传递是通过指向字符串的地址传递的。