Stack Usage with MS Visual Studio 2005
Without Stack Protection
Before call to DoIt Registers EAX = EBX = ECX = FB EDX = 781C3C58 ESI = EDI = FC EIP = EE ESP = 0013FF40 EBP = 0013FFC0 EFL =
Stack before call to DoIt EBP 0013FFC0 ESP 0013FF40 argc argv local variables
Calling DoIt DoIt(szBuffer, iLength, iSize, iWhat,iWhere,iHow); EE mov eax,dword ptr [esp+18h] F2 mov ecx,dword ptr [esp+1Ch] F6 mov edx,dword ptr [esp+24h] FA mov esi,dword ptr [esp+28h] FE push eax FF push ecx mov ecx,dword ptr [esp+28h] lea ebx,[esp+34h] call DoIt (401000h) D add esp,14h pop edi pop esi
Registers before calling DoIt EAX = EBX = 0013FF6C ECX = EDX = ESI = EDI = FC EIP = ESP = 0013FF38 EBP = 0013FFC0 EFL =
Stack after call to Doit Two variables pushed on stack Return address
DoIt Deassembled void DoIt( char * szBuffer, int iLength, int iSize, int iWhat, int iWhere, int iHow){ push ebp iSize = iSize + iLength; add edx,esi xor eax,eax push edi lea edi,[eax+0Fh] lea esp,[esp]
DoIt Deassembled for(int i=0; i<15; i++){ iSize += i*iLength*iWhat++; mov ebp,eax imul ebp,ecx add edx,ebp add ecx, A add eax,esi C sub edi, F jne DoIt+10h (401010h) }
DoIt Deassembled char * myChar = szBuffer; while(*myChar){ cmp byte ptr [ebx], pop edi mov eax,ebx pop ebp je DoIt+3Bh (40103Bh) A lea ebx,[szBuffer] *(myChar++)+=0x01; add byte ptr [eax], add eax, cmp byte ptr [eax], jne DoIt+30h (401030h) }
DoIt Deassembled printf("Doit called with %i, %i, %i, %s, %i, %i \n",iLength, iSize, iWhat, szBuffer, iWhere, iHow); B mov eax,dword ptr [esp+8] F push eax mov eax,dword ptr [esp+8] push eax push ebx push ecx push edx push esi push offset string "Doit called with %i, %i, %i, %s"... (4020F4h) E call dword ptr [__imp__printf (4020A4h)] add esp,1Ch } ret
With Stack Protection
Prologue Create security cookie Push ebx and esi int _tmain(int argc, _TCHAR* argv[]) { sub esp,24h mov eax,dword ptr [___security_cookie (403000h)] xor eax,esp A mov dword ptr[esp+20h],eax E push ebx F push esi
Stack Before Calling DoIt esp ebp
Stack Before Calling DoIt esp 0013FF3C ebp 0013FFC0 Local variables on stack. Notice the sparse layout
Preparation for calling DoIt DoIt(szBuffer, iLength, iSize, iWhat,iWhere,iHow); F9 mov eax,dword ptr [esp+28h] FD mov ecx,dword ptr [esp+20h] mov edx,dword ptr [esp+1Ch] mov esi,dword ptr [esp+24h] push eax A push ecx B mov ecx,dword ptr [esp+20h] F lea ebx,[esp+34h] call DoIt (401000h)
Stack after call to doit esp 0013FF30 ebp 0013FFC0 Two variables passed on stack Return Address
Register contents Register used to pass remaining variables EAX = EBX = 0013FF68 (address of string) ECX = EDX = ESI = EDI = FC EIP = ESP = 0013FF30 EBP = 0013FFC0 EFL =
Call of DoIt void DoIt( char * szBuffer, int iLength, int iSize, int iWhat, int iWhere, int iHow){ push ebp iSize = iSize + iLength; add edx,esi xor eax,eax push edi lea edi,[eax+0Fh] lea esp,[esp]
Call of Doit (cont) for(int i=0; i<15; i++){ iSize += i*iLength*iWhat++; mov ebp,eax imul ebp,ecx add edx,ebp add ecx, A add eax,esi C sub edi, F jne DoIt+10h (401010h) }
Call of Doit (cont) char * myChar = szBuffer; while(*myChar){ cmp byte ptr [ebx], pop edi mov eax,ebx pop ebp je DoIt+3Bh (40103Bh) A lea ebx,[szBuffer]
Call of Doit (cont) *(myChar++)+=0x01; add byte ptr [eax], add eax, cmp byte ptr [eax], jne DoIt+30h (401030h) }
Call of Doit (cont) *(myChar++)+=0x01; add byte ptr [eax], add eax, cmp byte ptr [eax], jne DoIt+30h (401030h) }
Call of Doit (cont) printf("Doit called with %i, %i, %i, %s, %i, %i \n",iLength, iSize, iWhat, szBuffer, iWhere, iHow); B mov eax,dword ptr [esp+8] F push eax mov eax,dword ptr [esp+8] push eax push ebx push ecx push edx push esi push offset string "Doit called with %i, %i, %i, %s"... (402104h) E call dword ptr [__imp__printf (4020A4h)] add esp,1Ch } ret
tmain epilogue return 0; } mov ecx,dword ptr [esp+48h] C add esp,14h F pop edi pop esi pop ebx xor ecx,esp xor eax,eax call __security_check_cookie (40112Fh) B add esp,2Ch E ret