News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

CreateProcess problem

Started by vogelsang, October 11, 2013, 03:47:42 PM

Previous topic - Next topic

vogelsang

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
"How beautiful this world ruled by dibs, not a gun!"
...

japheth

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.

vogelsang

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.
"How beautiful this world ruled by dibs, not a gun!"
...

sinsi

Is the stack aligned to 16 before all the pushes?

vogelsang

to be honest i don't know. whole code is in first post.
"How beautiful this world ruled by dibs, not a gun!"
...

sinsi

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.

japheth

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.

vogelsang

QuoteA simple "sub rsp, 40" just after _start will ensure that the stack is aligned.
now app works fine. thanks guys for help.
"How beautiful this world ruled by dibs, not a gun!"
...