MSDN says
Integer valued arguments in the leftmost four positions are passed in left-to-right order in RCX, RDX, R8, and R9, respectively. Space is allocated on the call stack as a shadow store for callees to save those registers. Remaining arguments get pushed on the stack in right-to-left order.
So, I'm trying to call the CreateFileW
function, and this is my code:
sub rsp, 20h ; Allocate 32 bytes because 4 registers 8 byte each
mov rcx, offset filename ; lpFileName
mov rdx, GENERIC_READ or GENERIC_WRITE ; dwDesiredAccess
mov r8, FILE_SHARE_DELETE ; dwShareMode
xor r9, r9 ; LpSecurityAttributes
;__And right-to-left order remaining arguments__
push 0 ; hTemplateFile
push FILE_ATTRIBUTE_NORMAL ;dwFlagsAndAttributes
push CREATE_ALWAYS ; dwCreationDisposition
call CreateFileW
It assembles, but does not work and win64dbg causes next error:
00000057 (ERROR_INVALID_PARAMETER)
The parameters are 100% ok because it works with the Invoke
macro, only the generated code is different.
mov rcx,src.403000 ;name
mov edx,C0000000 ;GENERIC_READ or GENERIC_WRITE
mov r8d,4 ;FILE_SHARE_DELETE
xor r9d,r9d ;0
mov qword ptr ss:[rbp-20],2; ;CREATE_ALWAYS
mov qword ptr ss:[rbp-18],80 ;FILE_ATTRIBUTE_NORMAL
and qword ptr ss:[rbp-10],0 ;0
call qword ptr ds:[<&CreateFileW>]
So my question is why it uses the RBP register instead of push
and does not allocate 32 bytes for "shadow-store"?
Notes
Since 64-bit MASM by Microsoft no longer has an invoke
directive I am using a Russian MASM64 SDK project that has an invoke
macro. That project is loosely based on the MASM32 SDK.