对于push,pop,call,leave,ret的理解
push指令
比如push ebp就是把ebp的值放在esp所指的地方,然后esp-4(32位,以下均为32位)。
pop指令
pop ebp就是把esp所指的地方的值给ebp,然后esp+4
call指令
call函数的时候,把eip的下一行存到esp所指的位置,然后esp-4
leave指令
leave指令可以等价于mov esp,ebp;pop ebp
ret指令
等价于pop eip
调试例子
下载:https://github.com/ctf-wiki/ctf-challenges/raw/master/pwn/stackoverflow/ret2text/bamboofox-ret2text/ret2text
该程序来自于ctfwiki中的基本ROP-ret2text
直接使用pwndbg启动起来,一直ni到我们需要的,比如call puts函数:

此时的esp为0xffffcf90,ebp为0xffffd018,我们si进去:

执行完call后,此时的esp为0xffffcf8c,esp指向的值为0x80486a7,ebp保持不变。
未执行call前,eip的下一行为0x80486a7,执行call时,将eip的下一行即0x80486a7给esp所指向的值,然后esp-4(0xffffcf90-4=0xffffcf8c)。
接下来ni到push 0x18:

要执行push 0x18,push就是把要push的东西给esp所指向的值,然后esp-4,所以指向完push 0x1后,esp会变为0xffffcf88,而esp所指向的值会变为0x18:

接下来再看push eax:

eax的值为0x0,esp的值为0xffffcf84,push就是把要push的东西给esp所指向的值,然后esp-4,所以esp所指向的值会变为0x0,esp变为0xffffcf84-4=0xffffcf80:
再ni到pop edx:
pop某个东西就是把esp所指向的值给这个东西,esp再加4,此时为pop edx,就是把esp当前所指向的值0xf7e1f9c4给edx,esp-4=0xffffcf78+4=0xffffcf7c,如下图:
此时的edx变为0xf7e1f9c4,esp变为0xffffcf7c。接着向下看:
ret就是相当于pop eip,要执行ret 0xc的话,eip接下来会变为esp所指向的值0xf7c73200,esp会变为0xffffcf7c+0xc+4=0xffffcf8c(如果没有0xc的话,就不用加)如下图:

直接finish出来,去找最后的leave:

leave就是等价于mov esp,ebp;pop ebp
先来看当前的:esp为0xffffcf90,ebp为0xffffd018,可以先用telescope 0xffffd018找一下ebp所指向的值:
由于由于leave相当于一次执行两步,先来分析mov esp,ebp,执行完这个后,esp会变为0xffffd018,此时再pop ebp,就是把esp所指向的值(0x0)给ebp,然后esp+4变为0xffffd018+4=0xffffd01c:

可以看到,ebp变为0,esp变为0xffffd01c。调试分析结束,由于我也刚学不久,如果有错误的地方,大佬勿喷。


浙公网安备 33010602011771号