设置消息断点 : WM_LBUTTONDOWN
X64
$$ /// @file d:\windbg-script.txt
$$ Windbg脚本
$$ 试验目的: 用WinDbg设置一个断点, 在断点条件发生时, 执行一个WinDbg脚本
$$ e.g. bp USER32!TranslateMessage "$$>< d:\windbg-script.txt"
$$ 试验环境: win7X64Sp1 + WinDbg 6.12.0002.633
$$ 试验步骤:
$$ * bc *
$$ * bp USER32!TranslateMessage "$$>< d:\windbg-script.txt"
$$ * 当断点触发后, 自动调用 d:\windbg-script.txt
$$ 只有符合脚本中约定的条件时,才会停下. 否则自动继续执行
$$ e.g. 例如只有 WM_LBUTTONDOWN 发生时, WinDbg才会停下来
$$ @note
$$ 当断点触发后, 进入USER32!TranslateMessage,
$$ 参考此API的反汇编, 可以看到 MSG * 入参在rcx中
$$ 0:000> uf USER32!TranslateMessage
$$ USER32!TranslateMessage:
$$ 00000000`775996f0 fff3 push rbx
$$ 00000000`775996f2 4883ec20 sub rsp,20h
$$ 00000000`775996f6 b8e5000000 mov eax,0E5h
$$ 00000000`775996fb 488bd9 mov rbx,rcx
$$ 00000000`775996fe 66394110 cmp word ptr [rcx+10h],ax
$$ 00000000`77599702 0f84ede20100 je USER32!TranslateMessage+0x14 (00000000`775b79f5)
$$ USER32!TranslateMessage+0x2c:
$$ 00000000`77599708 33d2 xor edx,edx
$$ 00000000`7759970a 488bcb mov rcx,rbx
$$ 00000000`7759970d e81e020000 call USER32!TranslateMessageEx (00000000`77599930)
$$ ...
$$ 通过观察MSG结构内容, 可以看到 MSG + 8 = message
$$ dt MSG @rcx -r3 -v
$$ ole32!MSG
$$ struct tagMSG, 6 elements, 0x30 bytes
$$ +0x000 hwnd : 0x00000000`0031040c struct HWND__, 1 elements, 0x4 bytes
$$ +0x000 unused : ??
$$ +0x008 message : 0xf
$$ +0x010 wParam : 0
$$ +0x018 lParam : 0n0
$$ +0x020 time : 0xdfd2cd
$$ +0x024 pt : struct tagPOINT, 2 elements, 0x8 bytes
$$ +0x000 x : 0n792
$$ +0x004 y : 0n1042
$$ 经过试验, 注释要放脚本上面. 如果放在脚本体外面, 会有函数执行失败的提示.
$$ /// run results
$$ MSG.message = 0000000000000201
$$ hold WM_LBUTTONDOWN
$$ MK_LBUTTON pressdown
$$ USER32!TranslateMessage:
$$ 00000000`775996f0 fff3 push rbx
$$ 00000000`775996f2 4883ec20 sub rsp,20h
$$ 00000000`775996f6 b8e5000000 mov eax,0E5h
$$ 00000000`775996fb 488bd9 mov rbx,rcx
$$ 00000000`775996fe 66394110 cmp word ptr [rcx+10h],ax
$$ 00000000`77599702 0f84ede20100 je USER32!TranslateMessage+0x14 (00000000`775b79f5)
$$ USER32!TranslateMessage+0x2c:
$$ 00000000`77599708 33d2 xor edx,edx
$$ 00000000`7759970a 488bcb mov rcx,rbx
$$ 00000000`7759970d e81e020000 call USER32!TranslateMessageEx (00000000`77599930)
$$ USER32!TranslateMessage+0x36:
$$ 00000000`77599712 4883c420 add rsp,20h
$$ 00000000`77599716 5b pop rbx
$$ 00000000`77599717 c3 ret
$$ USER32!TranslateMessage+0x14:
$$ 00000000`775b79f5 4c8b4918 mov r9,qword ptr [rcx+18h]
$$ 00000000`775b79f9 4c8b4110 mov r8,qword ptr [rcx+10h]
$$ 00000000`775b79fd 8b5108 mov edx,dword ptr [rcx+8]
$$ 00000000`775b7a00 488b09 mov rcx,qword ptr [rcx]
$$ 00000000`775b7a03 ff1587ab0500 call qword ptr [USER32!gImmApiEntries+0x160 (00000000`77612590)]
$$ 00000000`775b7a09 85c0 test eax,eax
$$ 00000000`775b7a0b 0f84f71cfeff je USER32!TranslateMessage+0x2c (00000000`77599708)
$$ USER32!TranslateMessage+0x30:
$$ 00000000`775b7a11 e9fc1cfeff jmp USER32!TranslateMessage+0x36 (00000000`77599712)
$$ rax=0000000000000000 rbx=0000000000000000 rcx=000000000028d300
$$ rdx=000000003a94041d rsi=000000000cd60503 rdi=00000000ffe33460
$$ rip=00000000775996f0 rsp=000000000028d1f8 rbp=00000000ffe33460
$$ r8=000000000028d300 r9=00000000ffe33460 r10=0000000000000000
$$ r11=0000000000000246 r12=0000000000000000 r13=0000000000000000
$$ r14=0000000000000001 r15=0000000000000002
$$ iopl=0 nv up ei pl zr na po nc
$$ cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
$$ USER32!TranslateMessage:
$$ 00000000`775996f0 fff3 push rbx
$$ ole32!MSG
$$ struct tagMSG, 6 elements, 0x30 bytes
$$ +0x000 hwnd : 0x00000000`000602e4 struct HWND__, 1 elements, 0x4 bytes
$$ +0x000 unused : 0n67108868
$$ +0x008 message : 0x201
$$ +0x010 wParam : 1
$$ +0x018 lParam : 0n720923
$$ +0x020 time : 0x1fdfc81
$$ +0x024 pt : struct tagPOINT, 2 elements, 0x8 bytes
$$ +0x000 x : 0n1032
$$ +0x004 y : 0n412
$$ USER32!TranslateMessage:
$$ 00000000`775996f0 fff3 push rbx
$$ get message on $t0
r $t0 = poi(@rcx + 0x08)
.echo ">> windbg-script.txt"
$$ get wParam on $t1
r $t1 = poi(@rcx + 0x10)
$$ /// #define WM_LBUTTONDOWN 0x0201
.if ($t0 == 0x0201)
{
.printf "MSG.message = %N\r\n", @$t0
.echo "hold WM_LBUTTONDOWN"
$$ /// #define MK_LBUTTON 0x0001
$$ get MK_LBUTTON on $t2
r $t2 = ($t1 & 0x0001)
.if ($t2 == 1)
{
$$ 鼠标左右键没有交换的情况下, 鼠标左键按下
.printf "MK_LBUTTON pressdown\r\n"
.echo ""
$$ 反汇编API
uf USER32!TranslateMessage
.echo ""
$$ 显示寄存器组
r
.echo ""
$$ 显示MSG * 入参细节
dt MSG @rcx -r3 -v
$$ WinDbg 停住了, 单步调试
$$ 用WinDbg下消息断点,运行的非常慢, 如果找到了需要的消息断点, 应该bc x, 清除消息断点.
}
}
.else
{
$$ 如果不是要捕获的消息, 从条件断点开始执行
gc
}
$$ /// @file