Windows CreateProcessA函数在MASM64(ml64.exe)中不工作
我想写一个启动另一个程序进程的程序。我正在使用Visual Studio 2015中的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
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