在 WinDbg 中设置条件内核断点会使调试对象操作系统停止运行

逆向工程 风袋 断点 内核模式
2021-06-17 21:20:16

我的设置:

  • 调试器:Win10 Pro、WinDbg Preview v.1.0.1904.18001
  • 调试对象:Win7 Pro(使用VMWare Workstation在VM中运行)

我正在尝试关注SendMessage来自用户空间呼叫:

在此处输入图片说明

进入内核,通过在 上设置条件断点win32k!NtUserMessageCall

在此处输入图片说明

如果我们采用NtUserMessageCall函数的声明

NTSTATUS NtUserMessageCall(
    HWND hWnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam,
    ULONG_PTR ResultInfo,
    DWORD dwWndProcType,
    BOOL bAnsi);

断点的条件是for uMsg == WM_SYSCOMMAND(或0x112)。我是这样设置的:

ba e 1 fffff960`00163318 "j (@rdx=0x112) ''; 'gc'"

然后我可以检查它是否设置正确:

在此处输入图片说明

但是当我“开始”操作系统时:

在此处输入图片说明

被调试的操作系统几乎完全停止。我什么也做不了。通过看到时钟小部件以 20 秒的间隔跳跃,我可以看到其中的一些“生命”,但无法与窗口交互或执行任何操作。请注意,如果我禁用上面的断点,一切都会开始顺利进行。

有人可以解释我在那里做错了什么吗?我怎样才能让它发挥作用?

1个回答

不知道如何使用 ida 来实现,因为下面显示的前端是一个纯粹的 Windbg 演示

使用名称或 Cid 查找 _EPROCESS

1: kd> !process 0 0 explorer.exe
PROCESS ffff8e0c835c9300
    SessionId: 1  Cid: 0fc8    Peb: 00583000  ParentCid: 0f8c
    DirBase: 0a600002  ObjectTable: ffffd58bc24b0d40  HandleCount: 1913.
    Image: explorer.exe

1: kd> !process 0fc8 0
Searching for Process with Cid == fc8
PROCESS ffff8e0c835c9300
    SessionId: 1  Cid: 0fc8    Peb: 00583000  ParentCid: 0f8c
    DirBase: 0a600002  ObjectTable: ffffd58bc24b0d40  HandleCount: 1913.
    Image: explorer.exe

设置无条件进程特定软件 bp

1: kd> bp /p ffff8e0c835c9300 win32kfull!NtUserMessageCall
WARNING: Software breakpoints on session addresses can cause bugchecks.
Use hardware execution breakpoints (ba e) if possible.

1: kd> g
Breakpoint 0 hit
win32kfull!NtUserMessageCall:
ffffeae2`57cdc020 48895c2408      mov     qword ptr [rsp+8],rbx

0: kd> ? @$proc
Evaluate expression: -125290582076672 = ffff8e0c`835c9300

0: kd> kb
 # RetAddr            Call Site
00 fffff803`2abdb285  win32kfull!NtUserMessageCall
01 00007ffc`bb641184  nt!KiSystemServiceCopyEnd+0x25
xxxxxxxxxxxxxxxxxxxxxxxxxx

0: kd> r rdx
rdx=0000000000000081

设置条件进程特定断点

0: kd> bp /p ffff8e0c835c9300 win32kfull!NtUserMessageCall ".if (@rdx != 0x112 ) { gc;}"

WARNING: Software breakpoints on session addresses can cause bugchecks.
Use hardware execution breakpoints (ba e) if possible.
breakpoint 0 redefined

0: kd> bl
     0 e Disable Clear  ffffeae2`57cdc020  win32kfull!NtUserMessageCall ".if (@rdx != 0x112 ) {gc;}"
     Match process data ffff8e0c`835c9300


0: kd> g

win32kfull!NtUserMessageCall:
ffffeae2`57cdc020 48895c2408      mov     qword ptr [rsp+8],rbx

