1.拦截窗口消息
以系统自带的计算器为例,用本地进程调试拦截"Clear按钮(C)"的鼠标左键单击消息,假设用spy++获得该按钮控件的参数:
Class Name: Button
Windows Caption: C
Windows Handle: 001601F6
Windows Proc: 771A8EB4
说明:WM_LBUTTONDOWN=0x00000201。其他如WM_LBUTTONUP=0x00000202,WM_RBUTTONDOWN=204,WM_RBUTTONUP=0x00000205。
0:002> bp 771A8EB4 ".if ((poi(@esp+4)=0x001601F6)&(poi(@esp+8)=0x00000201)) {} .else {gc} " //设置断点
0:002> g //运行并测试,下面是断点命中后的输出信息:
eax=7ffdf000 ebx=00000000 ecx=40000000 edx=00000040 esi=771a8eb4 edi=0007fd6c
eip=771a8eb4 esp=0007fd08 ebp=0007fd30 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
comctl32!Ordinal384+0xd004:
771a8eb4 8bff mov edi,edi
2.拦截所有程序对MessageBox的调用:
说明:用双机内核调试进行实现:
kd> !process 0 0 //进程列表
**** NT ACTIVE PROCESS DUMP ****
PROCESS 82196660 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000
DirBase: 003a4000 ObjectTable: e1001c70 HandleCount: 484.
Image: System
......
PROCESS 81fba408 SessionId: 0 Cid: 047c Peb: 7ffd5000 ParentCid: 0474
DirBase: 072f0280 ObjectTable: e194eb90 HandleCount: 515.
Image: EXPLORER.EXE
......
kd> .PROCESS 81fba408 //切换进程上下文
Implicit process is now 81fba408
WARNING: .cache forcedecodeuser is not enabled
kd> .reload /user //加载用户模块
Loading User Symbols
........................................................................................................
kd> bp user32!MessageBoxA //设置断点
kd> g //运行并测试,只要有应用程序调用MessageBox都会命中断点。
Breakpoint 0 hit
USER32!MessageBoxA:
001b:77d507ea 8bff mov edi,edi
关于内核调试加载用户态模块的方法还用一种比较简单的,就是通过对SSDT系统服务设置断点来达到目的,当SSDT系统服务断点命中后,你就可以加载用户态模块了,本人推荐将断点设在nt!NtCreateProcessEx这个函数(XP和2003可以),这样你只要在客户机(被调试机器)运行一个程序,就会命中断点,非常方便。
[课程]Linux pwn 探索篇!