整理OD学习之深入理解消息循环

68 篇文章 2 订阅
63 篇文章 4 订阅

原文转自:逆向工程-------OD学习之深入理解消息循环  本文略加整理。以下是原文部分:"

今天我们一起深入探讨下带有对话框的消息循环。先看下图:今天我们就来研究这个图!!


为了方便研究,我就选用看雪实例里的一个程序。从图上你可以看出一个主窗口,还有一个消息框。为了程序界面的简单,还请暂时把你看到的这个消息框当成对话框。这样一来你所看到的2个元素分别就是:主窗口和一个对话框。
现在我们就来模拟下你按下“OK”按钮后,系统到底做了些什么操作。
当你按下此按钮,系统就是构建一个消息结构
MSG {“按钮句柄”,“WM_LBUTTONDBLCLK”,参数1,参数2,“此时鼠标在屏幕中的坐标”}
之后把这个消息结构放到系统消息列队。之后系统会看情况把这个消息放入主窗口的线程消息队列中。
这个时候我们的主窗口消息循环中的GetMessage函数就会去自己的线程消息队列里取消息,如果没有取到,那么这个函数是不会返回的,原线程挂起同时发起线程的切换。(在此感谢刘飞同学的补充理解),如果取得消息的话,那么DispatchMessage函数就会分析这个MSG结构从而获得这个“按钮的句柄”,那么DispatchMessage就会调用这个按钮的回调函数(按钮回调函数包含在USER32.dll中)。按钮的回调函数会重新构建这个MSG,使其变成:
 MSG{“按钮父亲窗口的句柄(TrackMe对话框的句柄)”,WM_COMMAND,“OK按钮的资源号”,0}
并且把重新构建好的MSG结构再次放入主窗口消息队列中。这个时候GetMessage函数继续取消息,而这个时候的消息里的内容已经有所变化,DispatchMessage函数分析新来的MSG结构获得的句柄已经是对话框窗口的句柄,这个时候DispatchMessage函数就会去调用对话框的消息回调函数,令人兴奋的是,对话框的消息回调函数是程序员自定义的。这样一来,按钮的点击就和过程函数扯上了关系。
当然啦,上面说的还是比较的肤浅,其实里面还涉及到更多的消息的转换,我就不介绍了,有兴趣的读者用OD跟下就会发现其细节。

"

    上面的转载中,我标红了两处比较重要的信息:控件的消息,和转发到父窗口的WM_COMMAND消息。下面,我以windbg调试calc.exe为例,演示作者的意图。

    以Button 0为例,它的句柄值为0206006


Button 0的控件ID:0x0082


Button 0的父窗口信息:


    它的父窗口看着像是一个组合框,它的句柄值为06057E,和SPY++获得的结果一致。


    要验证原作者的结论是否正确,只需下在user32!InternalCallWindProc函数(前面的文章说过这是个万能消息断点)处对WM_LBUTTON和WM_COMMAND消息下条件断点:

0:004> bp USER32!InternalCallWinProc ".if((dwo(esp+8)==00020606&dwo(esp+c)==201)|(dwo(esp+8)==0006057E&dwo(esp+c)==111)){.echo LB;}.else{gc;}"
运行windbg并在Button 0上按键,windbg马上会中断在Button 0的user32!InternalCallWindProc函数处,此时打印调用堆栈:

0:004> g
LB
esp=0016ee14
USER32!InternalCallWinProc:
7596c494 55              push    ebp
0:000> kb
ChildEBP RetAddr  Args to Child              
0016ee10 7596c5b7 7455b4a9 00020606 00000201 USER32!InternalCallWinProc @注释 参数2:00020606是spy++给出的Button 0的句柄值,参数3:0x201是鼠标左键按下的消息
0016ee88 7596cbe9 00000000 7455b4a9 00020606 USER32!UserCallWinProcCheckWow+0x14b
0016eee8 7596cc40 7455b4a9 00000000 0016fc68 USER32!DispatchMessageWorker+0x357
再次运行windbg,它会再次中断在组合框的user32!InternalCallWindProc函数处,此时打印调用堆栈:

0:000> g
LB
esp=0016ebc4 
USER32!InternalCallWinProc:
7596c494 55              push    ebp
0:000> kb
ChildEBP RetAddr  Args to Child              
0016ebc0 7596c5b7 75985b91 0006057e 00000111 USER32!InternalCallWinProc @注释 参数2:0006057e是spy++给出Button 0的父窗口的句柄,参数3:111是WM_COMMAND消息
0016ec38 75964ede 00000000 75985b91 0006057e USER32!UserCallWinProcCheckWow+0x14b
0016ec94 75964f4d 00787e10 00000111 00000082 USER32!DispatchClientMessage+0xcf
...
综上所述,恰如原作者所述:控件上的消息会被转换成父窗口的WM_COMMAND消息。




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值