News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Do I need to hook this MessageBox?

Started by Trope, March 07, 2005, 04:30:36 PM

Previous topic - Next topic

Trope

Hi again. I am stuck on a project.

I am having difficulties in retrieving specific information in a MessageBox. I am writing an application that will be monitoring another application. We're all familiar with the following:

int MessageBox(

    HWND hWnd,   // handle of owner window
    LPCTSTR lpText,   // address of text in message box
    LPCTSTR lpCaption,   // address of title of message box 
    UINT uType    // style of message box
   );


but my question is, how do I retrieve and compare LPCTSTR lpText in the Target application?

I have successfully been able to obtain the MessageBox's handle by using the following:



invoke FindWindow, 0, ADDR winname
cmp eax, 0 ; if window does not exist
je @notThere    ; goto end
mov targethandle, eax   ; Prog handle



and I have been able to successfully CLOSE the MessageBox by Sending a WM_CLOSE Message (thanks to this forum).

But in between these, I want to compare the Text of the MessageBox.

I have tried things like:



invoke GetDlgItemText,targethandle,??,offset textcheck, SIZEOF textcheck



no luck. I suppose if I knew how, I could Hook the MessageBox somehow, but I am hoping there is an easier way.

I know that MessageBox's have their own MessageProc. Does this have something to do with the reason I cannot get to the MessageBox's Text parameter or something?

Any help would be terrific. I have been stuck on this for many hours (going on days) now.

Here is my skeleton program I have:



; MessageBox Monitor
;
; --------------------------------------------------------------------

.486
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data

winname        db "Status", 0
wrongText      db "Application Has Finished!", 0
appName        db "DebugMessage",0
appCaption     db "We found the MessageBox Text!",0
notfound       db "Cant find it",0

buffer         db 128 dup(0)
textcheck   db 128 dup(0)

.data?
targethandle   dd ?     ; handle to the program

.code
start:
invoke FindWindow, 0, ADDR winname

cmp eax, 0 ; if window does not exist
je @notfound    ; goto end
mov targethandle, eax   ; store handle

// THIS Dont work:
// invoke GetDlgItemText,targethandle,0,offset textcheck, SIZEOF textcheck
// i dont know how to get the control id of the text, if there even IS one
// THIS IS WHERE I NEED HELP
//

invoke lstrcmp, ADDR textcheck, ADDR wrongText
cmp eax, 0
je @notfound

; found it, now close it and continue.
; .
; .
; .
; invoke SendMessage, eax, WM_CLOSE, 0, 0

@end:

; ----------------------------

invoke ExitProcess, 0


@found:

invoke MessageBox, 0, ADDR appName, ADDR textcheck, 0 ;
jmp @end


@notfound:
invoke MessageBox, 0, ADDR notfound, ADDR appName, 0 ;
jmp @end


end start



Thanks Again!!

Trope


Infro_X

