flat assembler
Message board for the users of flat assembler.

Index > Windows > Confusing jne...

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Athlon64



Joined: 28 Feb 2012
Posts: 5
Athlon64
Hi there! I just got the fasm for windows package, and in the EXAMPLES\TEMPLATE\TEMPLATE.ASM file, I found some codes like this:
Code:
  msg_loop:
    invoke  GetMessage,msg,NULL,0,0
     cmp     eax,1
       jb      end_loop
    jne     msg_loop
    invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
 jmp     msg_loop

  error:
        invoke  MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK

  end_loop:
       invoke  ExitProcess,[msg.wParam]
    

I know it means to keep getting messages from Windows until it got a WM_QUIT, but what's the "jne msg_loop" for?
Post 28 Feb 2012, 16:52
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
It looks like it is avoiding processing the message if an error is detected (GetMessage returns -1 on error and since the value looks greater than 1 when doing unsigned comparisons it is catched by the second conditional jump). Now, this theory would work if -2 < return_value < 2, however, Microsoft states "nonzero, zero, or -1" so it could be potentially not processing some valid messages.

In case it is not clear what is doing the code, here it is what it does:
Code:
loop:
if GetMessage returned 0 ; i.e. WM_QUIT was sent
  goto exit
else if GetMessage returned 1
  process the message
end if

goto loop

exit:
exit program    
Post 28 Feb 2012, 18:08
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
I think this code will handle nonzero correctly:
Code:
  msg_loop:
        invoke  GetMessage,msg,NULL,0,0
        add     eax,1
        cmp     eax,1
        jb      msg_loop ; jump if EAX was -1 (Get next message on error)
        je      end_loop ; jump if EAX was 0  (Get out if WM_QUIT was sent)
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp     msg_loop

  error:
        invoke  MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK

  end_loop:
        invoke  ExitProcess,[msg.wParam]    
Post 28 Feb 2012, 18:37
View user's profile Send private message Reply with quote
mindcooler



Joined: 01 Dec 2009
Posts: 423
Location: Västerås, Sweden
mindcooler
Here is my straight-forward ninja-if-error one:

Code:
.msgloop:
        invoke  GetMessageA,msg,NULL,0,0
        or      eax,eax
        jz      .out
        cmp     eax,-1
        je      .out
        invoke  TranslateMessage,msg
        invoke  DispatchMessageA,msg
        jmp     .msgloop

 .out:
        ret    

_________________
This is a block of text that can be added to posts you make.
Post 28 Feb 2012, 20:15
View user's profile Send private message Visit poster's website MSN Messenger ICQ Number Reply with quote
shutdownall



Joined: 02 Apr 2010
Posts: 518
Location: Munich
shutdownall
Your second jump is wrong.
When eax is 0 you end loop (WM_QUIT).
When eax is -1 you have to stay still in loop but not process last message.
So second jump has to go to .msgloop.
Post 29 Feb 2012, 00:36
View user's profile Send private message Send e-mail Reply with quote
mindcooler



Joined: 01 Dec 2009
Posts: 423
Location: Västerås, Sweden
mindcooler
shutdownall wrote:
When eax is -1 you have to stay still in loop but not process last message.


Says who?

_________________
This is a block of text that can be added to posts you make.
Post 29 Feb 2012, 00:39
View user's profile Send private message Visit poster's website MSN Messenger ICQ Number Reply with quote
shutdownall



Joined: 02 Apr 2010
Posts: 518
Location: Munich
shutdownall
mindcooler wrote:
shutdownall wrote:
When eax is -1 you have to stay still in loop but not process last message.


Says who?

Microsoft. Rolling Eyes

Code:
BOOL bRet;

while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{ 
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
}
    


http://msdn.microsoft.com/en-us/library/windows/desktop/ms644936%28v=vs.85%29.aspx
Post 29 Feb 2012, 00:43
View user's profile Send private message Send e-mail Reply with quote
Athlon64



Joined: 28 Feb 2012
Posts: 5
Athlon64
Thank you all guys!
So I think this example is buggy, maybe a better way is:
Don't handle GetMessage() error:
Code:
  msg_loop: 
        invoke  GetMessage,msg,NULL,0,0 
        cmp     eax,1 
        jb      end_loop 
        invoke  TranslateMessage,msg 
        invoke  DispatchMessage,msg 
        jmp     msg_loop 

  end_loop: 
        invoke  ExitProcess,[msg.wParam]
    

Or
Code:
  msg_loop: 
        invoke  GetMessage,msg,NULL,0,0
        inc     eax
        cmp     eax, 1 
        jb      error_handler ; jump if EAX was -1
        je      end_loop      ; jump if EAX was 0  (Get out if WM_QUIT was sent)
    dec     eax           ; avoid something unexpected happen if Windows use the return value of GetMessage() to do something else
        invoke  TranslateMessage,msg 
        invoke  DispatchMessage,msg 
        jmp     msg_loop 

  error_handler: 
        ;; handle the error
    jmp     msg_loop

  end_loop: 
        invoke  ExitProcess,[msg.wParam]
    

if you need to handle it.
Post 29 Feb 2012, 03:21
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16901
Location: In your JS exploiting you and your system
revolution
Athlon64 wrote:
Code:
    dec     eax           ; avoid something unexpected happen if Windows use the return value of GetMessage() to do something else    
This is not necessary. The stdcall convention does not use eax (or any other GPR) for input values to functions.
Post 29 Feb 2012, 03:26
View user's profile Send private message Visit poster's website Reply with quote
Athlon64



