Search code examples
assemblystructurelocal-variablesfasm

Local variable structure FASM


So I was reading the manual on how to create structures..

At first, I did:

struc point X, Y
{
   .X dw X
   .Y dw Y
}



section '.code' code readable executable
main:
   push ebp
   mov ebp,esp

   PP Point 0, 0   ;Crashes here..

   mov esp, ebp
   pop ebp
   mov eax, 0x0
ret

So I thought well since its a local variable, I need to sub esp, sizeof(Point) and I did and it still crashed..

and so I did it within the Point structure and instead of crashing, it now gets deleted:

section '.data' data readable writeable
Response db 13, 10, "Value: %d", 13, 10, 0

struc Point X, Y
{
   sub esp, 0x8
   mov dword[esp + 0x00], X
   mov dword[esp + 0x04], Y
}



section '.code' code readable executable
main:
   push ebp
   mov ebp,esp

   PP Point 0, 0        ;create a point
   push PP
   call Point_Valid
   add esp, 0x04



   mov esp, ebp
   pop ebx

   call [getchar]

   mov eax, 0x00
ret


Point_Valid:
   push ebp
   mov ebp, esp

   mov eax, [ebp + 0x8]
   push eax              ;Not sure how to get Point from eax or Point.X..
   push Response
   call [printf]
   add esp, 0x08


   mov esp, ebp
   pop ebp
ret                         

However, not only does the above fail, it also triggers this:

enter image description here From within Malware Defender for Windows 8.1

I do not understand why :S But it only happens when I use the sub esp within the struct. If I use the .X dw X it just crashes but does not trigger malware defender.

Any ideas how I can achieve passing a point to a function? Or creating a local point and passing it to a function as well as accessing its fields?


Solution

  • In the first example you had misspelt point as Point, so it didn't assemble (unless you told the assembler to ignore case).

    If we ignore that, what you're doing here:

    main:
    push ebp
    mov ebp,esp
    
    PP point 0, 0   ;Crashes here..
    
    mov esp, ebp
    pop ebp
    mov eax, 0x0
    

    is pretty much the same as if you had written:

    main:
    push ebp
    mov ebp,esp
    
    dw 0,0
    
    mov esp, ebp
    pop ebp
    mov eax, 0x0
    

    It just inserts those two 0-words into the instruction "stream" where you put them. If you assemble this and then disassemble the output you get:

    00000000  6655              push ebp
    00000002  6689E5            mov ebp,esp
    00000005  0000              add [bx+si],al  ; <- the first 0
    00000007  0000              add [bx+si],al  ; <- the second 0
    00000009  6689EC            mov esp,ebp
    0000000C  665D              pop ebp
    0000000E  66B800000000      mov eax,0x0
    00000014  C3                ret
    

    Your pp variable would have to be declared somewhere else so that it never ends up in the code path (i.e. eip / rip shouldn't reach your variable).


    If you really need a stack-allocated point you could use virtual at:

    virtual at esp-0x10  ; use whatever address is appropriate in your case
      pp point 1,2
    end virtual
    
    mov ax,[pp.X]
    

    Note that this neither allocates space for nor initializes a point; it just sets up the name-address mapping.