Search code examples
assemblynestedstructuremasm

nested structure into an assembly file using masm compiler


Does someone know how to create nested structures in assembly using the windows compiler ml.exe

I would like to declare the structure of startupinfoexa (https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-startupinfoexa) but it contains the structure startupinfoa (https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa)

The startupinfoa structure is declared like this in my code:

STARTUPINFOA    struct 
cb            DWORD    ?
lpReserved    DWORD    ?
lpDesktop     DWORD    ?
lpTitle       DWORD    ?
dwX           DWORD    ?
dwY           DWORD    ?
dwXSize       DWORD    ?
dwYSize       DWORD    ?
dwXCountChars    DWORD    ?
dwYCountChars    DWORD    ?
dwFillAttribute  DWORD    ?
dwFlags       DWORD    ?
wShowWindow   WORD    ?
cbReserved2   WORD    ?
lpReserved2   DWORD    ?
hStdInput     DWORD    ?
hStdOutput    DWORD    ?
hStdError     DWORD    ?
STARTUPINFOA    ends

And it works well, but now i would like to use in my code the startupinfoexa, but i don't really know how to declare it as it contains the startupinfoa structure. What i used below doesn't work:

STARTUPINFOEXA struct
StartupInfo     STARTUPINFOA ?
lpAttributeList DWORD ?
STARTUPINFOEXA ends

Any idea?

Thanks


Solution

  • Do it with angle brackets:

    STARTUPINFOEXA struct
        StartupInfo     STARTUPINFOA <>
        lpAttributeList DWORD ?
    STARTUPINFOEXA ends
    

    Example (the program performs a "cmd /cDIR" in a console):

    .686
    .MODEL FLAT
    
    CreateProcessA PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
    WaitForSingleObject PROTO STDCALL :DWORD,:DWORD
    ExitProcess PROTO STDCALL :DWORD
    puts PROTO C :DWORD
    fflush PROTO C :DWORD
    _getch PROTO C
    
    INCLUDELIB kernel32.lib
    INCLUDELIB msvcrt.lib
    
    STARTUPINFOA    struct
        cb            DWORD    ?
        lpReserved    DWORD    ?
        lpDesktop     DWORD    ?
        lpTitle       DWORD    ?
        dwX           DWORD    ?
        dwY           DWORD    ?
        dwXSize       DWORD    ?
        dwYSize       DWORD    ?
        dwXCountChars    DWORD    ?
        dwYCountChars    DWORD    ?
        dwFillAttribute  DWORD    ?
        dwFlags       DWORD    ?
        wShowWindow   WORD    ?
        cbReserved2   WORD    ?
        lpReserved2   DWORD    ?
        hStdInput     DWORD    ?
        hStdOutput    DWORD    ?
        hStdError     DWORD    ?
    STARTUPINFOA ENDS
    
    STARTUPINFOEXA struct
        StartupInfo     STARTUPINFOA <>
        lpAttributeList DWORD ?
    STARTUPINFOEXA ends
    
    PROCESS_INFORMATION STRUCT              ; https://msdn.microsoft.com/library/windows/desktop/ms684873.aspx
        hProcess        DWORD ?
        hThread         DWORD ?
        dwProcessId     DWORD  ?
        dwThreadId      DWORD  ?
    PROCESS_INFORMATION ENDS
    
    .DATA
        app db "C:\WINDOWS\system32\cmd.exe",0
        arg db "/c dir", 0
        msg db 10,10,"ok",10,0
        startinfoex STARTUPINFOEXA <>
        procinfo PROCESS_INFORMATION <>
    
    .CODE
    
    _start:
    
        mov startinfoex.StartupInfo.cb, sizeof (STARTUPINFOEXA)
    
        ; CreateProcess(app,arg,0,0,false,0,0,0,&startupinfo,&procinfo)
        push OFFSET procinfo
        push OFFSET startinfoex
        push 0
        push 0
        push 0
        push 0
        push 0
        push 0
        push OFFSET arg
        push OFFSET app
        call CreateProcessA         ; https://msdn.microsoft.com/library/windows/desktop/ms682425.aspx
    
        ; WaitForSingleObject( procinfo.hProcess, INFINITE );
        push -1         ; INFINITE
        push dword ptr [procinfo.hProcess]
        call WaitForSingleObject
    
        ; puts ("ok"), fflush to flush the stdout-buffer
        push OFFSET msg
        call puts
        mov dword ptr [esp], 0
        call fflush
        add esp, 4
    
        call _getch             ; Stop and wait for a key pressed.
    
        ; return 0
        push 0
        call ExitProcess
    
    END _start