Joined: 28 Feb 2012
Posts: 5
Athlon64
revolution wrote:
Athlon64 wrote:
Code:
     dec     eax           ; avoid something unexpected happen if Windows use the return value of GetMessage() to do something else    
This is not necessary. The stdcall convention does not use eax (or any other GPR) for input values to functions.


Thanks a lot! Very Happy
Post 29 Feb 2012, 03:36
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7494
Location: Kraków, Poland
Tomasz Grysztar
That's strange, my old API reference has this information:
WIN32.HLP on GetMessage wrote:
Note that the function return value can be TRUE, FALSE, or -1.
But now MSDN only has the fragment about "nonzero, zero, or -1" (which is a bit misleading, because -1 is also a nonzero value). In example code they use BOOL type, and then compare it against -1 (wow, this type checking is almost like with assembly Wink).

And the comment from "Enzo Baker" proposes how to clean this up. Which would not be that much needed if they kept that old phrase from WIN32.HLP reference.
Post 29 Feb 2012, 08:57
View user's profile Send private message Visit poster's website Reply with quote
Athlon64



Joined: 28 Feb 2012
Posts: 5
Athlon64
more simple...
Code:
  msg_loop: 
        invoke  GetMessage,msg,NULL,0,0
        cmp     eax, 1 
        jb      end_loop      ; jump if EAX was 0  (Get out if WM_QUIT was sent)
        jl      error_handler ; jump if EAX was -1
        invoke  TranslateMessage,msg 
        invoke  DispatchMessage,msg 
        jmp     msg_loop 

  error_handler: 
        ;; handle the error
     jmp     msg_loop

  end_loop: 
        invoke  ExitProcess,[msg.wParam]
    
Post 29 Feb 2012, 10:44
View user's profile Send private message Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3500
Location: Bulgaria
JohnFound
AFAIK, the function GetMessage returns -1 only if the arguments have some invalid values. When you call it with <msg, 0, 0, 0> it simply can't fail.

So, what the error handler is supposed to do?
Post 29 Feb 2012, 10:58
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16901
Location: In your JS exploiting you and your system
revolution
Athlon64 wrote:
Code:
...
        cmp     eax, 1 
        jb      end_loop      ; jump if EAX was 0  (Get out if WM_QUIT was sent)
        jl      error_handler ; jump if EAX was -1
        invoke  TranslateMessage,msg 
...    
Since we are wasting time trying to optimise this, then let's do it properly. Wink
Code:
...
  test eax,eax
  jz end_loop
  js error_handler
...    
Post 29 Feb 2012, 11:01
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16901
Location: In your JS exploiting you and your system
revolution
JohnFound wrote:
AFAIK, the function GetMessage returns -1 only if the arguments have some invalid values. When you call it with <msg, 0, 0, 0> it simply can't fail.
Oh ye have little faith in the potential sources of error within a computer program. At least one source of error is that msg could be corrupted.

BTW: Haven't you ever heard of Murphy's Law?
Post 29 Feb 2012, 11:03
View user's profile Send private message Visit poster's website Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3500
Location: Bulgaria
JohnFound
How "msg" could be corrupted? It is just a buffer that GetMessage fills with information. The content of this buffer is not important and Windows will never use it. The size of the buffer is under the control of the programmer, so it can't be "corrupted".

Of course, some example of GetMessage returning -1 in the above circumstances will prove I am wrong. Smile
Post 29 Feb 2012, 11:12
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16901
Location: In your JS exploiting you and your system
revolution
JohnFound wrote:
How "msg" could be corrupted?
Well, let's see ...
JohnFound wrote:
It is just a buffer that GetMessage fills with information. The content of this buffer is not important and Windows will never use it.
Correct so far ...
JohnFound wrote:
The size of the buffer is under the control of the programmer, so it can't be "corrupted".
Aha! There is the problem right there. What if the program(mer) releases the memory page (errantly or course) where msg is supposed to be?

What if when processing a message Windows has a bug (Shock! Horror! Surely not!) and fails to generate a response, thus returning -1.

In short, I don't actually know what might cause an error. But then how do you know that such a call will never generate an error either?

Executive summary: It will most probably never ever return -1 so all this is mostly moot, but just in case it ever does ... then what? Crash?
Post 29 Feb 2012, 11:22
View user's profile Send private message Visit poster's website Reply with quote
mindcooler



Joined: 01 Dec 2009
Posts: 423
Location: Västerås, Sweden
mindcooler
@shutdownall
"handle the error and possibly exit"

_________________
This is a block of text that can be added to posts you make.
Post 29 Feb 2012, 11:37
View user's profile Send private message Visit poster's website MSN Messenger ICQ Number Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3500
Location: Bulgaria
JohnFound
Quote:
but just in case it ever does ... then what? Crash?


If we suppose Windows is buggy (it is possible of course) why you think it will return exactly -1??? The buggy GetMessage can return everything (in EAX and [msg] as well), so processing this kind of errors is impossible by default.

In this case if you want to be super cautious, you must control the validity of the [msg] structure content. So if [msg] contains invalid message number or data, to not pass it to TranslateMessage/DispatchMessage.
Post 29 Feb 2012, 11:45
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 688
Location: Adelaide
sinsi
I would think that -1 would be returned for the first call only - if hwnd was invalid (e.g. lots of code don't check the return value of CreateWindow) or MSG was in the code section (saw that once).
So it's not a true BOOL then, maybe TRUE/FALSE will change too eh?
Post 29 Feb 2012, 12:02
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2019, Tomasz Grysztar.

Powered by rwasa.