Hi,
I've wrote simple program, that creates new process. Main process is console program and child process is gui. when i run it program crashes. I've loaded it into debugger and it crash somewhere in the CreateProcessA. I don't know that function well. I guess that parameters i delivered was not suitable. What i did wrong?
here is the code of main app:
;--------MAKE-------------------------------------------------------------
;jwasm -win64 mt1.asm
;link /subsystem:console /entry:_start mt1.obj
;--------INCLUDES---------------------------------------------------------
includelib \jwasm\wininc208\lib64\kernel32.lib
includelib \jwasm\wininc208\lib64\user32.lib
;--------EXTERNALS--------------------------------------------------------
extern GetStdHandle :proc
extern ExitProcess :proc
extern CreateProcessA :proc
extern WriteConsoleA :proc
extern GetStartupInfoA :proc
;--------STRUCTS----------------------------------------------------------
STARTUPINFO STRUCT
cb DWORD ?
DWORD ? ; PADDING
lpReserved QWORD ?
lpDesktop QWORD ?
lpTitle QWORD ?
dwX DWORD ?
dwY DWORD ?
dwXSize DWORD ?
dwYSize DWORD ?
dwXCountChars DWORD ?
dwYCountChars DWORD ?
dwFillAttribute DWORD ?
dwFlags DWORD ?
wShowWindow WORD ?
cbReserved2 WORD ?
DWORD ? ;PADDING
lpReserved2 QWORD ?
hStdInput QWORD ?
hStdOutput QWORD ?
hStdError QWORD ?
STARTUPINFO ENDS
PROCESS_INFORMATION STRUCT
hProcess QWORD ?
hThread QWORD ?
dwProcessId DWORD ?
dwThreadId DWORD ?
PROCESS_INFORMATION ENDS
;--------CONSTS-----------------------------------------------------------
STD_OUTPUT_HANDLE equ -11
NORMAL_PRIORITY_CLASS equ 20h
NULL equ 0h
FALSE equ 0h
;--------DATA-------------------------------------------------------------
.data?
TestStartUp STARTUPINFO<>
TestProcessInfo PROCESS_INFORMATION<>
hStdOut dq ?
qwWritten dq ?
.data
tAppName db "mt.exe",0
tCreateProcessFailed db "CreateProcess failed "
tCreateProcessSuccess db "CreateProcess success"
;--------CODE-------------------------------------------------------------
.code
_start proc
mov rcx, STD_OUTPUT_HANDLE
call GetStdHandle
mov hStdOut, rax
mov rcx, offset TestStartUp
call GetStartupInfoA
mov rcx, offset TestProcessInfo
xor rdx, rdx
xor r8, r8
xor r9, r9
sub rsp, [4 * 8]
push FALSE
push NORMAL_PRIORITY_CLASS
push NULL
push NULL
mov rax, offset TestStartUp
push rax
mov rax, offset TestProcessInfo
push rax
call CreateProcessA
test rax, rax
mov rbx, offset tCreateProcessFailed
mov rdx, offset tCreateProcessSuccess
cmovz rdx, rbx
mov rcx, hStdOut
mov r8, lengthof tCreateProcessSuccess
mov r9, offset qwWritten
mov qword ptr [rsp + 8 * 4], 0
call WriteConsoleA
xor rcx, rcx
call ExitProcess
_start endp
end
and child app:
;--------MAKE-------------------------------------------------------------
;jwasm -win64 mt.asm
;link /subsystem:windows /entry:_start mt.obj
;--------INCLUDES---------------------------------------------------------
includelib \jwasm\wininc208\lib64\kernel32.lib
includelib \jwasm\wininc208\lib64\user32.lib
;--------EXTERNALS--------------------------------------------------------
extern ExitProcess :near
extern MessageBoxA :near
;--------DATA-------------------------------------------------------------
.data?
.data
tCpt db 'My name is MT', 0
tMsg db "Hi, I'm process created by MT1 app!", 0
;--------CODE-------------------------------------------------------------
.code
_start proc
sub rsp,28h ;shadow space, aligns stack
mov rcx, 0 ;hWnd = HWND_DESKTOP
lea rdx, tMsg ;LPCSTR lpText
lea r8, tCpt ;LPCSTR lpCaption
mov r9d, 0 ;uType = MB_OK
call MessageBoxA ;call MessageBox API functio call MessageBoxA
xor rcx, rcx
call ExitProcess
_start endp
end
Quote from: vogelsang on October 11, 2013, 03:47:42 PM
mov rcx, offset TestProcessInfo
xor rdx, rdx
xor r8, r8
xor r9, r9
sub rsp, [4 * 8]
push FALSE
push NORMAL_PRIORITY_CLASS
push NULL
push NULL
mov rax, offset TestStartUp
push rax
mov rax, offset TestProcessInfo
push rax
call CreateProcessA
I'd say the call of CreateProcess should rather look like this:
mov rcx, offset TestProcessInfo
xor rdx, rdx
xor r8, r8
xor r9, r9
mov rax, offset TestProcessInfo
push rax
mov rax, offset TestStartUp
push rax
push NULL
push NULL
push NORMAL_PRIORITY_CLASS
push FALSE
sub rsp, [4 * 8]
call CreateProcessA
add rsp, 10*8
It's still not quite correct, because it's not SEH-safe, but might work.
With this code it's not crashing, but it shows now my message: "CreateProcess failed" and mt.exe is not running. I've found bug. I should load to rcx ptr to tAppName, but when i fix it crashes.
I took a piece of code form Iczelion's tutorial example and tried to convert it to 64 bits. Maybe something messed myself too. How should look like correct SEH call?
btw which inc files from jwasm package contains WinAPI/C structs and function protos? I searched few, but didn't found. The structs i used comes form masm64 inc file, but that file not working neither with masm or jwasm.
Is the stack aligned to 16 before all the pushes?
to be honest i don't know. whole code is in first post.
At entry the stack is off by 8 (unless jwasm takes care of that).
The main problem is that every API call requires 4*8 bytes of "spill". That matches the first 4 params and is needed even for < 4 params.
Sometimes you get away with it, sometimes it goes "bang".
Most procs will align the stack, allocate space for the API call with the most params and space for locals in one "sub rsp,nn" and reuse the spill/param stack.
The convention seems to use "mov [rsp+20h],param 5" rather than a push.
Quote from: vogelsang on October 11, 2013, 10:07:28 PM
to be honest i don't know. whole code is in first post.
A simple "sub rsp, 40" just after _start will ensure that the stack is aligned.
Quote(unless jwasm takes care of that).
No. for a simple PROC ( without FRAME ) nothing is done.
QuoteA simple "sub rsp, 40" just after _start will ensure that the stack is aligned.
now app works fine. thanks guys for help.