工作中,经常遇到因窗口焦点莫名丢失或转移的bug,我们知道设置焦点的系统API 函数是SetFocus,因此,我想断到调用这个函数的地方。所以,需要查看这个api 在哪个dll里,MSDN描述这个api在User32.dll里,而当尝试中断时,发现断点没用,用depends.exe查看user32.dll的导出函数,确实有这个api函数,可能真实的API函数可能另有一个,微软利用某些机制改变了。
首先,我们用windbg,挂着我们的运行程序,配置好pdb路径等,试图对SetFocus函数下断点。(参考转来的文章: https://blog.csdn.net/blacet/article/details/103819155),发现断点没有下成功。于是,请教了老师傅如下:
0:004> x user32!*setfocus*
77541698 USER32!MLSetFocus (void)
775b4b68 USER32!_imp__NtUserSetFocus =
77555c00 USER32!NtUserSetFocus ()
7752c69a USER32!DlgSetFocus ()
77582a2a USER32!SLSetFocus ()
我们看到查询不到这API的,不过,有类似的,可能真实的api就是其中的一个。
我们分别用u 查看指定地址的反汇编,
0:004> u 77555c00
USER32!NtUserSetFocus:
77555c00 ff25684b5b77 jmp dword ptr [USER32!_imp__NtUserSetFocus (775b4b68)]
77555c06 cc int 3
77555c07 cc int 3
77555c08 cc int 3
77555c09 cc int 3
77555c0a cc int 3
77555c0b cc int 3
77555c0c cc int 3
0:004> u 775b4b68
USER32!_imp__NtUserSetFocus:
775b4b68 a0301376f0 mov al,byte ptr ds:[F0761330h]
775b4b6d 7413 je USER32!_imp__NtUserSetDesktopColorTransform+0x2 (775b4b82)
775b4b6f 76e0 jbe USER32!_imp__NtUserSetKeyboardState+0x1 (775b4b51)
775b4b71 7413 je USER32!_imp__NtUserSetCursorPos+0x2 (775b4b86)
775b4b73 76d0 jbe USER32!_imp__NtUserMagSetContextInformation+0x1 (775b4b45)
775b4b75 7413 je USER32!_imp__NtSetCursorInputSpace+0x2 (775b4b8a)
775b4b77 76b0 jbe USER32!_imp__NtUserSetProcessMousewheelRoutingMode+0x1 (775b4b29)
775b4b79 7413 je USER32!_imp__NtUserSetCursorContents+0x2 (775b4b8e)
用 dds地址,显示给定范围内的内存内容
775b4b68 USER32!_imp__NtUserSetFocus =
77555c00 USER32!NtUserSetFocus (
0:004> dds 77555c00
77555c00 4b6825ff
77555c04 cccc775b
77555c08 cccccccc
77555c0c cccccccc
77555c10 4b6425ff
77555c14 cccc775b
77555c18 cccccccc
77555c1c cccccccc
77555c20 4b6025ff
77555c24 cccc775b
77555c28 cccccccc
77555c2c cccccccc
77555c30 4b5c25ff
77555c34 cccc775b
77555c38 cccccccc
77555c3c cccccccc
77555c40 4b5825ff
77555c44 cccc775b
77555c48 cccccccc
77555c4c cccccccc
77555c50 4b5425ff
77555c54 cccc775b
77555c58 cccccccc
77555c5c cccccccc
77555c60 4b5025ff
77555c64 cccc775b
77555c68 cccccccc
77555c6c cccccccc
77555c70 4b4c25ff
77555c74 cccc775b
77555c78 cccccccc
77555c7c cccccccc
0:004> dds 775b4b68
775b4b68 761330a0 win32u!NtUserSetFocus
775b4b6c 761374f0 win32u!NtUserSetFeatureReportResponse
775b4b70 761374e0 win32u!NtUserSetFallbackForeground
775b4b74 761374d0 win32u!NtUserSetDisplayMapping
775b4b78 761374b0 win32u!NtUserSetDisplayAutoRotationPreferences
775b4b7c 761374a0 win32u!NtUserSetDialogControlDpiChangeBehavior
775b4b80 76137490 win32u!NtUserSetDesktopColorTransform
775b4b84 76137480 win32u!NtUserSetCursorPos
775b4b88 76136190 win32u!NtSetCursorInputSpace
775b4b8c 76137470 win32u!NtUserSetCursorContents
775b4b90 76137460 win32u!NtUserSetCoreWindowPartner
775b4b94 76137450 win32u!NtUserSetCoreWindow
775b4b98 76132d10 win32u!NtUserSetTimer
775b4b9c 76137440 win32u!NtUserSetClassWord
775b4ba0 76137430 win32u!NtUserSetChildWindowNoActivate
775b4ba4 76133020 win32u!NtUserSetCapture
775b4ba8 76137420 win32u!NtUserSetCalibrationData
775b4bac 76137410 win32u!NtUserSetBrokeredForeground
775b4bb0 76137400 win32u!NtUserSetBridgeWindowChild
775b4bb4 761373f0 win32u!NtUserSetAutoRotation
775b4bb8 761338c0 win32u!NtUserSetActiveWindow
775b4bbc 761373d0 win32u!NtUserSetActiveProcessForMonitor
775b4bc0 761373c0 win32u!NtUserSetActivationFilter
775b4bc4 761373b0 win32u!NtUserSendInteractiveControlHapticsReport
775b4bc8 76133380 win32u!NtUserSendInput
775b4bcc 761373a0 win32u!NtUserSendEventMessage
775b4bd0 76137390 win32u!NtUserRestoreWindowDpiChanges
775b4bd4 76137380 win32u!NtUserResolveDesktopForWOW
775b4bd8 76137370 win32u!NtUserRequestMoveSizeOperation
775b4bdc 76137350 win32u!NtUserRemoveVisualIdentifier
775b4be0 76133a60 win32u!NtUserRemoveMenu
775b4be4 761372e0 win32u!NtUserReleaseDwmHitTestWaiters
我们再看下加载的use32模块信息
0:004> lmvm user32
Browse full module list
start end module name
77510000 776a7000 USER32 (pdb symbols) C:\ProgramData\dbg\sym\wuser32.pdb\D6BE15768F32A983E69691D95F31D2451\wuser32.pdb
Loaded symbol image file: C:\WINDOWS\System32\USER32.dll
Image path: C:\WINDOWS\SysWOW64\USER32.dll
Image name: USER32.dll
Browse all global symbols functions data
Image was built with /Brepro flag.
Timestamp: 3CF29B91 (This is a reproducible build file hash, not a timestamp)
CheckSum: 0019E91A
ImageSize: 00197000
File version: 10.0.18362.535
Product version: 10.0.18362.535
File flags: 0 (Mask 3F)
File OS: 40004 NT Win32
File type: 2.0 Dll
File date: 00000000.00000000
Translations: 0409.04b0
Information from resource tables:
CompanyName: Microsoft Corporation
ProductName: Microsoft® Windows® Operating System
InternalName: user32
OriginalFilename: user32
ProductVersion: 10.0.18362.535
FileVersion: 10.0.18362.535 (WinBuild.160101.0800)
FileDescription: Multi-User Windows USER API Client DLL
LegalCopyright: © Microsoft Corporation. All rights reserved.
接着,我们使用!dh -a 77510000命令,查看user32的头信息
看到导出函数列表中确实是有SetFocus这个api的,
而且其地址是77555C00 。
我们再用u指令,看下这个地址的汇编,跳转到USER32!_imp__NtUserSetFocus (775b4b68) ,我们再
0:004> u 77555C00
USER32!NtUserSetFocus:
77555c00 ff25684b5b77 jmp dword ptr [USER32!_imp__NtUserSetFocus (775b4b68)]
77555c06 cc int 3
77555c07 cc int 3
77555c08 cc int 3
77555c09 cc int 3
77555c0a cc int 3
77555c0b cc int 3
77555c0c cc int 3
0:004> u 775b4b68
USER32!_imp__NtUserSetFocus:
775b4b68 a0301376f0 mov al,byte ptr ds:[F0761330h]
775b4b6d 7413 je USER32!_imp__NtUserSetDesktopColorTransform+0x2 (775b4b82)
775b4b6f 76e0 jbe USER32!_imp__NtUserSetKeyboardState+0x1 (775b4b51)
775b4b71 7413 je USER32!_imp__NtUserSetCursorPos+0x2 (775b4b86)
775b4b73 76d0 jbe USER32!_imp__NtUserMagSetContextInformation+0x1 (775b4b45)
775b4b75 7413 je USER32!_imp__NtSetCursorInputSpace+0x2 (775b4b8a)
775b4b77 76b0 jbe USER32!_imp__NtUserSetProcessMousewheelRoutingMode+0x1 (775b4b29)
775b4b79 7413 je USER32!_imp__NtUserSetCursorContents+0x2 (775b4b8e)
0:004> dds 775b4b68
775b4b68 761330a0 win32u!NtUserSetFocus
775b4b6c 761374f0 win32u!NtUserSetFeatureReportResponse
775b4b70 761374e0 win32u!NtUserSetFallbackForeground
775b4b74 761374d0 win32u!NtUserSetDisplayMapping
775b4b78 761374b0 win32u!NtUserSetDisplayAutoRotationPreferences
775b4b7c 761374a0 win32u!NtUserSetDialogControlDpiChangeBehavior
775b4b80 76137490 win32u!NtUserSetDesktopColorTransform
775b4b84 76137480 win32u!NtUserSetCursorPos
775b4b88 76136190 win32u!NtSetCursorInputSpace
绕了一圈又回来了,我们在一开始用dds就找到了这个函数的。我们可以猜测SetFocus的真实APi是win32u!NtUserSetFocus,在win32u!NtUserSetFocus处下断点,触发调用SetFocus的行为,果真中断下来了。