首页
社区
课程
招聘
[求助]DispatchMessageA如何分发消息?
2008-7-30 09:59 11045

[求助]DispatchMessageA如何分发消息?

2008-7-30 09:59
11045
0012FE6C   00401586  /CALL 到 DispatchMessageA 来自 abcde.00401584
0012FE70   0012FE80  \pMsg = MSG(C089) wParam = 1 lParam = 0
0012FE74   7C80B6A1  kernel32.GetModuleHandleA
0012FE78   7FFD5000
0012FE7C   00000000
0012FE80   00000000  ;hwnd表示消息所属的窗口
0012FE84   0000C089  ;消息的标识符
0012FE88   00000001  ;wParam,用于指定消息的附加信息
0012FE8C   00000000  ;lParam,用于指定消息的附加信息
0012FE90   001A5257  ;消息投递到消息队列中的时间
0012FE94   00000187  ;鼠标的位置
0012FE98   00000226  ;鼠标的位置

上面是DispatchMessageA函数入口点的堆栈情况,各参数已经注明了。
我想问的是,DispatchMessageA 怎么知道把这条消息配发到哪个窗口?换句话说,如何找到该消息的MainProc()?

我已经琢磨好久了,搞不定啊!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞0
打赏
分享
最新回复 (7)
雪    币: 383
活跃值: (115)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hldgaofeng 2008-7-30 10:17
2
0
调用GetWindowLong来得到WNDPROC,然后直接调用。
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qy黄文超 2008-7-31 14:03
3
0
可能是根据GETMESSAGE传过来的句柄
雪    币: 230
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
烟灰缸 2008-7-31 17:33
4
0
感谢2、3楼朋友的答复。
getmessage获得消息后,结构如下:
0012FE80   000301B8  ;这是产生消息的窗口的句柄
0012FE84   00000202  ;消息的标识符(鼠标左键弹起)
......
这个消息再经过TranslateMessage转换,就成了第一帖里的结构,然后再由DispatchMessage分发。

DispatchMessage里跟踪了半天,我也没找到GetWindowLong,还是没搞懂怎么分发的。
我把DispatchMessage里面的代码贴出来,请指点一下。
77D196B8 >  8BFF            mov     edi, edi  ;DispatchMessage的入口
77D196BA    55                 push    ebp
77D196BB    8BEC            mov     ebp, esp  
77D196BD    6A 01           push    1  
77D196BF    FF75 08       push    dword ptr ss:[ebp+8]  ;消息句柄入栈,即0012FE80
77D196C2    E8 2AF2FFFF     call    USER32.77D188F1
*************call的代码*************
  77D188F1    6A 1C           push    1C
  77D188F3    68 F089D177     push    USER32.77D189F0
  77D188F8    E8 C3FCFFFF     call    USER32.77D185C0
    (感觉这个call是构建一个SEH,不知道对不对?)
------------------call 77D185C0的代码--------------------
      77D185C0    68 6704D477     push    USER32.77D40467
      77D185C5    64:A1 00000000  mov     eax, dword ptr fs:[0]  ;fs:[00000000]=[7FFDF000]=0012FFB0   
      77D185CB    50              push    eax  
      77D185CC    8B4424 10       mov     eax, dword ptr ss:[esp+10]  ;1C送入eax,是即将要开辟的堆栈空间的大小
    77D185D0    896C24 10     mov    dword ptr ss:[esp+10], ebp  ;ebp=0012FE68
      77D185D4    8D6C24 10   lea  ebp, dword ptr ss:[esp+10]  ;堆栈地址=0012FE58
      77D185D8    2BE0            sub     esp, eax  
      77D185DA    53              push    ebx
      77D185DB    56              push    esi
      77D185DC    57              push    edi
      77D185DD    8B45 F8         mov     eax, dword ptr ss:[ebp-8]
      77D185E0    8965 E8         mov     dword ptr ss:[ebp-18], esp
      77D185E3    50              push    eax
      77D185E4    8B45 FC         mov     eax, dword ptr ss:[ebp-4]
      77D185E7    C745 FC FFFFFFF>mov     dword ptr ss:[ebp-4], -1
      77D185EE    8945 F8         mov     dword ptr ss:[ebp-8], eax
      77D185F1    8D45 F0         lea     eax, dword ptr ss:[ebp-10]
      77D185F4    64:A3 00000000  mov     dword ptr fs:[0], eax
      77D185FA    C3              retn
