Experimenting with UASM64.exe (V 2.51) i think shadow space is not properly filled with OPTION WIN64 > 7 (adding W64F_SMART). I used the following code for testing:
ifdef _WIN64
.model flat, fastcall ; 64 bit memory model
; option win64: 1=save regs to shadow space,
;2=calculate required stack space for arguments of INVOKE
;4=stack variables are 16-byte aligned
;8=takes care of everything
;case 1 ;-> ok
; option win64:1
;case 2 ;-> ok
OPTION STACKBASE : RBP ;-> no RBP based stack frame in leaf procs
option win64:1
;case 3 ;-> ok
; option win64:7
;case 4 ;-> ok
; OPTION STACKBASE : RBP ;-> no RBP based stack frame in leaf procs
; option win64:7
;case 5 ;-> xmm3 instead of r9, which is wrong
; option win64:11
;case 6 ;-> xmm3 instead of r9, which is wrong
; OPTION STACKBASE : RBP ;-> no RBP based stack frame in leaf procs
; option win64:11
;case 7 ;-> xmm3 instead of r9, which is wrong
; option win64:15
;case 8 ;-> xmm3 instead of r9, which is wrong
; OPTION STACKBASE : RBP ;-> no RBP based stack frame at all
; option win64:15
xax equ <rax>
xbx equ <rbx>
xcx equ <rcx>
xdx equ <rdx>
xsi equ <rsi>
xdi equ <rdi>
xsp equ <rsp>
xbp equ <rbp>
xword typedef qword
xlong typedef sqword
else
.686P
.model flat, stdcall ; 32 bit memory model
.xmm
OPTION STACKBASE : EBP
xax equ <eax>
xbx equ <ebx>
xcx equ <ecx>
xdx equ <edx>
xsi equ <esi>
xdi equ <edi>
xsp equ <esp>
xbp equ <ebp>
xword typedef dword
xlong typedef sdword
endif
include windows.inc
includelib kernel32.lib
.code
testit2 proc uses xbx xsi xdi, y1:RECT
;*************************************************************************************
; leaf proc
;*************************************************************************************
local i:DWORD
lea xax, i ;1. local
lea xax, y1 ;1. parameter
ret
testit2 endp
;*************************************************************************************
testit proc uses xbx xsi xdi, y1:RECT, d4:real4, d8:real8, d10:real10, x:dword , z:xword, y:RECT
;*************************************************************************************
; proc
;*************************************************************************************
local tx :dword
LOCAL ty :RECT
LOCAL tz :dword
invoke testit2, ty
lea xax, x
lea xdx, d4
lea xsi, d8
lea xdi, d10
lea xax, tx
lea xbx, ty
lea xcx, tz
ret
testit endp
;*************************************************************************************
start proc uses xbx xsi xdi ;r15
;*************************************************************************************
; main proc
;*************************************************************************************
local x :dword
LOCAL y :RECT
LOCAL z :xword
local d4:real4
local d8:real8
local d10:real10
int 3
invoke testit, y, d4, d8, d10, x , z, y
lea xax, x
lea xbx, y
lea xcx, z
lea xdx, d4
lea xsi, d8
lea xdi, d10
int 3
invoke ExitProcess, 0
ret
start endp
end start
to be continued in the following post ...
and this is the 32 disassembly:
;*************************************************************************************
; 32 bit
;*************************************************************************************
;00251000 | 55 | push ebp |
;00251001 | 8BEC | mov ebp,esp |
;00251003 | 83C4 FC | add esp,FFFFFFFC |
;00251006 | 53 | push ebx |
;00251007 | 56 | push esi |
;00251008 | 57 | push edi |
;00251009 | 8D45 FC | lea eax,dword ptr ss:[ebp-4] | i
;0025100C | 8D45 08 | lea eax,dword ptr ss:[ebp+8] | y1
;0025100F | 5F | pop edi |
;00251010 | 5E | pop esi |
;00251011 | 5B | pop ebx |
;00251012 | 8BE5 | mov esp,ebp |
;00251014 | 5D | pop ebp |
;00251015 | C2 1000 | ret 10 |
;00251018 | 55 | push ebp |
;00251019 | 8BEC | mov ebp,esp |
;0025101B | 83C4 E8 | add esp,FFFFFFE8 |
;0025101E | 53 | push ebx |
;0025101F | 56 | push esi |
;00251020 | 57 | push edi |
;00251021 | FF75 F8 | push dword ptr ss:[ebp-8] | ty
;00251024 | FF75 F4 | push dword ptr ss:[ebp-C] | ty
;00251027 | FF75 F0 | push dword ptr ss:[ebp-10] | ty
;0025102A | FF75 EC | push dword ptr ss:[ebp-14] | ty
;0025102D | E8 CEFFFFFF | call uasm_error.251000 |
;00251032 | 8D45 30 | lea eax,dword ptr ss:[ebp+30] |
;00251035 | 8D55 18 | lea edx,dword ptr ss:[ebp+18] |
;00251038 | 8D75 1C | lea esi,dword ptr ss:[ebp+1C] |
;0025103B | 8D7D 24 | lea edi,dword ptr ss:[ebp+24] |
;0025103E | 8D45 FC | lea eax,dword ptr ss:[ebp-4] |
;00251041 | 8D5D EC | lea ebx,dword ptr ss:[ebp-14] | ty
;00251044 | 8D4D E8 | lea ecx,dword ptr ss:[ebp-18] |
;00251047 | 5F | pop edi |
;00251048 | 5E | pop esi |
;00251049 | 5B | pop ebx |
;0025104A | 8BE5 | mov esp,ebp |
;0025104C | 5D | pop ebp |
;0025104D | C2 4000 | ret 40 |
;00251050 | 55 | push ebp |
;00251051 | 8BEC | mov ebp,esp |
;00251053 | 83C4 D0 | add esp,FFFFFFD0 |
;00251056 | 53 | push ebx |
;00251057 | 56 | push esi |
;00251058 | 57 | push edi |
;00251059 | CC | int3 |
;0025105A | FF75 F8 | push dword ptr ss:[ebp-8] | y
;0025105D | FF75 F4 | push dword ptr ss:[ebp-C] | y
;00251060 | FF75 F0 | push dword ptr ss:[ebp-10] | y
;00251063 | FF75 EC | push dword ptr ss:[ebp-14] | y
;00251066 | FF75 E8 | push dword ptr ss:[ebp-18] | z
;00251069 | FF75 FC | push dword ptr ss:[ebp-4] | x
;0025106C | 83EC 02 | sub esp,2 |
;0025106F | 66:FF75 D8 | push word ptr ss:[ebp-28] | d10
;00251073 | FF75 D4 | push dword ptr ss:[ebp-2C] | d10
;00251076 | FF75 D0 | push dword ptr ss:[ebp-30] | d10
;00251079 | FF75 E0 | push dword ptr ss:[ebp-20] | d8
;0025107C | FF75 DC | push dword ptr ss:[ebp-24] | d8
;0025107F | FF75 E4 | push dword ptr ss:[ebp-1C] | d4
;00251082 | FF75 F8 | push dword ptr ss:[ebp-8] | y
;00251085 | FF75 F4 | push dword ptr ss:[ebp-C] | y
;00251088 | FF75 F0 | push dword ptr ss:[ebp-10] | y
;0025108B | FF75 EC | push dword ptr ss:[ebp-14] | y
;0025108E | E8 85FFFFFF | call uasm_error.251018 |
;00251093 | 8D45 FC | lea eax,dword ptr ss:[ebp-4] | x
;00251096 | 8D5D EC | lea ebx,dword ptr ss:[ebp-14] | y
;00251099 | 8D4D E8 | lea ecx,dword ptr ss:[ebp-18] | z
;0025109C | 8D55 E4 | lea edx,dword ptr ss:[ebp-1C] | d4
;0025109F | 8D75 DC | lea esi,dword ptr ss:[ebp-24] | d8
;002510A2 | 8D7D D0 | lea edi,dword ptr ss:[ebp-30] | d10
;002510A5 | CC | int3 |
;002510A6 | 6A 00 | push 0 |
;002510A8 | FF15 00202500 | call dword ptr ds:[<&ExitProcess>] |
;002510AE | 5F | pop edi |
;002510AF | 5E | pop esi |
;002510B0 | 5B | pop ebx |
;002510B1 | 8BE5 | mov esp,ebp |
;002510B3 | 5D | pop ebp |
;002510B4 | C3 | ret |
;*************************************************************************************
to be continued ...
and these are 64 bit disassemblies (one for OPTION WIN64:1 and another one for OPTION WIN64:15)
;*************************************************************************************
; 64 bit
; OPTION STACKBASE : RBP -> no RBP based stack frame in leaf procs
; option win64:1 shadow space ok
;*************************************************************************************
;0000000000ED1000 | 48:894C24 08 | mov qword ptr ss:[rsp+8],rcx |
;0000000000ED1005 | 48:55 | push rbp |
;0000000000ED1007 | 53 | push rbx |
;0000000000ED1008 | 56 | push rsi |
;0000000000ED1009 | 57 | push rdi |
;0000000000ED100A | 48:83EC 18 | sub rsp,18 |
;0000000000ED100E | 48:8D6C24 10 | lea rbp,qword ptr ss:[rsp+10] |
;0000000000ED1013 | 48:8D45 FC | lea rax,qword ptr ss:[rbp-4] |
;0000000000ED1017 | 48:8D45 30 | lea rax,qword ptr ss:[rbp+30] |
;0000000000ED101B | 48:8D65 08 | lea rsp,qword ptr ss:[rbp+8] |
;0000000000ED101F | 5F | pop rdi |
;0000000000ED1020 | 5E | pop rsi |
;0000000000ED1021 | 5B | pop rbx |
;0000000000ED1022 | 5D | pop rbp |
;0000000000ED1023 | C3 | ret |
;0000000000ED1024 | F3:0F114C24 10 | movss dword ptr ss:[rsp+10],xmm1 | d4 -> shadow space
;0000000000ED102A | F2:0F115424 18 | movsd qword ptr ss:[rsp+18],xmm2 | d8
;0000000000ED1030 | 4C:894C24 20 | mov qword ptr ss:[rsp+20],r9 | d10
;0000000000ED1035 | 48:55 | push rbp |
;0000000000ED1037 | 53 | push rbx |
;0000000000ED1038 | 56 | push rsi |
;0000000000ED1039 | 57 | push rdi |
;0000000000ED103A | 48:83EC 28 | sub rsp,28 |
;0000000000ED103E | 48:8D6C24 10 | lea rbp,qword ptr ss:[rsp+10] |
;0000000000ED1043 | 48:83EC 20 | sub rsp,20 |
;0000000000ED1047 | 48:8D4D 00 | lea rcx,qword ptr ss:[rbp] |
;0000000000ED104B | E8 B0FFFFFF | call uasm_error_64.ED1000 |
;0000000000ED1050 | 48:83C4 20 | add rsp,20 |
;0000000000ED1054 | 48:8D45 60 | lea rax,qword ptr ss:[rbp+60] |
;0000000000ED1058 | 48:8D55 48 | lea rdx,qword ptr ss:[rbp+48] |
;0000000000ED105C | 48:8D75 50 | lea rsi,qword ptr ss:[rbp+50] |
;0000000000ED1060 | 48:8D7D 58 | lea rdi,qword ptr ss:[rbp+58] |
;0000000000ED1064 | 48:8D45 FC | lea rax,qword ptr ss:[rbp-4] |
;0000000000ED1068 | 48:8D5D 00 | lea rbx,qword ptr ss:[rbp] |
;0000000000ED106C | 48:8D4D F8 | lea rcx,qword ptr ss:[rbp-8] |
;0000000000ED1070 | 48:8D65 18 | lea rsp,qword ptr ss:[rbp+18] |
;0000000000ED1074 | 5F | pop rdi |
;0000000000ED1075 | 5E | pop rsi |
;0000000000ED1076 | 5B | pop rbx |
;0000000000ED1077 | 5D | pop rbp |
;0000000000ED1078 | C3 | ret |
;0000000000ED1079 | 48:55 | push rbp |
;0000000000ED107B | 53 | push rbx |
;0000000000ED107C | 56 | push rsi |
;0000000000ED107D | 57 | push rdi |
;0000000000ED107E | 48:83EC 48 | sub rsp,48 |
;0000000000ED1082 | 48:8D6C24 20 | lea rbp,qword ptr ss:[rsp+20] |
;0000000000ED1087 | CC | int3 |
;0000000000ED1088 | 48:83EC 40 | sub rsp,40 |
;0000000000ED108C | 48:8D4D 10 | lea rcx,qword ptr ss:[rbp+10] | y arg 1
;0000000000ED1090 | 66:0F6E4D E8 | movd xmm1,dword ptr ss:[rbp-18] | d4 arg 2
;0000000000ED1095 | F3:0F7E55 00 | movq xmm2,qword ptr ss:[rbp] | d8 arg 3
;0000000000ED109A | 4C:8D4D F0 | lea r9,qword ptr ss:[rbp-10] | d10 arg 4
;0000000000ED109E | 8B45 EC | mov eax,dword ptr ss:[rbp-14] | x arg 5
;0000000000ED10A1 | 894424 20 | mov dword ptr ss:[rsp+20],eax |
;0000000000ED10A5 | 48:8B45 08 | mov rax,qword ptr ss:[rbp+8] | z arg 6
;0000000000ED10A9 | 48:894424 28 | mov qword ptr ss:[rsp+28],rax |
;0000000000ED10AE | 48:8B45 10 | mov rax,qword ptr ss:[rbp+10] | y arg 7
;0000000000ED10B2 | 48:894424 30 | mov qword ptr ss:[rsp+30],rax |
;0000000000ED10B7 | E8 68FFFFFF | call uasm_error_64.ED1024 |
;0000000000ED10BC | 48:83C4 40 | add rsp,40 |
;0000000000ED10C0 | 48:8D45 EC | lea rax,qword ptr ss:[rbp-14] | x
;0000000000ED10C4 | 48:8D5D 10 | lea rbx,qword ptr ss:[rbp+10] | y
;0000000000ED10C8 | 48:8D4D 08 | lea rcx,qword ptr ss:[rbp+8] | z
;0000000000ED10CC | 48:8D55 E8 | lea rdx,qword ptr ss:[rbp-18] | d4
;0000000000ED10D0 | 48:8D75 00 | lea rsi,qword ptr ss:[rbp] | d8
;0000000000ED10D4 | 48:8D7D F0 | lea rdi,qword ptr ss:[rbp-10] | d10
;0000000000ED10D8 | CC | int3 |
;0000000000ED10D9 | 48:83EC 20 | sub rsp,20 |
;0000000000ED10DD | 33C9 | xor ecx,ecx |
;0000000000ED10DF | FF15 1B0F0000 | call qword ptr ds:[<&RtlExitUserProcess |
;0000000000ED10E5 | 48:83C4 20 | add rsp,20 |
;0000000000ED10E9 | 48:8D65 28 | lea rsp,qword ptr ss:[rbp+28] |
;0000000000ED10ED | 5F | pop rdi |
;0000000000ED10EE | 5E | pop rsi |
;0000000000ED10EF | 5B | pop rbx |
;0000000000ED10F0 | 5D | pop rbp |
;0000000000ED10F1 | C3 | ret |
;*************************************************************************************
;*************************************************************************************
; 64 bit
; OPTION STACKBASE : RBP -> no RBP based stack frame at all
; option win64:15 shadow space error (xmm3)
;*************************************************************************************
;00000000011B1000 | 48:894C24 08 | mov qword ptr ss:[rsp+8],rcx |
;00000000011B1005 | 48:895C24 10 | mov qword ptr ss:[rsp+10],rbx |
;00000000011B100A | 48:897424 18 | mov qword ptr ss:[rsp+18],rsi |
;00000000011B100F | 57 | push rdi |
;00000000011B1010 | 48:83EC 10 | sub rsp,10 |
;00000000011B1014 | 48:8D0424 | lea rax,qword ptr ss:[rsp] |
;00000000011B1018 | 48:8D4424 20 | lea rax,qword ptr ss:[rsp+20] |
;00000000011B101D | 48:83C4 10 | add rsp,10 |
;00000000011B1021 | 5F | pop rdi |
;00000000011B1022 | 48:8B5C24 10 | mov rbx,qword ptr ss:[rsp+10] |
;00000000011B1027 | 48:8B7424 18 | mov rsi,qword ptr ss:[rsp+18] |
;00000000011B102C | C3 | ret |
;00000000011B102D | 66:0FD64C24 10 | movq qword ptr ss:[rsp+10],xmm1 | d4 -> shadow space
;00000000011B1033 | 66:0FD65424 18 | movq qword ptr ss:[rsp+18],xmm2 | d8
;00000000011B1039 | 66:0FD65C24 20 | movq qword ptr ss:[rsp+20],xmm3 | d10 ???? r9 !!!
;00000000011B103F | 53 | push rbx |
;00000000011B1040 | 56 | push rsi |
;00000000011B1041 | 57 | push rdi |
;00000000011B1042 | 48:83EC 50 | sub rsp,50 |
;00000000011B1046 | 48:8D4C24 30 | lea rcx,qword ptr ss:[rsp+30] |
;00000000011B104B | E8 B0FFFFFF | call uasm_error_64.11B1000 |
;00000000011B1050 | 48:8D8424 A0000000 | lea rax,qword ptr ss:[rsp+A0] |
;00000000011B1058 | 48:8D9424 80000000 | lea rdx,qword ptr ss:[rsp+80] |
;00000000011B1060 | 48:8DB424 88000000 | lea rsi,qword ptr ss:[rsp+88] |
;00000000011B1068 | 48:8DBC24 90000000 | lea rdi,qword ptr ss:[rsp+90] |
;00000000011B1070 | 48:8D4424 20 | lea rax,qword ptr ss:[rsp+20] |
;00000000011B1075 | 48:8D5C24 30 | lea rbx,qword ptr ss:[rsp+30] |
;00000000011B107A | 48:8D4C24 40 | lea rcx,qword ptr ss:[rsp+40] |
;00000000011B107F | 48:83C4 50 | add rsp,50 |
;00000000011B1083 | 5F | pop rdi |
;00000000011B1084 | 5E | pop rsi |
;00000000011B1085 | 5B | pop rbx |
;00000000011B1086 | C3 | ret |
;00000000011B1087 | 48:895C24 08 | mov qword ptr ss:[rsp+8],rbx |
;00000000011B108C | 48:897424 10 | mov qword ptr ss:[rsp+10],rsi |
;00000000011B1091 | 57 | push rdi |
;00000000011B1092 | 48:81EC A0000000 | sub rsp,A0 |
;00000000011B1099 | CC | int3 |
;00000000011B109A | 48:8D4C24 50 | lea rcx,qword ptr ss:[rsp+50] | y arg 1
;00000000011B109F | 66:0F6E4C24 68 | movd xmm1,dword ptr ss:[rsp+68] | d4 arg 2
;00000000011B10A5 | F3:0F7E5424 70 | movq xmm2,qword ptr ss:[rsp+70] | d8 arg 3
;00000000011B10AB | 4C:8D8C24 80000000 | lea r9,qword ptr ss:[rsp+80] | d10 arg 4
;00000000011B10B3 | 8B4424 40 | mov eax,dword ptr ss:[rsp+40] | x arg 5
;00000000011B10B7 | 894424 20 | mov dword ptr ss:[rsp+20],eax |
;00000000011B10BB | 48:8B4424 60 | mov rax,qword ptr ss:[rsp+60] | z arg 6
;00000000011B10C0 | 48:894424 28 | mov qword ptr ss:[rsp+28],rax |
;00000000011B10C5 | 48:8B4424 50 | mov rax,qword ptr ss:[rsp+50] | y arg 7
;00000000011B10CA | 48:894424 30 | mov qword ptr ss:[rsp+30],rax |
;00000000011B10CF | E8 59FFFFFF | call uasm_error_64.11B102D |
;00000000011B10D4 | 48:8D4424 40 | lea rax,qword ptr ss:[rsp+40] | x
;00000000011B10D9 | 48:8D5C24 50 | lea rbx,qword ptr ss:[rsp+50] | y
;00000000011B10DE | 48:8D4C24 60 | lea rcx,qword ptr ss:[rsp+60] | z
;00000000011B10E3 | 48:8D5424 68 | lea rdx,qword ptr ss:[rsp+68] | d4
;00000000011B10E8 | 48:8D7424 70 | lea rsi,qword ptr ss:[rsp+70] | d8
;00000000011B10ED | 48:8DBC24 80000000 | lea rdi,qword ptr ss:[rsp+80] | d10
;00000000011B10F5 | CC | int3 |
;00000000011B10F6 | 33C9 | xor ecx,ecx |
;00000000011B10F8 | FF15 020F0000 | call qword ptr ds:[<&RtlExitUserProcess |
;00000000011B10FE | 48:81C4 A0000000 | add rsp,A0 |
;00000000011B1105 | 5F | pop rdi |
;00000000011B1106 | 48:8B5C24 08 | mov rbx,qword ptr ss:[rsp+8] |
;00000000011B110B | 48:8B7424 10 | mov rsi,qword ptr ss:[rsp+10] |
;00000000011B1110 | C3 | ret |
;*************************************************************************************
in 32 bit code i see, what i would expect, the same applies to 64 bit code (OPTION WIN64:1).
But with e.g OPTION WIN64:15 xmm3 is used to fill the shadow space for parameter 4 (a REAL10). XMM3 was never filled in the calling procedure, which is correct to my understanding, because a REAL10 should be passed by reference (as a pointer, because it´s more than 8 bytes long). So this pointer is saved to R9, but R9 is not saved to shadow space. With W64F_SMART set in OPTION WIN64, xmm3 is used, which is wrong in my view - or did i miss something?
JK
Here is a handy macro, to be put before the call xxx:
FillShadowSpace macro sBytes:=<80h>
lea rdx, [rsp+8]
mov qword ptr [rdx-32], "Ldne" ; endLocal
mov qword ptr [rdx-28], "laco" ; endLocal
mov qword ptr [rdx-24], "_pbr" ; rbp_rbp_
mov qword ptr [rdx-20], "_pbr" ; rbp_rbp_
mov qword ptr [rdx-8], 522D2D3Ch ; <--RetAd
mov qword ptr [rdx-4], "dAte" ; <--RetAd
xor ecx, ecx
@@: mov byte ptr [rdx], "x"
inc rdx
inc ecx
cmp ecx, sBytes
jb @B
ENDM
Before executing the call, start the hexdump with rsp and scroll some rows up to see what comes below rsp.
Win64 the parameters pass by available register, stack otherwise. Obs.(the stack always reserve the shadow space if parameter or locals, and uses the registers for parameters till no more to use).
REAL? is treated as xmm
integer or ptr as general registers Obs.(you can also treat integer as xmm but must be type off xmm size <union is you friend>)
WIN x64 calling convention (https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160)
UASM guide (http://www.terraspace.co.uk/uasm251_ext.pdf) Obs.(option win64 11-15 for RSP and 1-7 for RBP.)
W64F_SAVEREGPARAMS = 0x01, /* 1=save register params in shadow space on proc entry */
W64F_AUTOSTACKSP = 0x02, /* 1=calculate required stack space for arguments of INVOKE */
W64F_STACKALIGN16 = 0x04, /* 1=stack variables are 16-byte aligned; added in v2.12 */
W64F_SMART = 0x08, /* 1=takes care of everything */
W64F_HABRAN = W64F_SAVEREGPARAMS | W64F_AUTOSTACKSP | W64F_SMART,
W64F_ALL = W64F_SAVEREGPARAMS | W64F_AUTOSTACKSP | W64F_STACKALIGN16 | W64F_SMART, /* all valid flags */
.x64
option stackbase:rsp ; RSP or RBP are supported options for the stackbase.
option frame:auto ; Default
option win64:15 ; 11-15 for RSP and 1-7 for RBP.
deleted
Quote from: nidud on April 01, 2021, 11:42:39 PMThere are no shadow space below RSP and as everything below the red zone (https://devblogs.microsoft.com/oldnewthing/20190111-00/?p=100685) is actively used by the OS this is a very bad idea.
Thanks for the link, Nidud, it's interesting. The macro is for educational purposes only, and it works like a charm. Use it with x64Dbg or whatever to understand how the rbp-based stack frame really works.
My point is, the sample code above results in this (note the indented lines):
;*************************************************************************************
; 64 bit
; OPTION STACKBASE : RBP -> no RBP based stack frame at all
; option win64:15 shadow space error (xmm3)
;*************************************************************************************
;00000000011B1000 | 48:894C24 08 | mov qword ptr ss:[rsp+8],rcx |
;00000000011B1005 | 48:895C24 10 | mov qword ptr ss:[rsp+10],rbx |
;00000000011B100A | 48:897424 18 | mov qword ptr ss:[rsp+18],rsi |
;00000000011B100F | 57 | push rdi |
;00000000011B1010 | 48:83EC 10 | sub rsp,10 |
;00000000011B1014 | 48:8D0424 | lea rax,qword ptr ss:[rsp] |
;00000000011B1018 | 48:8D4424 20 | lea rax,qword ptr ss:[rsp+20] |
;00000000011B101D | 48:83C4 10 | add rsp,10 |
;00000000011B1021 | 5F | pop rdi |
;00000000011B1022 | 48:8B5C24 10 | mov rbx,qword ptr ss:[rsp+10] |
;00000000011B1027 | 48:8B7424 18 | mov rsi,qword ptr ss:[rsp+18] |
;00000000011B102C | C3 | ret |
;00000000011B102D | 66:0FD64C24 10 | movq qword ptr ss:[rsp+10],xmm1 | d4 -> shadow space
;00000000011B1033 | 66:0FD65424 18 | movq qword ptr ss:[rsp+18],xmm2 | d8
>>>>> ;00000000011B1039 | 66:0FD65C24 20 | movq qword ptr ss:[rsp+20],xmm3 | d10 ???? r9 !!!
;00000000011B103F | 53 | push rbx |
;00000000011B1040 | 56 | push rsi |
;00000000011B1041 | 57 | push rdi |
;00000000011B1042 | 48:83EC 50 | sub rsp,50 |
;00000000011B1046 | 48:8D4C24 30 | lea rcx,qword ptr ss:[rsp+30] |
;00000000011B104B | E8 B0FFFFFF | call uasm_error_64.11B1000 |
;00000000011B1050 | 48:8D8424 A0000000 | lea rax,qword ptr ss:[rsp+A0] |
;00000000011B1058 | 48:8D9424 80000000 | lea rdx,qword ptr ss:[rsp+80] |
;00000000011B1060 | 48:8DB424 88000000 | lea rsi,qword ptr ss:[rsp+88] |
;00000000011B1068 | 48:8DBC24 90000000 | lea rdi,qword ptr ss:[rsp+90] |
;00000000011B1070 | 48:8D4424 20 | lea rax,qword ptr ss:[rsp+20] |
;00000000011B1075 | 48:8D5C24 30 | lea rbx,qword ptr ss:[rsp+30] |
;00000000011B107A | 48:8D4C24 40 | lea rcx,qword ptr ss:[rsp+40] |
;00000000011B107F | 48:83C4 50 | add rsp,50 |
;00000000011B1083 | 5F | pop rdi |
;00000000011B1084 | 5E | pop rsi |
;00000000011B1085 | 5B | pop rbx |
;00000000011B1086 | C3 | ret |
;00000000011B1087 | 48:895C24 08 | mov qword ptr ss:[rsp+8],rbx |
;00000000011B108C | 48:897424 10 | mov qword ptr ss:[rsp+10],rsi |
;00000000011B1091 | 57 | push rdi |
;00000000011B1092 | 48:81EC A0000000 | sub rsp,A0 |
;00000000011B1099 | CC | int3 |
;00000000011B109A | 48:8D4C24 50 | lea rcx,qword ptr ss:[rsp+50] | y arg 1
;00000000011B109F | 66:0F6E4C24 68 | movd xmm1,dword ptr ss:[rsp+68] | d4 arg 2
;00000000011B10A5 | F3:0F7E5424 70 | movq xmm2,qword ptr ss:[rsp+70] | d8 arg 3
>>>>> ;00000000011B10AB | 4C:8D8C24 80000000 | lea r9,qword ptr ss:[rsp+80] | d10 arg 4
;00000000011B10B3 | 8B4424 40 | mov eax,dword ptr ss:[rsp+40] | x arg 5
;00000000011B10B7 | 894424 20 | mov dword ptr ss:[rsp+20],eax |
;00000000011B10BB | 48:8B4424 60 | mov rax,qword ptr ss:[rsp+60] | z arg 6
;00000000011B10C0 | 48:894424 28 | mov qword ptr ss:[rsp+28],rax |
;00000000011B10C5 | 48:8B4424 50 | mov rax,qword ptr ss:[rsp+50] | y arg 7
;00000000011B10CA | 48:894424 30 | mov qword ptr ss:[rsp+30],rax |
;00000000011B10CF | E8 59FFFFFF | call uasm_error_64.11B102D |
;00000000011B10D4 | 48:8D4424 40 | lea rax,qword ptr ss:[rsp+40] | x
;00000000011B10D9 | 48:8D5C24 50 | lea rbx,qword ptr ss:[rsp+50] | y
;00000000011B10DE | 48:8D4C24 60 | lea rcx,qword ptr ss:[rsp+60] | z
;00000000011B10E3 | 48:8D5424 68 | lea rdx,qword ptr ss:[rsp+68] | d4
;00000000011B10E8 | 48:8D7424 70 | lea rsi,qword ptr ss:[rsp+70] | d8
;00000000011B10ED | 48:8DBC24 80000000 | lea rdi,qword ptr ss:[rsp+80] | d10
;00000000011B10F5 | CC | int3 |
;00000000011B10F6 | 33C9 | xor ecx,ecx |
;00000000011B10F8 | FF15 020F0000 | call qword ptr ds:[<&RtlExitUserProcess |
;00000000011B10FE | 48:81C4 A0000000 | add rsp,A0 |
;00000000011B1105 | 5F | pop rdi |
;00000000011B1106 | 48:8B5C24 08 | mov rbx,qword ptr ss:[rsp+8] |
;00000000011B110B | 48:8B7424 10 | mov rsi,qword ptr ss:[rsp+10] |
;00000000011B1110 | C3 | ret |
;*************************************************************************************
here is, what is saved to shadow space for argument 4 (d10:REAL10):
;00000000011B1039 | 66:0FD65C24 20 | movq qword ptr ss:[rsp+20],xmm3 | d10 ???? r9 !!!
and here is, what is passed for argument 4 (d10:REAL10):
;00000000011B10AB | 4C:8D8C24 80000000 | lea r9,qword ptr ss:[rsp+80] | d10 arg 4
So a pointer to d10 is passed in R9, which is correct, but xmm3 is saved to shadow space for d10, which is wrong in my opinion.
JK
I'll setup some test-cases for this, as I want to check the symbol offsets for debugging with Zi8 anyway.
Is the issue just RSP mode, RBP works fine ?
Thanks for your reply!
I used the code supplied in the opening post. Just define "_WIN64" for 64 bit code. According to my tests the error occurs only if W64F_SMART is part of WIN64 options (RSP mode, RBP mode seems fine), just look at the ";case ..." lines to see, which options i tried, and which worked for me. The code does essentially nothing useful, it´s just for demonstrating the problem, "INT 3" makes the debugger (X64dbg) pop up, so i can see the created code.
I used UASM32 V 2.51 (UASM32.exe /c -win64 -Zp8 /win64 /D_WIN64 /Cp /W2 /I ...) and MS´s linker (LINK.EXE /SUBSYSTEM:CONSOLE /RELEASE /VERSION:4.0 /MACHINE:X64 /LIBPATH ...) in a batch file for creating and running the executable.
Hopefully you can reproduce it with this information, otherwise tell me, what might be missing.
JK
I'm playing with a WinAPI call that takes 23 parameters, it's a good test case for various frame options:
jinvoke LocalEnroll,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,rbx,23
As long as arg#22 is a pointer, it will not crash. No idea what the other args do, it's absolutely undocumented :cool:
I'm busy finalizing ver 2.52. Fixes include:
Fixed RSP prologue to receive REAL10's by reference and not value
Added a warning in this case, as passing REAL10 as a parameter might be misleading that it's by value instead of ref
Fixed out of memory error in UASM 32bit.
Added fix to CodeView8 to prevent corrupt debugging info.
Corrected symbol offsets for RSP stack-frame proc parameters when no sub rsp is needed.
So this issue will be solved now (+ give the user a warning.. ie. Did you really in intend to pass a REAL10 instead of a ptr?)
Thanks a lot for your efforts!