Home > Blockchain >  MASM struct in data section vs struct in the stack
MASM struct in data section vs struct in the stack

Time:11-03

I have to call WinApi SHFileOperationW function, but before this I need to fill this struct

typedef struct _SHFILEOPSTRUCTW {
HWND         hwnd;
UINT         wFunc;
PCZZWSTR     pFrom;
PCZZWSTR     pTo;
FILEOP_FLAGS fFlags;
BOOL         fAnyOperationsAborted;
LPVOID       hNameMappings;
PCWSTR       lpszProgressTitle;
} SHFILEOPSTRUCTW, *LPSHFILEOPSTRUCTW;

In MASM I defined this like that:

SHFILEOPSTRUCT struct 
    hwnd                  dq ?
    wFunc                 dd ?
    pFrom                 dq ?
    pTo                   dq ?
    fFlags                dw ?
    fAnyOperationsAborted dd ?
    hNameMappings         dq ?
    lpszProgressTitle     dq ?
SHFILEOPSTRUCT ends

In .data section I init my struct:

fos SHFILEOPSTRUCT <?>

So when I filling my struct with mov operations and load the address in rcx(1 arg of function) it cause error, but if I push struct fields in the stack and pass to function RSP its work just fine. Why so? Need I fill all the fields even if it 0? (does not work ↓)

mov [fos.hwnd], 0                       ; hWnd
mov [fos.wFunc], FO_DELETE              ; Delete 
mov rax, offset filename
mov [fos.pFrom], rax                    ; Filename
mov [fos.fFlags], FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT                           
lea rcx, fos

vs (it's work ↓)

push 0
push 0
push 0
push FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT
push 0
pushaddr filename
push FO_DELETE 
push 0
mov rcx, rsp

And then ofc I allocate some space in the stack and call the func:

sub rsp, 28h 
call SHFileOperationW

CodePudding user response:

The C/C headers in the Windows SDK assume the platform's default alignment is used.

this controlled by /Zp (Struct Member Alignment) option in both msvc and ML/ML64 ( The alignment can be 1, 2, 4, 8 or 16)

look also How align works with data packing

difference betweem MSVC and ML64: MSVC use /Zp16 as default for x64 and ARM64 but ML64 not.

so you need or direct set /Zp16 in ML64 command line (the best) or direct set aligment in STRUCT declaration:

like SHFILEOPSTRUCTW struct 16


also declare variable In .data section - mean use global variable and bad solution. this must be local variable, so in stack. code can look like

.code

SHFILEOPSTRUCTW struct 16
    hwnd                  dq ?
    wFunc                 dd ?
    pFrom                 dq ?
    pTo                   dq ?
    fFlags                dw ?
    fAnyOperationsAborted dd ?
    hNameMappings         dq ?
    lpszProgressTitle     dq ?
SHFILEOPSTRUCTW ends

FO_DELETE           EQU 03h

FOF_NOCONFIRMATION  EQU 10h
FOF_ALLOWUNDO       EQU 40h
FOF_SILENT          EQU 04h

EXTERN __imp_SHFileOperationW:QWORD

VarSize EQU ((SIZEOF SHFILEOPSTRUCTW   15) and not 15)
fos EQU [rsp   20h]


er_ff proc

    sub rsp, 28h   VarSize
    xor eax,eax
    mov fos[SHFILEOPSTRUCTW.hwnd],rax
    mov fos[SHFILEOPSTRUCTW.wFunc],FO_DELETE
    mov fos[SHFILEOPSTRUCTW.pFrom],rcx
    mov fos[SHFILEOPSTRUCTW.pTo],rax
    mov fos[SHFILEOPSTRUCTW.fFlags],FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT
    lea rcx,fos
    call __imp_SHFileOperationW
    add rsp, 28h   VarSize 
    ret
er_ff endp

end

so use SHFILEOPSTRUCTW struct 16 ot better ml64 /c /Cp /Zp16 "$(InputFileName)"

  • Related