Any suggestions, examples and error reports are accepted

As the subject says, this is just a short brief about common directives which I refer sometimes when I guess something is missing...













THE STACK (common usage):
    - is used to store and cast data
    - should be aligned to DWORD (32 bits, 4 bytes)
    - ESP and EBP registers are used to move through the stack
    - ESP is the stack pointer and EBP is the base pointer used by functions
    - invoke a function means store one return address and parameters (if any) to the stack
    - declare local variables means create a stack frame subtracting a specified number of bytes to ESP
    - local variables differ from any else stored to the stack in the fact that they have a negative displacement from EBP
















STACK RELATED DIRECTIVES (common usage):
    - PUSH : stores temporary data to the stack subtracting 4 bytes to ESP
    - PUSHAD: pushes all the registers in the sequence EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI
    - PUSHFD: pushes the flag registers (EFLAGS)
    - POP : casts data from the stack adding 4 bytes to ESP, commonly used to balance PUSH
    - POPAD: pops 32 bytes to the registers in the sequence EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX
    - POPFD: pops 4 bytes to the flag registers (EFLAGS)
    - CALL : pushes the address after itself and jumps to the direct/indirect address
    - LEAVE: removes the stack frame restoring ESP and EBP back to their condition before the stack frame is initialized
    - RET : jumps to the address at ESP adding 4 bytes to ESP plus the parameters size in bytes
    NOTES:
    - RET is the STDCALL calling convention, while C calling convention do only RET leaving the caller to adjust ESP





Example_Function proc var1:DWORD,var2:DWORD

******************************************************************************
*   BEFORE COMPILING                AFTER COMPILING                         *
******************************************************************************

                                    PUSH EBP (current value of ebp)
                                    MOV EBP,ESP (sets the base pointer)

    local new_var:DWORD             ADD ESP,-4 (creates the stack frame)

                            NOTES:  /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
                                    has the local variable
                                    has the pushed value of ebp
                                    has the address where return to
                                    has the first parameter
                                    has the second parameter
                                    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

    mov edx,new_var                 MOV EDX,DWORD PTR SS:

    mov eax,var1                    MOV EAX,DWORD PTR SS:
    mov ecx,var2                    MOV ECX,DWORD PTR SS:

                                    LEAVE (restores esp and ebp)
    Ret                             RET 8 ("pops" the EIP "releasing" 8 bytes)

******************************************************************************

Example_Function endp




PUSH EAX acts like: mov dword ptr ss:,eax
                    add esp,-4

PUSH directive: first moves the given value to the 32 bits wide address before the stack pointer ESP,
                and second adjusts the register ESP.


The correct conceptual maneuver of PUSH ESP is "first moves..., and second adjusts...": mov dword ptr ss:,esp
                                                                                        add esp,-4

                                          MOV DWORD PTR SS:,ESP
-------------------------------------     --------------------------------------
|   ESP - 4   0012FFBC   11111111   |     |   ESP - 4   0012FFBC   0012FFC0    |
| > ESP       0012FFC0   FFFFFFFF   |     | > ESP       0012FFC0   FFFFFFFF    |
|   ESP + 4   0012FFC4   00000000   |     |   ESP + 4   0012FFC4   00000000    |
|   ESP + 8   0012FFC8   00000000   |     |   ESP + 8   0012FFC8   00000000    |
-------------------------------------     --------------------------------------

                                          ADD ESP,-4
                                          -------------------------------------
                                          | > ESP       0012FFBC   0012FFC0   |
                                          |   ESP + 4   0012FFC0   FFFFFFFF   |
                                          |   ESP + 8   0012FFC4   00000000   |
                                          |   ESP + C   0012FFC8   00000000   |
                                          -------------------------------------

The wrong conceptual maneuver of PUSH ESP is "first adjusts..., and second moves...": add esp,-4
                                                                                      mov dword ptr ss:,esp

                                          ADD ESP,-4
-------------------------------------     --------------------------------------
|   ESP - 4   0012FFBC   11111111   |     | > ESP       0012FFBC   11111111    |
| > ESP       0012FFC0   FFFFFFFF   |     |   ESP + 4   0012FFC0   FFFFFFFF    |
|   ESP + 4   0012FFC4   00000000   |     |   ESP + 8   0012FFC4   00000000    |
|   ESP + 8   0012FFC8   00000000   |     |   ESP + C   0012FFC8   00000000    |
-------------------------------------     --------------------------------------

                                          MOV DWORD PTR SS:,ESP
                                          -------------------------------------
                                          | > ESP       0012FFBC   0012FFBC   |
                                          |   ESP + 4   0012FFC0   FFFFFFFF   |
                                          |   ESP + 8   0012FFC4   00000000   |
                                          |   ESP + C   0012FFC8   00000000   |
                                          -------------------------------------



POP EAX acts like: add esp,4
                   mov eax,dword ptr ss:

POP directive: first adjusts the register ESP,
               and second moves the value from the 32 bits wide address before the stack pointer ESP.


The correct conceptual maneuver of POP ESP is "first adjusts..., and second moves...": add esp,4
                                                                                       mov esp,dword ptr ss:

                                          ADD ESP,4
