首页 > 其他分享 >整理OD学习之深入理解消息循环

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

时间:2022-11-07 20:31:28浏览次数:35  
标签:函数 对话框 句柄 OD 循环 USER32 消息 按钮 深入


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


整理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

整理OD学习之深入理解消息循环_调试_02

Button 0的控件ID:0x0082

整理OD学习之深入理解消息循环_父窗口_03

Button 0的父窗口信息:

整理OD学习之深入理解消息循环_父窗口_04

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

整理OD学习之深入理解消息循环_父窗口_05

    要验证原作者的结论是否正确,只需下在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消息。






标签:函数,对话框,句柄,OD,循环,USER32,消息,按钮,深入
From: https://blog.51cto.com/u_13927568/5831355

相关文章

  • Node
    一、Node开发概述(一)为什么要学习服务器端开发基础1、能够和后端程序员更加紧密的配合2、网站业务逻辑前置,学习前端技术需要后端技术支持(Ajax)3、拓宽知识视野,能够站在更......
  • git submodule add 报错SSL certificate problem unable to get local issuer certifi
    在使用hugo并安装主题时遇到的错误SSLcertificateproblem:unabletogetlocalissuercertificate(base)PSE:\vscodeProject\chz8bit.github.io\quickstart>gitsu......
  • leetcode-2363-easy
    MergeSimilarItemsYouaregiventwo2Dintegerarrays,items1anditems2,representingtwosetsofitems.Eacharrayitemshasthefollowingproperties:ite......
  • leetcode-1287-easy
    ElementAppearingMoreThan25%InSortedArrayGivenanintegerarraysortedinnon-decreasingorder,thereisexactlyoneintegerinthearraythatoccursmo......
  • Springboot中使用GSON报错 An attempt was made to call the method com.google.gso
    错误如下: Description:Anattemptwasmadetocallthemethodcom.google.gson.GsonBuilder.setLenient()Lcom/google/gson/GsonBuilder;butitdoesnotexist.Itscl......
  • LeetCode125. 验证回文串
    验证回文串Day:2022-11-7link:https://leetcode.cn/problems/valid-palindromequestion:如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正......
  • xss反射型深入分析
    有任何问题都可以留言咨询。 定义再理解什么是xss反射型漏洞?这里有个核心思想,指的是用户输入了什么,那响应的内容肯定会包括什么。比如用户输入了"testxss",那响应的内......
  • 浏览器事件循环
    执行js代码的时候,遇见同步任务,直接推入调用栈中执行,遇到异步任务,将该任务挂起,等到异步任务有返回之后推入到任务队列中,当调用栈中的所有同步任务全部执行完成,将任务队列中......
  • 【HDLBits刷题笔记】15 Finding bugs in code
    Bugsmux2原本代码的逻辑是反的,这不是坑人吗。moduletop_module(inputsel,input[7:0]a,input[7:0]b,output[7:0]out);assignout......
  • LeetCode40. 组合总和 II
    题意给一个数组和target,找出数组中所有和为target的组合方法DFS代码classSolution{private:vector<vector<int>>res;vector<int>tmp;public:......