The MASM Forum

General => The Campus => Topic started by: henry.chris on March 01, 2013, 05:36:20 PM

Title: Way besides ExitProcess to exit a program?
Post by: henry.chris on March 01, 2013, 05:36:20 PM
This is a college programming assignment in masm32 using kernel32.lib

I'm trying to learn how to use windows API functions in my code, and have been successful with several.
Currently I want to learn how to exit a program without using invoke ExitProcess, 0
I have tried several things and feel I am getting closer, but am hitting a road block.  My goal is to
display "Goodbye" to the user for a small amount of time and then exit.
I am currently trying to use
invoke SetConsoleTitleA, near32 ptr currentTitle ; sets current title to Haha
invoke FindWindowA, 0h, near32 ptr currenTitle            ; Returns window handle


and then call

invoke SendMessageA,hwnd_window,WM_SYSCOMMAND,SC_CLOSE, 0h

I am trying to use FindWindow to return the handle for SendMessageA; however, I can't even
figure out how to use the return from the function in assembly. I can't find where it's returned to,
or how to set something to the return of the function if that is the case. 

I figure i can use SendMessageA to close the console at least.

Any ways I can exit with a displayed string and not just, "Press any key to Continue..."
like I usually get would be of great help.

Title: Re: Way besides ExitProcess to exit a program?
Post by: MichaelW on March 01, 2013, 06:08:45 PM
Assuming that ESP has the same value that it had at entry (IOW, anything that was pushed onto the stack has been removed from the stack), you can set the return value in EAX and use RET.

    printf("Bye")
    invoke Sleep, 2000
    xor eax, eax
    ret

Title: Re: Way besides ExitProcess to exit a program?
Post by: henry.chris on March 01, 2013, 06:23:04 PM
I defined the Sleep function and used it correctly. That works beautifully, thank you.
I'm not sure I completely understand the esp, but I think everything is pulled off the stack.
Using 'ret' seems to do the exact same thing as invoke ExitProcess, 0        though. The
"Goodbye" message is displayed, then the 'ret' exits the program and it displays "Press any key to continue..."

Is it a setting I have turned on somewhere? Should ExitProcess even ask to 'press a key to continue..."
or should it just close the console automatically?
Title: Re: Way besides ExitProcess to exit a program?
Post by: MichaelW on March 01, 2013, 07:01:39 PM
"Press any key to continue ..." is what the inkey macro displays. Perhaps I should have added that you cannot do this within a procedure. Here is my full test source:

;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
    .data
    .code
;==============================================================================
start:
;==============================================================================
    printf("Bye")
    invoke Sleep, 2000
    xor eax, eax
    ret
;==============================================================================
end start


And perhaps I should also have added that you probably should not be using the inkey macro in a GUI app.

Also, if you are running the app from a batch file with a PAUSE command then you should see "Press any key to continue . . ." after the app terminates.
Title: Re: Way besides ExitProcess to exit a program?
Post by: jj2007 on March 01, 2013, 11:31:25 PM
The main difference between a simple ret and ExitProcess is that the latter uses a different way out.