-------------------------------------     --------------------------------------
| > ESP       0012FFBC   0012FFC0   |     |   ESP - 4   0012FFBC   0012FFC0    |
|   ESP + 4   0012FFC0   FFFFFFFF   |     | > ESP       0012FFC0   FFFFFFFF    |
|   ESP + 8   0012FFC4   00000000   |     |   ESP + 4   0012FFC4   00000000    |
|   ESP + C   0012FFC8   00000000   |     |   ESP + 8   0012FFC8   00000000    |
-------------------------------------     --------------------------------------

                                          MOV ESP,DWORD PTR SS:
                                          -------------------------------------
                                          |   ESP - 4   0012FFBC   0012FFC0   |
                                          | > ESP       0012FFC0   FFFFFFFF   |
                                          |   ESP + 4   0012FFC4   00000000   |
                                          |   ESP + 8   0012FFC8   00000000   |
                                          -------------------------------------

The wrong conceptual maneuver of POP ESP is "first moves..., and second adjusts...": mov esp,dword ptr ss:
                                                                                     add esp,4

                                          MOV ESP,DWORD PTR SS:
-------------------------------------     -------------------------------------
| > ESP       0012FFBC   0012FFC0   |     |   ESP - 4   0012FFBC   0012FFC0   |
|   ESP + 4   0012FFC0   FFFFFFFF   |     | > ESP       0012FFC0   FFFFFFFF   |
|   ESP + 8   0012FFC4   00000000   |     |   ESP + 4   0012FFC4   00000000   |
|   ESP + C   0012FFC8   00000000   |     |   ESP + 8   0012FFC8   00000000   |
-------------------------------------     -------------------------------------

                                          ADD ESP,4
                                          -------------------------------------
                                          |   ESP - 8   0012FFBC   0012FFC0   |
                                          |   ESP - 4   0012FFC0   FFFFFFFF   |
                                          | > ESP       0012FFC4   00000000   |
                                          |   ESP + 4   0012FFC8   00000000   |
                                          -------------------------------------



LEAVE acts like: mov esp,ebp
                 pop ebp

                 - or -

                 mov esp,ebp
                 add esp,4
                 mov ebp,dword ptr ss:



RET acts like: jmp dword ptr ss:
                       add esp,4+



Boomerang
Monday, February 02, 2009
Posted on 2009-02-01 23:02:53 by Boomerang
- is used to store and cast data
cast data? What is this?

- should be aligned to DWORD (32 bits, 4 bytes)
unless you're programming for 64-bit windows (fair enough, you're talking 32-bit)

- ESP and EBP registers are used to move through the stack
you can use ESP by itself, or any register not just EBP

- ESP is the stack pointer and EBP is the base pointer used by functions
EBP is usually used in masm when you have parameters or locals on the stack to access.
If you can keep track of ESP, you can use stuff like "push ", but debugging can be a bitch.
Just use "option prologue:none" and then there's no messing around with EBP, means you can use it at will.

I am biased though - I hate macros and generally avoid using 'invoke'.
When you need to push each parameter it makes you think (instead of 'invoke dword,dword,dword...)
Posted on 2009-02-02 00:16:25 by sinsi

- is used to store and cast data
cast data? What is this?

- should be aligned to DWORD (32 bits, 4 bytes)
unless you're programming for 64-bit windows (fair enough, you're talking 32-bit)

- ESP and EBP registers are used to move through the stack
you can use ESP by itself, or any register not just EBP

- ESP is the stack pointer and EBP is the base pointer used by functions
EBP is usually used in masm when you have parameters or locals on the stack to access.
If you can keep track of ESP, you can use stuff like "push ", but debugging can be a bitch.
Just use "option prologue:none" and then there's no messing around with EBP, means you can use it at will.

I am biased though - I hate macros and generally avoid using 'invoke'.
When you need to push each parameter it makes you think (instead of 'invoke dword,dword,dword...)


- to cast: ...to throw out...
  There are really many uses of this verb. I used it just to give an idea of what happens.
  Obviously when you "throw out" something from the stack it remains in the stack, even with a POP.
  Maybe the use of a debugger is the best solution to see how the stack works - "I know it when I see it"
  Another solution could be give some visual examples (tables, images, preformatted text) which can give an idea of some basic concepts.

- 32 bits / 64 bits
  I you have any good example about 64 bits registers (push, pop, etc...), please post it

- ESP and EBP
  The solutions to use the stack could be a lot...
  ESP is the stack pointer of choice used to move through the stack.
  Usually (common usage) EBP is the base pointer used by functions.

- OPTION PROLOGUE:NONE, OPTION EPILOGUE:NONE, OPTION PROLOGUE:PROLOGUEDEF, OPTION EPILOGUE:EPILOGUEDEF
  This could be a good idea to post an example, something like: BEFORE COMPILING / AFTER COMPILING


At last, an example about invoke and call.

***********************************************************************************
*   BEFORE COMPILING                       AFTER COMPILING                      *
***********************************************************************************

    invoke Example_Function,eax,ecx        PUSH ECX
                                            PUSH EAX
                                            CALL 00456379 (address of the function)

    push ecx                                PUSH ECX
    push eax                                PUSH EAX
    call Example_Function                  CALL 00456379 (address of the function)

***********************************************************************************
Posted on 2009-02-02 11:52:04 by Boomerang