1: kd> ? @$proc
Evaluate expression: -125290582076672 = ffff8e0c`835c9300

1: kd> r rdx
rdx=0000000000000112

中断调用堆栈

1: kd> kb
 # RetAddr             Call Site
00 fffff803`2abdb285   win32kfull!NtUserMessageCall
01 00007ffc`bb641184   nt!KiSystemServiceCopyEnd+0x25
02 00007ffc`bb8b9d60   win32u!NtUserMessageCall+0x14
03 00007ffc`bb8b98d2   USER32!RealDefWindowProcWorker+0x150
04 00007ffc`b8aeea12   USER32!RealDefWindowProcW+0x52
05 00007ffc`b8aeeaf2   UxTheme!DoMsgDefault+0x2e [es\uxtheme\handlers.cpp @ 550] 
06 00007ffc`b8ae8626   UxTheme!OnDwpSysCommand+0x32 [es\uxtheme\nctheme.cpp @ 7566] 
07 00007ffc`b8ae7641   UxTheme!_ThemeDefWindowProc+0x4c6 [emes\uxtheme\sethook.cpp @ 1067] 
08 00007ffc`bb8b9ad4   UxTheme!ThemeDefWindowProcW+0x11 [hemes\uxtheme\sethook.cpp @ 1109] 
09 00007ffc`a339bd0c   USER32!DefWindowProcW+0x1c4
0a 00007ffc`a33b0f2e   v_WndProc+0xac
0b 00007ffc`bb8bca66   s_WndProc+0x6e
0c 00007ffc`bb8bc78c   USER32!UserCallWinProcCheckWow+0x266
0d 00007ffc`bb8cfa83   USER32!DispatchClientMessage+0x9c
0e 00007ffc`be5322c4   USER32!_fnDWORD+0x33
0f 00007ffc`bb641184   ntdll!KiUserCallbackDispatcherContinue
10 00007ffc`bb8b9d60   win32u!NtUserMessageCall+0x14
11 00007ffc`bb8b98d2   USER32!RealDefWindowProcWorker+0x150
12 00007ffc`b8aeea12   USER32!RealDefWindowProcW+0x52
13 00007ffc`b8aeebb4   UxTheme!DoMsgDefault+0x2e [hemes\uxtheme\handlers.cpp @ 550] 
14 00007ffc`b8ae8626   UxTheme!OnDwpNcLButtonDown+0xa4 [hemes\uxtheme\nctheme.cpp @ 7157] 
15 00007ffc`b8ae7641   UxTheme!_ThemeDefWindowProc+0x4c6 [\themes\uxtheme\sethook.cpp @ 1067] 
16 00007ffc`bb8b9ad4   UxTheme!ThemeDefWindowProcW+0x11 [l\themes\uxtheme\sethook.cpp @ 1109] 
17 00007ffc`a339bd0c   USER32!DefWindowProcW+0x1c4
18 00007ffc`a33b0f2e   v_WndProc+0xac
19 00007ffc`bb8bca66   s_WndProc+0x6e
1a 00007ffc`bb8bc582   USER32!UserCallWinProcCheckWow+0x266
1b 00007ffc`a33a48a3   USER32!DispatchMessageWorker+0x1b2
1c 00007ffc`a33a47a9   FrameMessagePump+0xe3
1d 00007ffc`a33a46f6   explorerframe!BrowserThreadProc+0x85
1e 00007ffc`a33a5a12   explorerframe!BrowserNewThreadProc+0x3a
1f 00007ffc`a33b70c2  InternalResumeRT+0x12
20 00007ffc`babdb3ec  Run+0xb2
21 00007ffc`babdb0a5  TT_Run+0x3c
22 00007ffc`babdaf85  ThreadProc+0xdd
23 00007ffc`bc9ac315  s_ThreadProc+0x35
24 00007ffc`bb6d7e94   shcore!_WrapperThreadProc+0xf5
25 00007ffc`be4f7ad1   KERNEL32!BaseThreadInitThunk+0x14
26 00000000`00000000   ntdll!RtlUserThreadStart+0x21

没有任何特殊原因可以使用死记硬背的软件 bp

如何做多个条件

1: kd> bp win32kfull!NtUserMessageCall ".if ( ( @rdx != 410 ) & ( @rcx != 20498 ) ) { r rdx,rcx; gc }"
WARNING: Software breakpoints on session addresses can cause bugchecks.
Use hardware execution breakpoints (ba e) if possible.
breakpoint 0 redefined
1: kd> g
rdx=0000000000000084 rcx=0000000000010404
rdx=0000000000000084 rcx=000000000001046e
rdx=0000000000000084 rcx=0000000000010404
rdx=0000000000000020 rcx=0000000000010470
rdx=0000000000000020 rcx=000000000001046e
rdx=0000000000000020 rcx=00000000000104a6
rdx=0000000000000020 rcx=000000000001048e
rdx=0000000000000020 rcx=0000000000060480
rdx=0000000000000020 rcx=0000000000010446
rdx=0000000000000020 rcx=0000000000010404
rdx=0000000000000407 rcx=000000000001047c
rdx=0000000000000084 rcx=0000000000010404
rdx=000000000000004e rcx=0000000000010492
win32kfull!NtUserMessageCall:
ffffeae2`57cdc020 48895c2408      mov     qword ptr [rsp+8],rbx
1: kd> r rdx,rcx
rdx=0000000000000407 rcx=0000000000020498

位运算符与逻辑运算符的演示以及为什么需要将逻辑运算符评估为 C++

0:000> $$ display rdx and rcx register
0:000> r rdx, rcx
rdx=0000000000000000 rcx=00007ffd7a57fc04
0:000> $$ evaluating logical operator as C++ expression
0:000> ?? @rdx && @rcx
bool false
0:000> $$ evaluating logical operator as masm expression (will fail)
0:000> ? @rdx && @rcx
Numeric expression missing from '& @rcx'
0:000> $$ evaluating bitwise operator as masm expression 
0:000> ? @rdx & @rcx
Evaluate expression: 0 = 00000000`00000000
0:000> $$ evaluating bitwise operator as c++ expression 
0:000> ?? @rdx & @rcx
unsigned int64 0