Zero
Joined: 02 Aug 2008
Posts: 16
|
I've reach tutorial 14 on Process creation by iczelion. I've studied his code, as well as the FASM translation and it seems pretty straightforward. The name of the executable file is specified, as well as some flags and a PROCESS_INFORMATION structure and a STARTUPINFO structure that is initialized via the GetStartupInfo function.
So I tried running the program, but I get an error from windows stating that the program needs to close. My first suspicion was that perhaps CreateProcess was failing, so I added some code to check its return value and I "think" its OK.
The next possibility was a resource leak somewhere. I've looked at the code now for a few hours and can't find any errors with it. The program seems to close both the thread handle and the process handle correctly.
The code is below. I'd appreciate it if someone could help me unravel this thing as it's driving me mad.
format PE GUI 4.0
entry start
include '%fasminc%\win32a.inc'
; +-----------------------+
; | menu item declaration |
; +-----------------------+
MI_PROCESS_CREATE equ 110
MI_PROCESS_TERMINATE equ 120
MI_EXIT equ 190
section '.data' data readable writeable
sTitle db 'Tutorial 14',0
sClsName db 'TUT14',0
mbCaption db 'Message Box Title',0
mbText db 'Create Process Failed',0
hWindow dd ?
hInstance dd ?
msg MSG
wc WNDCLASS
hMenu dd ? ;menu handle
proExitCode dd ? ;process exit code
progName db 'sixmore.exe',0
progStartInfo STARTUPINFO
pi PROCESS_INFORMATION
section '.code' code readable executable
start:
; +------------------------------+
; | registering the window class |
; +------------------------------+
invoke GetModuleHandle,NULL
mov [hInstance],eax
mov [wc.hInstance],eax
mov [wc.style],CS_HREDRAW or CS_VREDRAW
mov [wc.lpfnWndProc],window_procedure
mov [wc.lpszClassName],sClsName
mov [wc.lpszMenuName],30
mov [wc.hbrBackground],COLOR_WINDOW+1
invoke LoadIcon,NULL,IDI_APPLICATION
mov [wc.hIcon],eax
invoke LoadCursor,NULL,IDC_ARROW
mov [wc.hCursor],eax
invoke RegisterClass,wc
; +--------------------------+
; | creating the main window |
; +--------------------------+
invoke CreateWindowEx,\
WS_EX_CLIENTEDGE,\
sClsName,\
sTitle,\
WS_OVERLAPPEDWINDOW or WS_VISIBLE,\
CW_USEDEFAULT,\
CW_USEDEFAULT,\
300,\
200,\
NULL,\
NULL,\
[hInstance],\
NULL
mov [hWindow],eax
invoke GetMenu,eax
mov [hMenu],eax
; +---------------------------+
; | entering the message loop |
; +---------------------------+
window_message_loop_start:
invoke GetMessage,msg,NULL,0,0
or eax,eax
je window_message_loop_end
invoke TranslateMessage,msg
invoke DispatchMessage,msg
jmp window_message_loop_start
window_message_loop_end:
invoke ExitProcess,0
; +----------------------+
; | the window procedure |
; +----------------------+
proc window_procedure,hWnd,uMsg,wParam,lParam
push ebx esi edi
cmp [uMsg],WM_INITMENUPOPUP
je wmINITMENUPOPUP
cmp [uMsg],WM_COMMAND
je wmCOMMAND
cmp [uMsg],WM_DESTROY
je wmDESTROY
wmDEFAULT:
invoke DefWindowProc,[hWnd],[uMsg],[wParam],[lParam]
jmp wmBYE
wmINITMENUPOPUP:
invoke GetExitCodeProcess,[pi.hProcess],proExitCode
cmp eax,TRUE
je GetExitCodeProcess_TRUE
invoke EnableMenuItem,[hMenu],MI_PROCESS_CREATE,MF_ENABLED
invoke EnableMenuItem,[hMenu],MI_PROCESS_TERMINATE,MF_GRAYED
jmp wmBYE
GetExitCodeProcess_TRUE:
cmp [proExitCode],STILL_ACTIVE
je GetExitCodeProcess_STILL_ACTIVE
invoke EnableMenuItem,[hMenu],MI_PROCESS_CREATE,MF_ENABLED
invoke EnableMenuItem,[hMenu],MI_PROCESS_TERMINATE,MF_GRAYED
jmp wmBYE
GetExitCodeProcess_STILL_ACTIVE:
invoke EnableMenuItem,[hMenu],MI_PROCESS_CREATE,MF_GRAYED
invoke EnableMenuItem,[hMenu],MI_PROCESS_TERMINATE,MF_ENABLED
jmp wmBYE
wmCOMMAND:
cmp [wParam],0xFFFF and MI_PROCESS_CREATE
je wmCOMMAND_MI_PROCESS_CREATE
cmp [wParam],0xFFFF and MI_PROCESS_TERMINATE
je wmCOMMAND_MI_PROCESS_TERMINATE
cmp [wParam],0xFFFF and MI_EXIT
je wmCOMMAND_MI_EXIT
jmp wmBYE
wmCOMMAND_MI_EXIT:
invoke DestroyWindow,[hWnd]
jmp wmBYE
wmCOMMAND_MI_PROCESS_CREATE:
cmp [pi.hProcess],0
je pi_hProcess_IS_0
invoke CloseHandle,[pi.hProcess]
mov [pi.hProcess],0
pi_hProcess_IS_0:
invoke GetStartupInfo,[progStartInfo]
invoke CreateProcess,progName,NULL,NULL,NULL,FALSE,\
NORMAL_PRIORITY_CLASS,\
NULL,NULL,progStartInfo,pi
;Check if Create Process was successful
cmp eax,0
jne tst
invoke MessageBox,mbText,mbCaption,MB_OK
jmp wmBYE
tst:
invoke CloseHandle,[pi.hThread]
jmp wmBYE
wmCOMMAND_MI_PROCESS_TERMINATE:
invoke GetExitCodeProcess,[pi.hProcess],proExitCode
cmp [proExitCode],STILL_ACTIVE
jne proExitCode_NOT_STILL_ACTIVE
invoke TerminateProcess,[pi.hProcess],0
proExitCode_NOT_STILL_ACTIVE:
invoke CloseHandle,[pi.hProcess]
mov [pi.hProcess],0
jmp wmBYE
close_all: invoke CloseHandle,[pi.hThread]
invoke CloseHandle,[pi.hProcess]
jmp wmBYE
wmDESTROY:
invoke PostQuitMessage,0
wmBYE:
pop edi esi ebx
ret
endp
section '.idata' import data readable writeable
library KERNEL32, 'KERNEL32.DLL',\
USER32, 'USER32.DLL'
import KERNEL32,\
GetModuleHandle, 'GetModuleHandleA',\
GetExitCodeProcess, 'GetExitCodeProcess',\
GetStartupInfo, 'GetStartupInfoA',\
CreateProcess, 'CreateProcessA',\
TerminateProcess, 'TerminateProcess',\
CloseHandle, 'CloseHandle',\
ExitProcess, 'ExitProcess'
import USER32,\
RegisterClass, 'RegisterClassA',\
CreateWindowEx, 'CreateWindowExA',\
DefWindowProc, 'DefWindowProcA',\
LoadCursor, 'LoadCursorA',\
LoadIcon, 'LoadIconA',\
GetMenu, 'GetMenu',\
EnableMenuItem, 'EnableMenuItem',\
GetMessage, 'GetMessageA',\
DestroyWindow, 'DestroyWindow',\
TranslateMessage, 'TranslateMessage',\
DispatchMessage, 'DispatchMessageA',\
PostQuitMessage, 'PostQuitMessage',\
MessageBox, 'MessageBoxA'
section '.rsrc' resource data readable
directory RT_MENU,appMenu
resource appMenu,\
30,LANG_NEUTRAL,menuMain
menu menuMain
menuitem '&Process',0,MFR_POPUP + MFR_END
menuitem '&Create Process',MI_PROCESS_CREATE,MFT_STRING
menuitem '&Terminate Process',MI_PROCESS_TERMINATE,MFT_STRING
menuseparator
menuitem '&Exit',MI_EXIT,MFR_END
|