The MASM Forum

64 bit assembler => 64 bit assembler. Conceptual Issues => Topic started by: vogelsang on October 11, 2013, 03:47:42 PM

Title: CreateProcess problem
Post by: vogelsang on October 11, 2013, 03:47:42 PM
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
Title: Re: CreateProcess problem
Post by: japheth on October 11, 2013, 07:50:07 PM
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.
Title: Re: CreateProcess problem
Post by: vogelsang on October 11, 2013, 09:43:28 PM
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.
Title: Re: CreateProcess problem
Post by: sinsi on October 11, 2013, 09:55:28 PM
Is the stack aligned to 16 before all the pushes?
Title: Re: CreateProcess problem
Post by: vogelsang on October 11, 2013, 10:07:28 PM
to be honest i don't know. whole code is in first post.
Title: Re: CreateProcess problem
Post by: sinsi on October 11, 2013, 10:35:06 PM
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.
Title: Re: CreateProcess problem
Post by: japheth on October 11, 2013, 10:43:09 PM
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.
Title: Re: CreateProcess problem
Post by: vogelsang on October 11, 2013, 11:25:02 PM
QuoteA simple "sub rsp, 40" just after _start will ensure that the stack is aligned.
now app works fine. thanks guys for help.