No, you can use EnumChildWindows to enumerate the static box, as well as the buttons from the hWnd of the MessageBox.
Then you can use GetWindowInfo to compare the style to see if it is a static. (Personally i don't know any styles unique to STATIC class)
Then once you have the hWnd, you can use GetWindowText to get the text.

mariø

Quote from: Infro_X on March 07, 2005, 05:31:34 PM
No, you can use EnumChildWindows to enumerate the static box, as well as the buttons from the hWnd of the MessageBox.
Then you can use GetWindowInfo to compare the style to see if it is a static. (Personally i don't know any styles unique to STATIC class)
Then once you have the hWnd, you can use GetWindowText to get the text.

Maybe you can also use GetClassName to find the "Static" classname

pbrennick

Labels are STATIC, editboxes are not.
Paul

Trope

I think this post from a VB forum is on the right track - actually, if we could convert it to ASM it would be perfect!



'put in declarations part of a form
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long


Private Sub Form_Load()
    Dim x As Long, staticx As Long, MyStr As String
    x = FindWindow("#32770", vbNullString)
    staticx = FindWindowEx(x, 0&, "static", vbNullString)
    MyStr = String(100, Chr$(0))
    GetWindowText staticx, MyStr, 100
    MyStr = Left$(MyStr, InStr(MyStr, Chr$(0)) - 1)
    MsgBox MyStr
End Sub

'--

this will msgbox you the text contained in the first message box found, to test it open up another instance of VB and in the form_load proc just put msgbox "Hey there"

then run this program, it will display a message box of the text it grabbed from the other message box.



and here is my attempt at converting it:



.code
start:
invoke FindWindow, ADDR winClassname, NULL
.IF eax==NULL
    invoke MessageBox, NULL,ADDR notfound,ADDR appName,MB_OK
.ELSE
    mov targethandle, eax
    invoke FindWindowEx, ADDR targethandle, 0, ADDR szStatic, NULL
    .IF eax!=NULL
        mov myBuffer, eax
        invoke MessageBox, NULL,ADDR buffer,ADDR appName,MB_OK
    .ENDIF
.ENDIF

@end:

; ----------------------------

invoke ExitProcess, 0


end start




again... no luck.

Any ideas where to try from here?

Peterpan

#5
Just a small mistake you have there. variable "targethandle" is the HANDLE to the dialog window, you don't have to use ADDR

invoke FindWindowEx, targethandle, 0, ADDR szStatic, NULL

Be careful if the MessageBox use an icon. It also  STATIC, so you have to loop for the STATIC class to find the LABEL, not an ICON. Also WM_CLOSE will not close MessageBox, if the MessageBox using MB_YESNO or MB_ABORTRETRYIGNORE

Edit:
Oops sorry, there is another mistake  :green It should code like this

mov hChild, FUNC( FindWindowEx, targethandle, 0, ADDR szStatic, NULL )
invoke GetWindowText, hChild, addr szBuffer, LengthOf szBuffer

Trope

COOL. Trying this now.

But can you tell me , how would I know that the class name is #32770?

Where is this stuff documented?

I used Ice's TUT #24 , his hook program, and it confirms the MessageBox indeed uses that class.

Peterpan

I don't know where is the complete doc exactly, but this one clearly stated

The window class name for dialog boxes is "#32770".

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msaa/msaapndx_49q0.asp

Trope

We are close on this one I believe.

Getting a syntax error on this line:



mov hChild, FUNC( FindWindowEx, targethandle, 0, ADDR szStatic, NULL )




here is the whole code so far:



; MessageBox Monitor
;
; --------------------------------------------------------------------

.486
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
winClassname        db "#32770", 0
wrongText           db "Application Has Finished!", 0
appName             db "Debug Message",0
appCaption          db "We found the MessageBox Text!",0
notfound            db "Cant find it",0

szStatic            db "static",0

; A buffer
szBuffer            db 128 dup(0)

.data?
; Special handles
targethandle        dd ?     ; handle to the MESSAGEBOX
hChild              dd ?     ; handle to the STATIC

.code
start:
invoke FindWindow, ADDR winClassname, NULL
.IF eax==NULL
    invoke MessageBox, NULL,ADDR notfound,ADDR appName,MB_OK
.ELSE
    mov targethandle, eax
    mov hChild, FUNC( FindWindowEx, targethandle, 0, ADDR szStatic, NULL )
    invoke GetWindowText, hChild, addr szBuffer, LengthOf szBuffer
    .IF eax!=NULL
        invoke MessageBox, NULL,ADDR szBuffer,ADDR appName,MB_OK
    .ENDIF
.ENDIF

@end:

; ----------------------------

invoke ExitProcess, 0


end start



As a new user to MASM, that syntax is not familiar to me ( yet ).

Any ideas where the syntax is wrong?

Peterpan

Sorry about that. I didn't see your complete code earlier. You must include the macro file

   include \masm32\macros\macros.asm

Or if you don't want to use macro, you can change it to this

   invoke FindWindowEx, targethandle, 0, ADDR szStatic, NULL
   mov hChild, eax


Trope

 :clap:

Works like a charm!!!!!!!!!!! )ignore my PM, plz.


Thank you for you help. As a newbie, I really appreciate this.

Peterpan

Okay, that is fine, I will ignore it  :toothy
You are welcome  :U