ExitProce   8BC0            mov eax, eax                             ; kernel32.ExitProcess(ExitCode)
75CCBBE4    55              push ebp
75CCBBE5    8BEC            mov ebp, esp
75CCBBE7    6A FF           push -1
75CCBBE9    68 B0F3E877     push 77E8F3B0
75CCBBEE    FF75 08         push dword ptr [ebp+8]
75CCBBF1    FF15 1017C775   call dword ptr [<&ntdll.RtlExitUserProcess
... code never gets here ...
75CCBBF7    E9 ACE40000     jmp 75CDA0A8

BaseThreadInitThunk    8BFF            mov edi, edi
75CBED5C               55              push ebp
75CBED5D               8BEC            mov ebp, esp
75CBED5F               85C9            test ecx, ecx
75CBED61               0F85 4D010000   jne 75CBEEB4
75CBED67               FF75 08         push dword ptr [ebp+8]
75CBED6A               FFD2            call edx   << edx=00401000h, ret returns here
75CBED6C               50              push eax
75CBED6D               FF15 0C17C775   call dword ptr [<&ntdll.RtlExitUserThread
[/color]
Title: Re: Way besides ExitProcess to exit a program?
Post by: dedndave on March 01, 2013, 11:54:16 PM
RtlExitUserProcess calls NtTerminateProcess
but, i am wondering what is wrong with ExitProcess ???   :P

    INVOKE  Sleep,-1
it may not terminate, but it will stop doing stuff   :biggrin:
Title: Re: Way besides ExitProcess to exit a program?
Post by: Magnum on March 02, 2013, 04:13:01 AM

CPU Disasm
Address   Hex dump          Command                                  Comments
00401000  /$  68 00304000   PUSH OFFSET 00403000                     ; /format = "Bye"
00401005  |.  FF15 24204000 CALL DWORD PTR DS:[<&msvcrt.printf>]     ; \MSVCRT.printf
0040100B  |.  83C4 04       ADD ESP,4
0040100E  |.  68 D0070000   PUSH 7D0                                 ; /Time = 2000. ms
00401013  |.  E8 28000000   CALL <JMP.&kernel32.Sleep>               ; \KERNEL32.Sleep
00401018  |.  33C0          XOR EAX,EAX
0040101A  \.  C3            RETN



I wonder why this differs ?
Title: Re: Way besides ExitProcess to exit a program?
Post by: henry.chris on March 02, 2013, 05:57:30 AM
Ok, so at my school we have to use the visual studio environment for masm.  It just seems like it's how studio exits a program in assembly. It doesn't do this for .cpp or other languages i've used, so I just expected it to be a part of the ExitProcess somehow.  I used a different compiler etc... and got it to close successfully.  The invoke Sleep, -1 is actually cool if you have to display a long message.

Thank you for your time, I'm still learning so I was having a hard time parsing what you gave me.

If I may, I have another question now. Tell me if I need a new thread or anything else.  I'm trying to poll the keyboard for a keypress. Basically..instead of needing to "press enter to continue" I just want to poll most any one keypress.  I searched and saw dedndave's procedure but cannot get it to work for some reason.   I then tried using invoke WaitForSingleObject, STD_INPUT, 0FFFFFFFFh ....which works great, but leaves the keypress in the buffer. So, after my call to this function, I clear the screen and output a menu...the keypress is recorded in the place I ask the user to choose a menu item.  I then searched for functions to clear that from the buffer. I thought invoke FlushConsoleInputBuffer would work with the correct handle...but it doesn't seem to.   Does anyone have an idea of how I could keep that keypress from being recorded?
Title: Re: Way besides ExitProcess to exit a program?
Post by: qWord on March 02, 2013, 06:15:24 AM
Quote from: henry.chris on March 02, 2013, 05:57:30 AMDoes anyone have an idea of how I could keep that keypress from being recorded?
As usual there are several ways, but the simplest is probably to use the CRT function _getch():
invoke GetStdHandle,STD_INPUT_HANDLE
invoke FlushConsoleInputBuffer,eax
invoke crt__getch ; reads one char. from input, but does not echo it
Title: Re: Way besides ExitProcess to exit a program?
Post by: Zen on March 02, 2013, 06:31:32 AM
My all-time favorite means of Process Termination is: Bug Check (http://msdn.microsoft.com/en-us/library/hh994433(v=vs.85).aspx),...this is especially satisfying if you are drunk.
Here is the MSDN documentation: KeBugCheck routine (http://msdn.microsoft.com/en-us/library/windows/hardware/ff551948(v=vs.85).aspx)
Title: Re: Way besides ExitProcess to exit a program?
Post by: dedndave on March 02, 2013, 06:48:00 AM
getch is what you want   :t
Title: Re: Way besides ExitProcess to exit a program?
Post by: henry.chris on March 02, 2013, 06:58:26 AM
Ok, _getch it is, I tried it before when trying to implement your proc Dedndave...could not get it to work for some reason.
I'll try the bug check routine also just to see what it does.  Thank you all for your time. 
Title: Re: Way besides ExitProcess to exit a program?
Post by: dedndave on March 02, 2013, 10:35:37 AM
it may have something to do with the fact it is being called from another thread
i am no C expert, but i think there is a "thread-safe" version of MSVCRT that you can use
one of the C guys may be able to help you more

an alternate approach is to use the keyboard polling routine in a "round-robin" style loop
that way, you don't have to start another thread
Title: Re: Way besides ExitProcess to exit a program?
Post by: MichaelW on March 02, 2013, 06:59:48 PM
Per MSDN "These functions lock the calling thread and are therefore thread-safe."

http://msdn.microsoft.com/en-US/library/078sfkak(v=vs.80).aspx

But the source from the PSDK uses #ifdef _MT to determine whether to lock or not, so the only way to know for sure is to trace it in a debugger (this under Windows XP):

77C2EAA1   8BFF             MOV EDI,EDI   ; ntdll.7C910228
77C2EAA3   56               PUSH ESI
77C2EAA4   6A 03            PUSH 3
77C2EAA6   E8 10BB0000      CALL msvcrt._lock
77C2EAAB   E8 95FDFFFF      CALL msvcrt.77C2E845
77C2EAB0   6A 03            PUSH 3
77C2EAB2   8BF0             MOV ESI,EAX
77C2EAB4   E8 60BA0000      CALL msvcrt._unlock
77C2EAB9   59               POP ECX
77C2EABA   59               POP ECX
77C2EABB   8BC6             MOV EAX,ESI
77C2EABD   5E               POP ESI
77C2EABE   C3               RETN