---------------------------------------------------------------------------------      
  77D188FD    33FF            xor     edi, edi
  77D188FF    897D E4         mov     dword ptr ss:[ebp-1C], edi
  77D18902    8B75 08         mov     esi, dword ptr ss:[ebp+8]
  77D18905    66:F746 06 FEFF test    word ptr ds:[esi+6], 0FFFE
  77D1890B    0F85 E17D0200   jnz     USER32.77D406F2  ;跳转未实现
  77D18911    8B0E            mov     ecx, dword ptr ds:[esi]
  77D18913    3BCF            cmp     ecx, edi
  77D18915    0F84 07030000   je      USER32.77D18C22  ;跳转实现
  77D18C22    33DB            xor     ebx, ebx
  77D18C24  ^ E9 05FDFFFF     jmp     USER32.77D1892E
  77D1892E    8B46 04         mov     eax, dword ptr ds:[esi+4]
  77D18931    3D 00040000     cmp     eax, 400
  77D18936    73 18           jnb     short USER32.77D18950  ;跳转实现
  77D18950    33C0            xor     eax, eax
  77D18952    3BC7            cmp     eax, edi
  77D18954    0F85 A47D0200   jnz     USER32.77D406FE
  77D1895A    8B56 04         mov     edx, dword ptr ds:[esi+4]
  77D1895D    81FA 13010000   cmp     edx, 113  ;将消息标识符0C089与113比较
  77D18963    0F84 F0000000   je      USER32.77D18A59  ;跳转未实现
  77D18969    81FA 18010000   cmp     edx, 118  ;将消息标识符0C089与118比较
  77D1896F    0F84 E4000000   je      USER32.77D18A59  ;跳转未实现
  77D18975    33C0            xor     eax, eax
  77D18977    3BDF            cmp     ebx, edi
  77D18979    74 6A           je      short USER32.77D189E5 ;跳转实现
  77D189E5    E8 16FCFFFF     call    USER32.77D18600
    (这个call是恢复原先的SEH结构?)
++++++++++++++++++++++++++++++++++++++++++++++++++
    77D18600    8B4D F0         mov     ecx, dword ptr ss:[ebp-10]  ;堆栈 ss:[0012FE48]=0012FFB0  (0012FE48   0012FFB0  指向下一个 SEH 记录的指针)
    77D18603    64:890D 0000000>mov     dword ptr fs:[0], ecx
    77D1860A    59              pop     ecx
    77D1860B    5F              pop     edi
    77D1860C    5E              pop     esi
    77D1860D    5B              pop     ebx
    77D1860E    C9              leave
    77D1860F    51              push    ecx
    77D18610    C3              retn
++++++++++++++++++++++++++++++++++++++++++++++++++
  77D189EA    C2 0800         retn    8
****************************************************************
77D196C7    5D              pop     ebp
77D196C8    C2 0400         retn    4
雪    币: 197
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
曾用名 2008-8-1 14:29
5
0
DispatchMessage中不能找到MainProc(),MainProc()是由系统调用的称为回调函数DispatchMessage只是将一个消息放到消息对列中
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小小愿望 2008-8-1 16:19
6
0
你都收到消息了(GetMessage),当然是本窗口的
雪    币: 383
活跃值: (115)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hldgaofeng 2008-8-1 17:20
7
0
你在你窗口的WNDPROC中下个断点,断下来之后你看下堆栈不就明白了吗?

看看这个网址:http://bbs.pediy.com/archive/index.php?t-26046.html
雪    币: 230
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
烟灰缸 2008-8-2 09:45
8
0
谢谢hldgaofeng的热心回复,我的疑问和你所给网址上的疑问是一模一样的,目的都是想知道,如何通过跟踪一个消息,找到相应的处理代码。我也相信,很多朋友也和我一样,跟到消息循环时,陷入了getmessage-->translatemessage-->dispatchmessage-->getmessage的循环出不来了。
可能是我比较笨,或基础比较差,现在只是弄明白了个大概:原来DispatchMessage调用DispatchMessageWorker,进而会调用 UserCallWinProcCheckWow,然后最终调用到InternalCallWinProc,把消息分发到窗口的WinProc(相应的处理代码)。
我再仔细研究一下代码。
再次感谢各位朋友的答复。
游客
登录 | 注册 方可回帖
返回