mov esi, esp ?????????????

Before invoking any function the stack pointer will be moved into esi (source index) for eg:
int nStartup = ::WSAStartup(0x202, &wsadata);
1003898D mov esi,esp // Disassembled code

Why is it so?
«1

Comments

  • : Before invoking any function the stack pointer will be moved into esi (source index) for eg:
    : int nStartup = ::WSAStartup(0x202, &wsadata);
    : 1003898D mov esi,esp // Disassembled code
    :
    : Why is it so?
    :

    This is called making a "stack frame". It simplifies accessing parameters of a function. Also, it makes it easier to handle memory allocated on the stack by a subroutine.

    For example, we have a function Multiply. It takes 2 parameters and returns the result in eax.
    [code]
    Multiply proc Integer1:DWORD, Integer2:DWORD

    mov esi, esp ; Save the stack pointer

    ; edx is used, but we want to save it, so we push it on the
    ; stack, this will change the value of esp, the stack pointer,
    ; but esi will remain the same
    push edx

    ; The parameters on the stack can now be accessed
    ; relative to esi
    mov eax, [esi+8] ; Integer1
    mov edx, [esi+0ch]; Integer2
    mul edx

    ; We can restore edx now, meanwhile esp has changed,
    ; but esi has remained the same throughout the procedure.
    pop edx

    ret

    Multiply endp[/code]You can save esp anywhere you like, normally it is saved into ebp (the base pointer).

    I hope I got it right, good luck!
  • [b][red]This message was edited by Asesh at 2006-7-27 11:30:40[/red][/b][hr]
    It's the ebp register that is used to access local variables and arguments to functions not esp (or esi after moving esp into esi). Thanks for your reply


  • : [b][red]This message was edited by Asesh at 2006-7-27 11:30:40[/red][/b][hr]
    : It's the ebp register that is used to access local variables and arguments to functions not esp (or esi after moving esp into esi). Thanks for your reply
    :
    :
    :
    [blue]You can use any register, even ESP itself for local vars.
    In fact, that is how INTEL recommends it to do:
    [code]
    foo:
    sub esp, 8 ; Allocate two DWORD variables as locals

    ; --- Store zeroes into these vars:

    xor eax, eax
    mov [esp], eax
    mov [esp+4], eax

    add esp, 8 ; Release variables
    ret
    [/code]
    [/blue]
  • : : [b][red]This message was edited by Asesh at 2006-7-27 11:30:40[/red][/b][hr]
    : : It's the ebp register that is used to access local variables and arguments to functions not esp (or esi after moving esp into esi). Thanks for your reply
    : :
    : :
    : :
    : [blue]You can use any register, even ESP itself for local vars.
    : In fact, that is how INTEL recommends it to do:
    : [code]
    : foo:
    : sub esp, 8 ; Allocate two DWORD variables as locals
    :
    : ; --- Store zeroes into these vars:
    :
    : xor eax, eax
    : mov [esp], eax
    : mov [esp+4], eax
    :
    : add esp, 8 ; Release variables
    : ret
    : [/code]
    : [/blue]
    :

    I would recommend this only if you don`t push/pop or call other functions in the subroutine. I`ve tried coding without a stack frame once and found it excessively difficult as esp was changing all the time throughout the function.

    I guess it`s just a matter of whether or not you`re willing to think along with the esp register changes, but I don`t see any benefit other than saving the few bytes for the frame setup.

    This might be iteresting to read:
    http://blogs.msdn.com/oldnewthing/archive/2004/01/16/59415.aspx

  • [b][red]This message was edited by Asesh at 2006-7-28 9:55:9[/red][/b][hr]
    Can you explain me this: 10038907 mov eax,0CCCCCCCCh (Disassembled code in VC++). I see this in every procedure just before the local variables are declared.
  • Without any further information I can only guess that it's for somehow writing out breakpoint instructions in multiples of four, perhaps in case of a buffer overflow with the intention of remotely executing code. It's probably something less exciting though.
  • : [b][red]This message was edited by Asesh at 2006-7-28 9:55:9[/red][/b][hr]
    : Can you explain me this: 10038907 mov eax,0CCCCCCCCh (Disassembled code in VC++). I see this in every procedure just before the local variables are declared.
    :

    This is used for debugging of certain bugs. In MSVC`s debug mode, each function gets additional bytes in its stack frame, which is filled with 0CCh. When an array overrun or some similar bug occurs, then the CC`s get overwritten, so it will be easy to spot this.
    Also, this helps to track down uninitialized variables (They`ll be CC`s).
    Furthermore, if a program somehow executes the stack, it will hit an INT 3 breakpoint (0CCh in machine code)

    Im not sure if this is entirely accurate, but that`s what I found with Google.
  • : [b][red]This message was edited by Asesh at 2006-7-27 11:30:40[/red][/b][hr]
    : It's the ebp register that is used to access local variables and arguments to functions not esp (or esi after moving esp into esi). Thanks for your reply
    :
    :
    :
    [code]
    ;c function long foo(par1, par2)
    ;{ long var1; }

    push par2 ;ebp+12
    push par1 ;ebp+8
    call foo ;push eip ebp+4

    ;foo function
    push ebp ;ebp+0
    mov ebp, esp ;stack frame
    sub esp, 4 ;allocate local

    ;parameters=ebp+8 and 12
    ;locals=ebp-4

    add esp, 4 ;deallocate local
    mov esp, ebp ;destroy stack frame
    pop ebp ;restore ebp
    ret 8 ;return 8 bytes for 2 parameters to fix stack
    [/code]
    [green]
    Should probably look similiar to this but you can vary it. If you are incorporating functions for an higher level language, then, you need to see what calling conventions that language uses and structure your functions from there if you don't already know that. I know windows uses _stdcall, c uses _cdecl, and there are others like _fastcall.
    [/green]

  • Thanks a lot guys :)
  • sub esp, 4h will reserve 4 bytes for local variables if it's so then why will VC++ reserve 192 bytes (sub esp,0C0h) for local variables even if local variables doesn't exist?
  • : sub esp, 4h will reserve 4 bytes for local variables if it's so then why will VC++ reserve 192 bytes (sub esp,0C0h) for local variables even if local variables doesn't exist?
    :
    [blue]You always look at the disassembled DEBUG code - you should try to look at the optimized RELEASE code. All these things you finding - you will not find them in RELEASE. However, remember that compiler optimizes the code which is not referenced. Also, put the hardware breakpoint in the place you want to look at:
    [code]
    void some_local_vars ()
    {
    PCHAR pstr = "Message!!!!!!!!!!!!!!";
    _asm int 3 // Hardware breakpoint
    MessageBox (0, pstr, "Report", MB_OK);
    }
    [/code]
    Now, build it in RELEASE and run it in debugger - if debugger says "No debug info" - click "Run anyway". The debugger will stop at this _asm instruction and show the code in ASM. Look before the breakpoint - you should see how the stack allocated for local variables (pstr).[/blue]
  • [b][red]This message was edited by Asesh at 2006-7-30 7:55:15[/red][/b][hr]
    [b][red]This message was edited by Asesh at 2006-7-29 5:10:11[/red][/b][hr]
    : : sub esp, 4h will reserve 4 bytes for local variables if it's so then why will VC++ reserve 192 bytes (sub esp,0C0h) for local variables even if local variables doesn't exist?
    : :
    : [blue]You always look at the disassembled DEBUG code - you should try to look at the optimized RELEASE code. All these things you finding - you will not find them in RELEASE. However, remember that compiler optimizes the code which is not referenced. Also, put the hardware breakpoint in the place you want to look at:
    : [code]
    : void some_local_vars ()
    : {
    : PCHAR pstr = "Message!!!!!!!!!!!!!!";
    : _asm int 3 // Hardware breakpoint
    : MessageBox (0, pstr, "Report", MB_OK);
    : }
    : [/code]
    : Now, build it in RELEASE and run it in debugger - if debugger says "No debug info" - click "Run anyway". The debugger will stop at this _asm instruction and show the code in ASM. Look before the breakpoint - you should see how the stack allocated for local variables (pstr).[/blue]
    :

    It shows: Unhandled exception at 0x00433419 in cApp_1.exe: User breakpoint and it's bcoz of the interruptr 3.

    And when I disassembled the application (Release mode) I don't see any code for setting up the stack frame and allocation of stack for local variables. I wonder why

    int _tmain()
    {
    DWORD dwNumber = 12;
    return 0;
    004010D0 xor eax,eax
    }
    004010D2 ret

  • It shows: Unhandled exception at 0x00433419 in cApp_1.exe: User breakpoint and it's bcoz of the interrupt 3.
    :
    : And when I disassembled the application (Release mode) I don't see any code for setting up the stack frame and allocation of stack for local variables. I wonder why
    :
    : int _tmain()
    : {
    : DWORD dwNumber = 12;
    : return 0;
    : 004010D0 xor eax,eax
    : }
    : 004010D2 ret
    :

    Hello no reply?
  • [b][red]This message was edited by anthrax11 at 2006-8-2 9:28:4[/red][/b][hr]
    :
    : It shows: Unhandled exception at 0x00433419 in cApp_1.exe: User breakpoint and it's bcoz of the interrupt 3.

    [green]INT 3 is only for debugging purposes, that is, the debugger handles this exception. If you run the program without the debugger, Windows simply halts the execution of the program. Use INT 3 if you want to set a breakpoint for the debugger.[/green]
    : :
    : : And when I disassembled the application (Release mode) I don't see any code for setting up the stack frame and allocation of stack for local variables. I wonder why
    : :
    : : int _tmain()
    : : {
    : : DWORD dwNumber = 12;
    : : return 0;
    : : 004010D0 xor eax,eax
    : : }
    : : 004010D2 ret
    : :
    [green]_tmain is not really a subfunction, it just denotes the starting point of the program. In other programming languages, the Main function [b]may[/b] be a function, that is called by the startup code generated by the compiler.[/green]
    :
    : Hello no reply?
    :
    [green]Nobody is an infinite source of wisdom. I made this reply based mostly on logical assumptions, because you so eagerly waited for a reply ;-)[/green]


  • [blue]From latest VS 2005: (I had to do a small meaningless loop in a 'foo()' to avoid inlining.)[/blue]
    [code]
    #include

    void foo ()
    {
    char sMsg [] = "My Own Text Message...";

    _asm int 3

    for (int i=3; i<6; i++)
    {
    sMsg [i] = sMsg [i+8];
    }
    printf (sMsg);
    }

    int main ()
    {
    foo ();
    return 0;
    }
    [/code]
    [code]
    --- d:alexprojectsvsnet2005 estasm estasmmain.cpp ------------------------
    00401005 xor byte ptr [eax],al
    00401008 xor eax,esp
    0040100A mov dword ptr [esp+18h],eax
    0040100E push esi
    0040100F push edi
    char sMsg [] = "My Own Text Message...";
    00401010 mov ecx,5
    00401015 mov esi,offset string "My Own Text Message..." (4020E4h)
    0040101A lea edi,[esp+8]
    0040101E rep movs dword ptr es:[edi],dword ptr [esi]
    00401020 movs word ptr es:[edi],word ptr [esi]
    00401022 movs byte ptr es:[edi],byte ptr [esi]

    _asm int 3
    00401023 int 3

    for (int i=3; i<6; i++)
    {
    sMsg [i] = sMsg [i+8];
    00401024 mov al,byte ptr [esp+13h]
    00401028 mov cl,byte ptr [esp+14h]
    0040102C mov dl,byte ptr [esp+15h]
    00401030 mov byte ptr [esp+0Bh],al
    }
    printf (sMsg);
    00401034 lea eax,[esp+8] [b]//Addr. of 'sMsg'[/b]
    00401038 push eax
    00401039 mov byte ptr [esp+10h],cl
    0040103D mov byte ptr [esp+11h],dl
    00401041 call dword ptr [__imp__printf (40209Ch)]
    }
    00401047 mov ecx,dword ptr [esp+24h]
    0040104B add esp,4 [b]//Restoring stack frame[/b]
    0040104E pop edi
    0040104F pop esi
    00401050 xor ecx,esp
    00401052 call __security_check_cookie (401068h)
    00401057 add esp,1Ch
    0040105A ret
    --- No source file -------------------------------------------------------------
    0040105B int 3
    0040105C int 3
    0040105D int 3
    0040105E int 3
    0040105F int 3
    --- d:alexprojectsvsnet2005 estasm estasmmain.cpp ------------------------

    int main ()
    {
    foo ();
    00401060 call foo (401000h)
    return 0;
    00401065 xor eax,eax
    }
    00401067 ret
    [/code]

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories