Windows CreateProcessA函数在MASM64(ml64.exe)中不工作

Windows CreateProcessA函数在MASM64(ml64.exe)中不工作,windows,winapi,assembly,masm,Windows,Winapi,Assembly,Masm,我想写一个启动另一个程序进程的程序。我正在使用Visual Studio 2015中的MASM64 ml64.exe 程序不起作用。没有显示任何内容。在调试器中,我遇到访问冲突 我不知道我的代码出了什么问题 我的代码: extrn ExitProcess : proc extrn MessageBoxA : proc extrn CreateProcessA : proc PROCESS_INFORMATION struct hProcess DWORD ? hThread

我想写一个启动另一个程序进程的程序。我正在使用Visual Studio 2015中的MASM64 ml64.exe

程序不起作用。没有显示任何内容。在调试器中,我遇到访问冲突

我不知道我的代码出了什么问题

我的代码:

extrn ExitProcess : proc
extrn MessageBoxA : proc
extrn CreateProcessA : proc

PROCESS_INFORMATION    struct 
hProcess    DWORD    ?
hThread    DWORD    ?
dwProcessId    DWORD    ?
dwThreadId    DWORD    ?
PROCESS_INFORMATION    ends

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

.const
MB_ICONINFORMATION equ 40h
ERROR_ALREADY_EXISTS equ 0B7h
NORMAL_PRIORITY_CLASS equ 020h

.data
szText db "This is first application which creates new process using CreateProcessA.", 00h
szCaption db "Information",00h
processInfo PROCESS_INFORMATION <>
startupInfo STARTUPINFOA <>
szProcName db "D:\Apps\SampleApp.exe", 00h

.code
    Main proc
        ;not sure if correct - begin
        lea rax, processInfo
        lea rbx, startupInfo


        sub rsp, 60h 
        push rax
        push rbx
        push 00h
        push 00h
        push NORMAL_PRIORITY_CLASS
        push 00h
        mov r9, 00h
        mov r8, 00h
        mov rdx, 00h
        lea rcx, szProcName
        call CreateProcessA
        add rsp, 60h 
        ;not sure if correct - end

        sub rsp, 28h
        mov r9, MB_ICONINFORMATION
        lea r8, szCaption
        lea rdx, szText
        xor rcx, rcx
        call MessageBoxA
        add rsp, 28h

        Exit:
        xor rcx, rcx
        call ExitProcess
    Main endp
end

提前感谢您的帮助。

您应该检查流程信息和STARTUPINFO结构的定义,因为它们在x86和x64之间可能有所不同。例如,句柄定义为指针,而不是DWORD 32位整数。

除了初始化STARTUPINFO并确保使用正确的数据类型外,指针在64位窗口中的宽度为64位,而DWORD始终为32位,您还需要正确分配参数区域,有时也称为阴影空间:

即使使用alloca,参数区域也始终位于堆栈的底部,因此在任何函数调用期间,参数区域始终与返回地址相邻。 它至少包含四个条目,但始终有足够的空间容纳任何可能被调用的函数所需的所有参数。 请注意,始终为寄存器参数分配空间,即使参数本身从未回到堆栈中;被调用方保证已为其所有参数分配了空间

强调我的,来自

假设所需的所有数据结构都已正确初始化,则可能调用CreateProcessA:

请注意,调用方负责在调用后清理堆栈

您可以使用子rsp在堆栈上保留空间。。。这并非完全错误。 当然,你必须正确地计算,但最重要的是,这种技术不能立即与推送兼容

一旦你有子rsp。。。mov[rsp+…]类的一个或多个间接存储器。。。需要设置参数。
推操作只会再次移动堆栈指针,使之前的所有工作都无用。

在函数中保留足够的空间,以便调用具有如此多参数的子函数。 在函数prolog中使用

然后简单地分配整个参数列表

mov QWORD PTR [rsp+48h], rax                     
mov QWORD PTR [rsp+40h], rbx                     
mov QWORD PTR [rsp+38h], 00h                     
mov QWORD PTR [rsp+30h], 00h                     
mov QWORD PTR [rsp+28h], NORMAL_PRIORITY_CLASS
mov QWORD PTR [rsp+20h], 00h

xor r9, r9    ; pass 0              
xor r8, r8    ; pass 0
xor edx, edx  ; pass 0  (higher DWORD becomes always also zero, saving the REX-byte)
lea rcx, szProcName
call CreateProcessA  

这是一个有点老的问题,但因为我刚刚解决了它,所以把它写下来。 现在我也在为同样的问题而挣扎,但我的对手是NASM。 问题是一样的,但语法会有点不同。 您的问题是您的STARTUPINFOA和PROCESS_信息不正确,原因有二:

x64系统上的指针为DWORD64 您没有考虑64位系统上的结构填充 NASM语法中的正确结构如下所示:

; https://msdn.microsoft.com/library/windows/desktop/ms686331.aspx
STRUC _STARTUPINFOA
    .cb:                resq 1
    .lpReserved:        resq 1
    .lpDesktop:         resq 1
    .lpTitle:           resq 1
    .dwX:               resd 1
    .dwY:               resd 1
    .dwXSize:           resd 1
    .dwYSize:           resd 1
    .dwXCountChars:     resd 1
    .dwYCountChars:     resd 1
    .dwFillAttribute:   resd 1
    .dwFlags:           resd 1
    .wShowWindow:       resd 1
    .cbReserved2:       resd 1
    .lpReserved2:       resq 1
    .hStdInput:         resq 1
    .hStdOutput:        resq 1
    .hStdError:         resq 1
ENDSTRUC

; https://msdn.microsoft.com/library/windows/desktop/ms684873.aspx
STRUC _PROCESS_INFORMATION
    .hProcess:          resq 1
    .hThread:           resq 1
    .dwProcessId:       resd 1
    .dwThreadId:        resd 1
ENDSTRUC
一点解释:

resq=DWORD64 resd=DWORD32 如果遵循结构,大多数字段都可以正确填充,但有两个字段不同。原因是结构填充。MS编译器选择结构中最大的元素,然后将所有其他字段填充到该元素。为了给出示例,案例如下所示:

编译器选择DWORD64作为最大元素 cb字段是DWORD,但由于无法将其与下一个字段lpReserved:DWORD64填充,因此将其填充到DWORD64 lpReserved、lpDesktop和lpTitle已为DWORD64 从dwX到dwFlags,可以使用下一个元素填充大小,因此不会发生更改 wShowWindow和cbReserved2是唯一的字,所以编译器将它们一起填充到8个字节,以便将每个字段更改为DWORD 从lpReserved2到hStdError的数据都已写入DWORD64
当我做了正确的填充后,效果很好。祝你好运

在任何API调用之前,堆栈指针必须在16个字节上对齐,但在调用CreateProcessA之前不能这样做-这已经足够crashI使用子rsp 60h了。我已将此更改为子rsp,58h,但仍然不起作用。。。应该有什么值?调试器已经不存在查找何处崩溃?启动信息您也没有初始化..在调试器中我得到访问冲突。根据哪个指令?使用调试器的全部目的是获取详细信息并进一步调查,例如检查寄存器内容。参数区域通常称为阴影空间。很好地发现OP的代码没有遵循win64调用约定。我从来没有听说过术语DWORD64。在基于8086的体系结构上,双字双字总是32位宽。64位数字是qword四字。然后请打开visual studio并检查basestd.h:typedef unsigned\uuu int64 DWORD64,*PDWORD64;
mov QWORD PTR [rsp+48h], rax                     
mov QWORD PTR [rsp+40h], rbx                     
mov QWORD PTR [rsp+38h], 00h                     
mov QWORD PTR [rsp+30h], 00h                     
mov QWORD PTR [rsp+28h], NORMAL_PRIORITY_CLASS
mov QWORD PTR [rsp+20h], 00h

xor r9, r9    ; pass 0              
xor r8, r8    ; pass 0
xor edx, edx  ; pass 0  (higher DWORD becomes always also zero, saving the REX-byte)
lea rcx, szProcName
call CreateProcessA  
; https://msdn.microsoft.com/library/windows/desktop/ms686331.aspx
STRUC _STARTUPINFOA
    .cb:                resq 1
    .lpReserved:        resq 1
    .lpDesktop:         resq 1
    .lpTitle:           resq 1
    .dwX:               resd 1
    .dwY:               resd 1
    .dwXSize:           resd 1
    .dwYSize:           resd 1
    .dwXCountChars:     resd 1
    .dwYCountChars:     resd 1
    .dwFillAttribute:   resd 1
    .dwFlags:           resd 1
    .wShowWindow:       resd 1
    .cbReserved2:       resd 1
    .lpReserved2:       resq 1
    .hStdInput:         resq 1
    .hStdOutput:        resq 1
    .hStdError:         resq 1
ENDSTRUC

; https://msdn.microsoft.com/library/windows/desktop/ms684873.aspx
STRUC _PROCESS_INFORMATION
    .hProcess:          resq 1
    .hThread:           resq 1
    .dwProcessId:       resd 1
    .dwThreadId:        resd 1
ENDSTRUC