Let's first look at the static compilation result of a simple code:
#include "stdafx.h"int _tmain(int argc, _TCHAR* argv[]){01041380 55 push ebp 01041381 8B EC mov ebp,esp 01041383 81 EC C0 00 00 00 sub esp,0C0h 01041389 53 push ebx 0104138A 56 push esi 0104138B 57 push edi 0104138C 8D BD 40 FF FF FF lea edi,[ebp-0C0h] 01041392 B9 30 00 00 00 mov ecx,30h 01041397 B8 CC CC CC CC mov eax,0CCCCCCCCh 0104139C F3 AB rep stos dword ptr es:[edi] return 0;0104139E 33 C0 xor eax,eax }010413A0 5F pop edi 010413A1 5E pop esi 010413A2 5B pop ebx 010413A3 8B E5 mov esp,ebp 010413A5 5D pop ebp 010413A6 C3 ret
EBP is a so-called frame pointer pointing to the top of the current activity record (bottom of the previous activity record), that is, ESP at the bottom of the stack is a so-called Stack pointer, point to the bottom of the current activity record (the top of the next activity record to be inserted), that is, the top of the stack
Ret: use the data in the stack to modify the IP value to achieve near Transfer
(IP) = (SS) * 16 + (SP) // Stack pointer. This command is equivalent to the output stack (SP) = (SP) + 2 in the 16-bit wordlength system; another usage: ret n (n is an integer), equivalent to (IP) = (SS) * 16 + (SP) = (SP) + 2 (SP) = (SP) + nlea: load effect address, take the valid address lea reg 16, mem16 send the 16-bit address of memory operand mem to the specified register such as lea AX, BUF transfers the address specified by BUF in the memory to AX. If it is mov AX and BUF, it transmits the content referred to by BUF to AXstos dst, and dst is a destination address mov ecx, 30 hrep stos dword ptr es: [edi] stos is to store the content in the register EAX to the memory unit (address ES: EDI) dword meaning dual-word, A 32-bit rep can be the prefix of any character passing command (cmps, lods, movs, scas, stos, The subsequent string commands are repeatedly executed until the value of ecx is 0. Execute the command ecx minus 1 push: push reg (ESP) = (ESP) on the inbound stack) -4 // 32-bit system mov SS: [ESP], regpop: Output stack mov reg, SS: [ESP] (ESP) = (ESP) + 4 the push and pop commands only perform word operations. The words here refer to the default calling method for C for the system character length. The stack always calls the reverse order of parameters (from right to left) and the called party restores the stack. These parameters are aligned to the machine font length. This call is the default C-mode function calling rule of the C compiler. It refers to the method for passing parameters and returning parameters between the caller and the called function, commonly used methods in windows include Pascal, WINAPI (_ stdcall), and C (_ cdecl ). _ Cdecl C call rules: 1) the parameter enters the stack from right to left. 2) after the function is returned, the caller clears the stack. Therefore, this method often produces a large executable program _ stdcall, also known as WINAPI. The Calling rule is: 1) the parameter enters the stack from right to left. 2) the stack is cleaned up before the called function returns, the generated code is smaller than cdecl. Pascal calling rules are mainly used in the win16 library functions. Currently, there is basically no need to use Quick calling methods (_ fastcall) in the windows Kernel) the C ++ compiled code contains the this call method (_ thiscall ). In windows, eax stores the returned values. We can see that in the _ cdecl mode, the called function requires the following work: 1) Save ebp2) Save esp to ebp. The above two steps are as follows:; save ebp, put esp into ebp. At this time, both ebp and esp are the top pushes of ebpmov ebp and esp3) to save local variables in the stack when this function is called. Method: reduce esp by a number, which means it is pushed into a bunch of variables. To recover the esp, you only need to restore it to the data saved in the ebp. 4) Save ebx, esi, and edi to the stack. After the function is called, it is restored. The corresponding code is as follows: Move esp down to a range, which is equal to releasing a new space in the stack to store the local variable sub esp, 0 cchpush ebx; the following three registers are saved to push esipush edi5) initialize the local variable area to 0 cccccccch. 0cch is actually the machine code of the int 3 command, which is a breakpoint interrupt command. Because local variables cannot be executed, if they are executed, it indicates that the program is wrong. In this case, an interruption occurs to prompt the developer. Unique operations for compiling dubug versions by VC. Related code: lea edi, [ebp-0cch]; was originally to mov edi, ebp-0cch, but mov does not support parameters such as ebp-0cch; the purpose is to save all local variables and initialize them to 0 cccccccchmov ecx, 30 hmov eax, 0 cccccccchrep stos dword ptr es: [edi]; string written to windows, int3 is an interruption left for debugging tools. After the debugging tool runs, it replaces the int3 Vector so that the interrupt mode executes its own code. When you Debug a program in a single step (such as the command p in Debug), the debugging tool will change the next instruction of the Code to int 3, in this way, the code of the debugging tool will be executed after the current line of code is executed, instead of continuing to execute, so as to achieve single-step debugging. Some software may estimate the use of int3 to prevent hackers from cracking their programs. In this way, the use of int3 debugging tools will not be able to debug their programs normally. 6) then do what should be done in the function. 7) Restore ebx, esi, edi, esp, ebp, and finally return. The Code is as follows: pop edi; restore edi, esi, ebxpop esipop ebxmov esp, ebp; restore the original ebp and esp, so that the previous called function can normally use pop ebpret if there is a return value, put the returned value into eax before running the ret command, and obtain the returned value through eax externally.