View Full Version : finding the msg loop
4oh4
July 13th, 2001, 16:20
I could use some generic help finding the message loop on a msvc/mfc app. I've tried bmsg [hwnd] wm_command, but sice breaks on "mov edx, 00000111". Tracing downwards, the "jz xxxxxxxx" is never taken for some reason. How can I break on wm_command and f10'ing through sice will take me to the wm_initdialog section?
I've even gone through a deadlisting, searching for ever occurance of "00000111". I've breaked on every "cmp" and every "mov reg, 111" followed by a "cmp".
This is starting to get annoying.
Any ideas?
4oh4
July 14th, 2001, 13:57
First off, the last sentence in the previous post should read "I've tried to break on every...." I found one location which breaks every time I click on one menu only. I'm guessing that that specific menu is subclassed, which seems strange. But I did manage to break on another code location every time I accessed a menu (except for the one I added in for some reason).
I'm stuck with how do I compare wParam with the resource id of the menu item that I added? When I break in softice on 'bmsg [hwnd] wm_command', when I click on one of my added menu items, sice shows what the wparam is but when I check all the registers.....none of them contain the wparam (my menu item's resource id). This is really annoying.
Does anyone have any suggestions at all?
I was thinking that if I could find a basic generic vc++ w/ mfc app (and source), it could help me learn to debug vc++ apps. Maybe throw in a int3 right after the '.if wParam == wm_command' (or however that would look in vc++).
4oh4
July 14th, 2001, 15:19
nm
I found a couple of interesting looking essays on this type of thing. Hopefully, they'll answer my questions.
Kayaker
July 14th, 2001, 17:11
Hi 4oh4,
It sounds like you're not breaking early enough in the proc that handles messages. Rather than searching for a likely bp in the disassembly, why not trace there directly from the bmsg <hwnd> wm_command break so you don't miss anything.
There's a couple of ways you can do this quickly. I'll just paste a quick example from choosing File/Open from notepad. Say you have this:
Break due to BMSG 0904 WM_COMMAND (ET=2.51 seconds)
hWnd=0904 wParam=000A lParam=00000000 msg=0111 WM_COMMAND
In most cases you'll break in KernelAlloc at
141F:0AE0 6668741C4000 PUSH 00401C74
141F:0AE6 666800000300 PUSH 00030000
KERNEL.Alloc
Notice the first push statement. This is the address of the start of WndProc, or wherever the message loop is. You can set a bp directly on this with:
:bpx 167:401c74
(167 is my cs: register in regular program code, change it to whatever yours is)
Press F5 and you should be there and can start tracing, watching for msg=111 and wParam. Remember that the ControlID wParam is in hex, but some resource editors like Exescope will show them in decimal. WDasm shows them properly in hex.
The other option is as soon as you break on bmsg <hwnd> wm_command is set a:
:bpx k32thk1632prolog
F11 and you'll be here
0167:BFF943FD E8E3D3FDFF CALL KERNEL32!K32Thk1632Prolog
0167:BFF94402 E8F6F1FDFF CALL BFF735FD
0167:BFF94407 E8FED3FDFF CALL KERNEL32!K32Thk1632Epilog
This is the Windows routine for setting up the stack frame. Step *into* the middle call CALL BFF735FD and you'll be here
0167:BFF735FD 55 PUSH EBP
0167:BFF735FE 8BEC MOV EBP,ESP
.
.
0167:BFF7361F 65D16E04 SHR DWORD PTR GS:[ESI+04],1
0167:BFF73623 7222 JB BFF73647
0167:BFF73625 65FF32 PUSH DWORD PTR GS:[EDX]
0167:BFF73628 8D5204 LEA EDX,[EDX+04]
0167:BFF7362B E2F2 LOOP BFF7361F
0167:BFF7362D 8BFC MOV EDI,ESP
0167:BFF7362F 33C0 XOR EAX,EAX
0167:BFF73631 65394608 CMP GS:[ESI+08],EAX
0167:BFF73635 7404 JZ BFF7363B
0167:BFF73637 65FF5608 CALL GS:[ESI+08] ; 401C74
0167:BFF7363B 8BE7 MOV ESP,EDI
Step *into* the last call CALL GS:[ESI+08] and it will again be the start of the messaging loop in program code at address 401C74. You'll see the wm_command params being processed in the LOOP.
If you display the stack as soon as you get into program code with 'dd esp' at
0167:00401C74 55 PUSH EBP
0167:00401C75 8BEC MOV EBP,ESP
you'll see the return address from the call, hWnd, uMsg, wParam and lParam
016F:0063FC70 BFF7363B 00000904 00000111 0000000A
016F:0063FC80 00000000
Your ControlID may be being referenced to the frame pointer EBP, so this is why you don't see it in a disassembly. For notepad the local variables are referenced at
[EBP+4] = Return address of Call = BFF7363B
[EBP+8] = hWnd = 904
[EBP+C] = Msg = 111
[EBP+10] = wParam = 0A
[EBP+14] = lParam = 0
Hope this helps
Kayaker
4oh4
July 22nd, 2001, 20:52
Thanks again kayaker.
After you sent that I stumbled upon your essay that covered this same topic (rce cd maybe?). It just goes to show that 'zen cracking' thing about the more you try to find something your search fails. Then when your mind is blank and you're just looking around you find exactly what you've been looking for.
Anyways, this is where I am right now. Softice isn't loaded (mostly because of a huge hangover), but I've been thinking about this project. I've added a jump to my cave in the wm_command part of the msgloop, where I've added a messagebox. This messagebox gets triggered correctly. Then I added a "cmp d,[ebp+10],menuid" in hiew which gets translated to "cmp [ebp][10], menuid" (I can't remember the menuid at the moment). That didn't work at all. It's obviously not the correct hiew asm syntax. I basically left off with that and didn't try anything else, and am too bothered with this hangover to work on this tonight. Please forgive my laziness, but what is the correct 'hiew syntax' for typing that cmp instruction?
Kayaker
July 23rd, 2001, 11:33
Hi 4oh4,
I think you've got the syntax right, in hiew you'd enter
cmp dword ptr [ebp+10], BB9
where BB9 is the Control ID (3001 in decimal), as:
cmp d,[ebp+10],0BB9
Notice the 0 required before *any* value or address in hiew that doesn't begin with a number. i.e. the address A00000 needs to be entered as 0A00000.
Hiew is great, but not intuitive in its usage. Dunno if this was the cause of your problem, or just your hangover
Kayaker
4oh4
July 23rd, 2001, 13:54
Actually, I just looked at it again this morning. I didn't have much time, but the hiew syntax was correct as you said. Believe it or not I had followed the cmp instruction with a jmp instead of a jne/jnz. I quickly changed that jmp into a conditional jmp and my little test messagebox didn't get triggered. I'm not sure exactly why yet, but I'll tackle it again after work. Hopefully it's just a silly mistake on my part that I'll be able to easily spot.
Thanks for the advice Kayaker.
Powered by vBulletin® Version 4.2.2 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.