flat assembler
Message board for the users of flat assembler.

Index > Windows > New fastcall macro for saft calling X64 procedure

Author
Thread Post new topic Reply to topic
Kevin_Zheng



Joined: 04 Jul 2003
Posts: 125
Location: China
Kevin_Zheng
Hi, Guys:
If we want to write X64 WIN ASM code, the code have to add one line code in the entrypoint:
Code:
sub rsp, 0x08    


The reason is that the X64 proceduce will store the returned address into the RSP, and some of instructions (mov xmm, [rsp] ) willl raise exception when it found that the RSP mod 16 = 8.

Please see below new fastcall macro, it will balance stack before invoke X64 procedure. so we don't need add this line code "sub rsp, 0x08" in the entrypoint.

Safty Fastcall Macro:
Code:
;============================================================================
; It's used to align the X64 program's stack to stack dqword aligned (16 bytes align).
; For example, the WIN64 program will load to this address is 0x401000:4883EC08, 
; and set the the stack address is 0x28:6FF58, the program must make sure the stack
; dqword aligned, it means that the first LSB byte must equal to zero. 
; for example: the address 0x6FF58 convert to 0x6FF50, 0x6x6FF40, etc okay.
macro   ALIGN_STACK
{
        and spl, 0xF0           ; Mask the LSB 4bits.
}
;============================================================================
; It's used to safe fastcall WINX64 API.
; the fastcall stack:
; push rcx rdx r8 r9
; push rip
; push rbp
; mov rbp, rsp
; [rbp + 0x00] ==> RBP
; [rbp + 0x08] ==> RIP
; [rbp + 0x10] ==> RCX
; [rbp + 0x18] ==> RDX  
; [rbp + 0x20] ==> R8
; [rbp + 0x28] ==> R9 
;============================================================================
macro fastcall proc,[arg]{ 
common 
  push  rsp             ; Save current RSP position on the stack 
  push  qword [rsp]     ; Keep another copy of that on the stack
  add   rsp, 8          ; Balance the stack pointer. 
  ALIGN_STACK           ; adjust RSP to align the stack if not already there 
  fastcall proc, arg 
  pop rsp               ;restore RSP to its original value 
}
    


Pedemo.asm from example:
Code:

; Example of 64-bit PE program

format PE64 GUI
entry start

include         'WIN64A.INC'

;============================================================================
; It's used to align the X64 program's stack to stack dqword aligned (16 bytes align).
; For example, the WIN64 program will load to this address is 0x401000:4883EC08, 
; and set the the stack address is 0x28:6FF58, the program must make sure the stack
; dqword aligned, it means that the first LSB byte must equal to zero. 
; for example: the address 0x6FF58 convert to 0x6FF50, 0x6x6FF40, etc okay.
macro   ALIGN_STACK
{
        and spl, 0xF0           ; Mask the LSB 4bits.
}
;============================================================================
; It's used to safe fastcall WINX64 API.
; the fastcall stack:
; push rcx rdx r8 r9
; push rip
; push rbp
; mov rbp, rsp
; [rbp + 0x00] ==> RBP
; [rbp + 0x08] ==> RIP
; [rbp + 0x10] ==> RCX
; [rbp + 0x18] ==> RDX  
; [rbp + 0x20] ==> R8
; [rbp + 0x28] ==> R9 
;============================================================================
macro fastcall proc,[arg]{ 
common 
  push  rsp             ; Save current RSP position on the stack 
  push  qword [rsp]     ; Keep another copy of that on the stack
  add   rsp, 8          ; Balance the stack pointer. 
  ALIGN_STACK           ; adjust RSP to align the stack if not already there 
  fastcall proc, arg 
  pop rsp               ;restore RSP to its original value 
}
;============================================================================

section '.text' code readable executable

  start:
        
        ;sub    rsp,8   ; reserve stack for API use and make stack dqword aligned
        ;mov    r9d,0
        ;lea    r8,[_caption]
        ;lea    rdx,[_message]
        ;mov    rcx,0
        ;call   [MessageBoxA]
        
        invoke wsprintf, szTemp, "PE64 Demo: %s", _message
        invoke MessageBoxA, 0, szTemp, _caption, 0
        mov     ecx,eax
        ;call   [ExitProcess]
        invoke ExitProcess

section '.data' data readable writeable

  _caption db 'Win64 assembly program',0
  _message db 'Hello World!',0
  szTemp        rb      1000

section '.idata' import data readable writeable

  dd 0,0,0,RVA kernel_name,RVA kernel_table
  dd 0,0,0,RVA user_name,RVA user_table
  dd 0,0,0,0,0

  kernel_table:
    ExitProcess dq RVA _ExitProcess
    dq 0
  user_table:
    MessageBoxA dq RVA _MessageBoxA
    wsprintf            dq RVA _wsprintfA
    dq 0

  kernel_name db 'KERNEL32.DLL',0
  user_name db 'USER32.DLL',0

  _ExitProcess dw 0
    db 'ExitProcess',0
  _MessageBoxA dw 0
    db 'MessageBoxA',0
  _wsprintfA dw 0
    db 'wsprintfA',0

    


Description:
Download
Filename: PE64DEMO.zip
Filesize: 1.69 KB
Downloaded: 81 Time(s)


_________________
Pure Assembly Language Funs
Post 03 Sep 2015, 23:06
View user's profile Send private message MSN Messenger Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.