前言:比起ESP寻址的方式,EBP需要去理解下其中的含义,所以记录下!
个人理解:
1、EBP和ESP之间的关系
起初-1 相隔 ----> 在没进CALL之前,会先将调用CALL的参数先压入堆栈,堆栈中EBP寄存器中的地址是在ESP寄存器中的地址之下, 自己理解为相隔 中间-2 相等 ----> 进入CALL之后,EBP寄存器会先把保存的地址先压入堆栈中保存,然后再保存ESP寄存器中的地址,这里就可以理解为ESP不变,将EBP进行提升栈顶的操作 中间-3 相隔 ----> 因为调用了CALL,那么就会进行一系列的运算,那么肯定需要堆栈中的空间,那么ESP地址就会上升 中间-4 相等 ----> 当调用完了之后,当前EBP寄存器保存的就是之前的ESP的地址,现在就会返回给ESP寄存器,堆栈需要保持平衡 末尾-5 相隔 ----> 堆栈到现在还没有完全保持平衡,还需要把EBP的地址返回给EBP寄存器,然后出了CALL之后,还需要指令进行外/内平衡的操作保持真正的堆栈平衡!
汇编体现:
00401000 > 6A 01 push 0x1 ; 压入堆栈0x1 00401002 6A 02 push 0x2 ; 压入堆栈0x2 00401004 E8 3C000000 call CRACKME.00401045 ; 调用call 00401045 00401009 83C4 08 add esp,0x8 ; 恢复两个参数的堆栈数,所以+8 0040100C . 6A 00 push 0x0 ; / 0040100E . 68 F4204000 push CRACKME.004020F4 ; | 00401013 . E8 A6040000 call <jmp.&USER32.FindWindowA> ; \ 00401018 . 0BC0 or eax,eax 0040101A . 74 01 je short CRACKME.0040101D 0040101C . C3 retn 0040101D > C705 64204000>mov dword ptr ds:[0x402064],0x4003 00401027 . C705 68204000>mov dword ptr ds:[0x402068],CRACKME.WndP>; è 00401031 . C705 6C204000>mov dword ptr ds:[0x40206C],0x0 0040103B . C705 70204000>mov dword ptr ds:[0x402070],0x0 00401045 55 push ebp ; 保存原始ebp地址 00401046 8BEC mov ebp,esp ; 再让当前ebp中保存esp的地址 00401048 83EC 10 sub esp,0x10 ; 提升栈顶,用于保存其他要用到的东西,当前没有体现用处 0040104B 8B45 08 mov eax,dword ptr ss:[ebp+0x8] ; CRACKME.<ModuleEntryPoint> 0040104E 0345 0C add eax,dword ptr ss:[ebp+0xC] 00401051 8BE5 mov esp,ebp ; 把之前保存的ebp返回给esp 00401053 5D pop ebp ; 再把之前压入的ebp地址返回给ebp寄存器 00401054 C3 retn ; 跳出
来源:https://www.cnblogs.com/zpchcbd/p/12307298.html