experiment 用OD下消息断点, 捕获按钮操作.实验目的: 想直接拦截按钮操作的消息处理, 分析按钮操作的逻辑.实验程序: <<使用OllyDbg从零开始Cracking 第一章翻译>> 中附带的一个CrackMe.使用OD加载目标程序, 当程序运行起来后, 暂停OD经过实验, 点击菜单会触发主窗体WM_COMMAND消息. 如果直接捕获弹出的注册窗口的WM_COMMAND, 捕获不到.准备捕获主窗体的WM_COMMAND消息, 找到菜单生成注册窗体的处理.找到注册窗体的创建函数传入的注册窗口处理过程,从而找到注册窗体的所有消息处理实现逻辑.点击菜单属于WM_COMMAND, 按照消息名称排序, 好找一些.下完消息断电后, 确认一下是否消息断点已下.F9, 让程序跑起来. 点击注册菜单. 程序被断在WM_COMMAND消息断点处.[cpp] view plaincopy00401128 > $ C8 000000 ENTER 0,0 ; 主窗体消息断点WM_COMMAND 0040112C . 56 PUSH ESI 0040112D . 57 PUSH EDI 0040112E . 53 PUSH EBX0040112F . 837D 0C 02 CMP DWORD PTRSS:[EBP+C],2 00401133 . 74 5E JE SHORT CRACKME.00401193 00401135 . 817D 0C 040200>CMP DWORD PTR SS:[EBP+C],204 0040113C . 74 65 JE SHORT CRACKME.004011A3F8往下走,找到创建注册窗体的代码.[cpp] view plaincopy00401209 > 6A 00PUSH 0 ; /lParam = NULL 0040120B . 68 53124000 PUSH CRACKME.00401253 ; |DlgProc = CRACKME.00401253 00401210 . FF75 08PUSH DWORD PTR SS:[EBP+8] ;|hOwner 00401213 . 68 15214000 PUSH CRACKME.00402115 ; |pTemplate = "DLG_REGIS" 00401218 . FF35 CA204000 PUSH DWORD PTR DS:[4020CA] ; |hInst = 00400000 0040121E . E8 7D020000 CALL<JMP.&USER32.DialogBoxParamA> ;\DialogBoxParamA CRACKME.00401253 是注册窗体的消息处理过程. 转到那看看.[cpp] view plaincopy00401253/. C8 000000 ENTER0,0 ; 注册窗体消息处理过程00401257 |. 53 PUSH EBX 00401258 |. 56 PUSH ESI 00401259 |.57 PUSH EDI 0040125A |. 817D 0C 100100>CMP DWORD PTRSS:[EBP+C],110 ; WM_INITDIALOG 00401261 |. 74 34 JE SHORTCRACKME.00401297 00401263 |. 817D 0C110100>CMP DWORD PTRSS:[EBP+C],111 ; WM_COMMAND 0040126A |. 74 35 JE SHORT CRACKME.004012A1 0040126C |. 837D 0C 10CMP DWORD PTR SS:[EBP+C],10 ;WM_CLOSE 00401270 |. 0F84 81000000 JE CRACKME.004012F7 00401276 |. 817D 0C010200>CMP DWORD PTRSS:[EBP+C],201 ; WM_LBUTTONDOWN 0040127D |. 74 0C JE SHORT CRACKME.0040128B 0040127F |. B8 00000000 MOV EAX,0 00401284 |> 5F POP EDI 00401285 |. 5E POP ESI 00401286 |.5B POP EBX 00401287 |. C9LEAVE 00401288 |. C2 1000 RETN 10可以看到CRACKME.004012A1 是注册窗体WM_COMMAND命令处理函数.注册窗体一共处理了4种消息(窗体初始化, 退出, 确定, 命令处理)在地址0040126A 上回车, 去看看按钮处理逻辑. [cpp] view plaincopy004012A1 |> 33C0/XOR EAX,EAX ; 注册窗体: 按钮处理逻辑004012A3 |. 817D 10EB0300>|CMP DWORD PTR SS:[EBP+10],3EB 004012AA |. 74 4B |JE SHORT CRACKME.004012F7 004012AC |. 817D 10EA0300>|CMP DWORD PTR SS:[EBP+10],3EA 004012B3 |. 75 3B |JNZ SHORT CRACKME.004012F0 004012B5 |. 6A 0B|PUSH 0B ; /Count = B (11.) 004012B7 |. 68 8E214000 |PUSH CRACKME.0040218E ; |Buffer = CRACKME.0040218E 004012BC |. 68 E8030000|PUSH 3E8 ;|ControlID = 3E8 (1000.) 004012C1 |. FF75 08|PUSH DWORD PTR SS:[EBP+8] ; |hWnd 004012C4 |. E8 07020000 |CALL<JMP.&USER32.GetDlgItemTextA> ;\GetDlgItemTextA 004012C9 |. 83F8 01 |CMP EAX,1 004012CC |. C745 10 EB0300>|MOV DWORD PTR SS:[EBP+10],3EB 004012D3 |.^72 CC \JB SHORT CRACKME.004012A1 004012D5 |. 6A 0B PUSH 0B ; /Count = B (11.) 004012D7 |. 68 7E214000 PUSH CRACKME.0040217E ; |Buffer = CRACKME.0040217E 004012DC |. 68 E9030000 PUSH 3E9 ;|ControlID = 3E9 (1001.) 004012E1 |. FF75 08PUSH DWORD PTR SS:[EBP+8] ;|hWnd 004012E4 |. E8 E7010000 CALL<JMP.&USER32.GetDlgItemTextA> ;\GetDlgItemTextA 004012E9 |. B8 01000000 MOV EAX,1 004012EE |. EB 07 JMP SHORT CRACKME.004012F7 004012F0 |> B8 00000000 MOV EAX,0 004012F5 |.^EB 8D JMP SHORT CRACKME.00401284 004012F7 |> 50 PUSH EAX ; /Result004012F8 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd 004012FB |. E8 B2010000 CALL<JMP.&USER32.EndDialog> ;\EndDialog 00401300 |. B8 01000000 MOV EAX,1 00401305 \.^E9 7AFFFFFF JMPCRACKME.00401284 如果F2 在地址004012A1 上下普通代码断点, 已经断住了注册窗体的WM_COMMAND逻辑为了只断住按钮(OK, Quit)的处理, 将断点下在004012B5 F9, 让程序跑起来. 填入Name, SN, 按下确定按钮可以看出, 注册窗口消息处理只是得到用户输入[cpp] view plaincopy004012A1 |> 33C0/XOR EAX,EAX ; 注册窗体: 按钮处理逻辑004012A3 |. 817D 10EB0300>|CMP DWORD PTR SS:[EBP+10],3EB 004012AA |. 74 4B |JE SHORT CRACKME.004012F7 004012AC |. 817D 10EA0300>|CMP DWORD PTR SS:[EBP+10],3EA 004012B3 |. 75 3B |JNZ SHORT CRACKME.004012F0 004012B5 |. 6A 0B|PUSH 0B ; /Count =B (11.) 004012B7 |. 68 8E214000 |PUSH CRACKME.0040218E ; |name 004012BC |. 68 E8030000 |PUSH3E8 ; |ControlID = 3E8 (1000.) 004012C1 |. FF75 08 |PUSH DWORD PTR SS:[EBP+8] ; |hWnd 004012C4 |. E8 07020000 |CALL<JMP.&USER32.GetDlgItemTextA> ;\GetDlgItemTextA 004012C9 |. 83F8 01 |CMP EAX,1 004012CC |. C745 10 EB0300>|MOV DWORD PTR SS:[EBP+10],3EB 004012D3 |.^72 CC \JB SHORT CRACKME.004012A1 004012D5 |. 6A 0B PUSH 0B ; /Count = B (11.) 004012D7 |. 68 7E214000 PUSH CRACKME.0040217E ; |pwd 004012DC |. 68 E9030000 PUSH3E9 ; |ControlID =3E9 (1001.) 004012E1 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd 004012E4 |. E8 E7010000 CALL<JMP.&USER32.GetDlgItemTextA> ;\GetDlgItemTextA 004012E9 |. B8 01000000 MOVEAX,1 004012EE |. EB 07 JMP SHORT CRACKME.004012F7 004012F0 |> B8 00000000 MOV EAX,0 004012F5 |.^EB 8D JMP SHORT CRACKME.00401284 004012F7 |> 50 PUSH EAX ; /Result 004012F8 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd 004012FB |. E8 B2010000 CALL<JMP.&USER32.EndDialog> ;\EndDialog 00401300 |. B8 01000000 MOV EAX,1 00401305 \.^E9 7AFFFFFF JMPCRACKME.00401284 从00401305继续往下走, 进行数据有效性的校验.总结:通过消息断点, 可以从父窗口WMCOMMAND操作(菜单点击, 按钮点击)得到子窗体的消息处理过程.。