当前位置:   article > 正文

调试运行在Wow64子系统下的程序----x64版windbg调试win32程序_wow64systemserviceex

wow64systemserviceex

    大家有没有遇到过这种情况:程序崩溃了,windbg分析线程堆栈时,输出了一堆乱七八糟的调用栈。更烦心的是,这堆调用栈中根本找不到跟自己程序相关的信息。来看一个类似的场景:运行C:\Windows\SysWOW64\calc.exe (win32版的calc.exe),windbg(x64 bit)附加到calc.exe:

  1. 0:003> ~*kb
  2. 0 Id: 2718.1c98 Suspend: 1 Teb: 00000000`7efdb000 Unfrozen
  3. # RetAddr : Args to Child : Call Site
  4. 00 00000000`741fae90 : 00000000`00000000 00000000`7420342a 00000000`00000000 00000000`0005138e : wow64win!ZwUserGetMessage+0xa
  5. 01 00000000`7424d18f : 00000000`0017ef6c 00000000`7efdb000 00000000`7efdd000 00000000`741faef4 : wow64win!whNtUserGetMessage+0x30
  6. 02 00000000`741d2776 : 00000000`74b378d7 00000000`74240023 00000000`00200246 00000000`0017ef64 : wow64!Wow64SystemServiceEx+0xd7
  7. 03 00000000`7424d286 : 00000000`00000000 00000000`741d1920 00000000`770f3128 00000000`7712c4f1 : wow64cpu!ServiceNoTurbo+0x2d
  8. 04 00000000`7424c69e : 00000000`00000000 00000000`00000000 00000000`74244b10 00000000`7ffe0030 : wow64!RunCpuSimulation+0xa
  9. 05 00000000`771243c3 : 00000000`002c3b20 00000000`00000000 00000000`77222e70 00000000`770f7550 : wow64!Wow64LdrpInitialize+0x42a
  10. 1 Id: 2718.4d8 Suspend: 1 Teb: 00000000`7efd8000 Unfrozen
  11. # RetAddr : Args to Child : Call Site
  12. 00 00000000`741d283e : 00000000`74b3a965 00000000`00000023 00000000`00000246 00000000`0373f30c : wow64cpu!CpupSyscallStub+0x9
  13. 01 00000000`7424d286 : 00000000`00000000 00000000`741d1920 00000000`00000000 00000000`00000000 : wow64cpu!WaitForMultipleObjects32+0x3b
  14. 02 00000000`7424c69e : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : wow64!RunCpuSimulation+0xa
  15. 03 00000000`771898c4 : 00000000`00000000 00000000`7efdf000 00000000`7efd8000 00000000`00000000 : wow64!Wow64LdrpInitialize+0x42a
  16. 2 Id: 2718.2078 Suspend: 1 Teb: 00000000`7efd5000 Unfrozen
  17. # RetAddr : Args to Child : Call Site
  18. 00 00000000`741d283e : 00000000`74b38e63 00000000`00000023 00000000`00000246 00000000`03bcf9fc : wow64cpu!CpupSyscallStub+0x9
  19. 01 00000000`7424d286 : 00000000`00000000 00000000`741d1920 00000000`00000000 00000000`00000000 : wow64cpu!WaitForMultipleObjects32+0x3b
  20. 02 00000000`7424c69e : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : wow64!RunCpuSimulation+0xa
  21. 03 00000000`771898c4 : 00000000`00000000 00000000`7efdf000 00000000`7efd5000 00000000`00000000 : wow64!Wow64LdrpInitialize+0x42a

    Windows x64系统为了兼容win32程序,加入了Wow64子系统。Wow子系统Hook win32的系统调用,在Wow64Cpu/Wow64/Wow64win三个dll中实现相应的系统调用功能。所以尽管calc.exe并不显示依赖这些dll,但是在windbg输出的调用栈中仍会找到这些模块信息。

    既然Wow64子系统只是Hook win32程序的API,那么他必然不会修改程序本身的实现,所以calc.exe的调用信息只是被隐藏在Wow64Cpu/Wow64/Wow64win这3个dll的背后。那么如何把他们暴露到阳光下?只要2条windbg命令就能实现:

  1. 0:003> .load wow64exts
  2. 0:003> !wow64exts.sw
  3. Switched to Guest (WoW) mode

    wow64exts命令扩展随windbg一起发布,用于调试运行在Wow64子系统中的win32程序,默认并不加载,需要使用.load wow64exts加载。加载后通过命令!wow64exts.sw切换模式,切换后就像在x86系统上调试win32程序一样:

  1. 0:003:x86> ~*kb
  2. 0 Id: 2718.1c98 Suspend: 1 Teb: 7efdb000 Unfrozen
  3. # ChildEBP RetAddr Args to Child
  4. 00 0017ef64 74b3790d 0017f068 00000000 00000000 USER32!NtUserGetMessage+0x15
  5. 01 0017ef80 00871cbc 0017f068 00000000 00000000 USER32!GetMessageW+0x33
  6. 02 0017fcfc 0088219a 00870000 00000000 00483faf calc!WinMain+0x878
  7. 03 0017fd8c 75d5343d 7efde000 0017fdd8 772e9802 calc!_initterm_e+0x1a1
  8. 04 0017fd98 772e9802 7efde000 77afdc5b 00000000 KERNEL32!BaseThreadInitThunk+0xe
  9. 05 0017fdd8 772e97d5 00882d6c 7efde000 00000000 ntdll_772b0000!__RtlUserThreadStart+0x70
  10. 06 0017fdf0 00000000 00882d6c 7efde000 00000000 ntdll_772b0000!_RtlUserThreadStart+0x1b
  11. 1 Id: 2718.4d8 Suspend: 1 Teb: 7efd8000 Unfrozen
  12. # ChildEBP RetAddr Args to Child
  13. 00 0373f9ac 76dc171a 00000002 0373f9fc 00000001 ntdll_772b0000!ZwWaitForMultipleObjects+0x15
  14. 01 0373fa48 75d519fc 0373f9fc 0373fa70 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x100
  15. 02 0373fa90 74b40882 00000002 7efde000 00000000 KERNEL32!WaitForMultipleObjectsExImplementation+0xe0
  16. 03 0373fae4 74b40b81 000000f4 0373fb44 ffffffff USER32!RealMsgWaitForMultipleObjectsEx+0x14d
  17. 04 0373fb00 71057910 00000001 0373fb44 00000000 USER32!MsgWaitForMultipleObjects+0x1f
  18. 05 0373fb4c 7105782f 00000000 00000000 00000000 gdiplus!BackgroundThreadProc+0x59
  19. 06 0373fb64 75d5343d 00832218 0373fbb0 772e9802 gdiplus!DllRefCountSafeThreadThunk+0x10
  20. 07 0373fb70 772e9802 00832218 74cbda33 00000000 KERNEL32!BaseThreadInitThunk+0xe
  21. 08 0373fbb0 772e97d5 7105781f 00832218 00000000 ntdll_772b0000!__RtlUserThreadStart+0x70
  22. 09 0373fbc8 00000000 7105781f 00832218 00000000 ntdll_772b0000!_RtlUserThreadStart+0x1b
  23. 2 Id: 2718.2078 Suspend: 1 Teb: 7efd5000 Unfrozen
  24. # ChildEBP RetAddr Args to Child
  25. 00 03bcfa8c 72a3a41c 00000001 03bcfaec 00000001 ntdll_772b0000!ZwWaitForMultipleObjects+0x15
  26. 01 03bcfb34 75d5343d 00000000 03bcfb80 772e9802 WINMM!timeThread+0x3c
  27. 02 03bcfb40 772e9802 00000000 7404da03 00000000 KERNEL32!BaseThreadInitThunk+0xe
  28. 03 03bcfb80 772e97d5 72a3a3e0 00000000 00000000 ntdll_772b0000!__RtlUserThreadStart+0x70
  29. 04 03bcfb98 00000000 72a3a3e0 00000000 00000000 ntdll_772b0000!_RtlUserThreadStart+0x1b
  30. # 3 Id: 2718.2734 Suspend: 1 Teb: 7ef9d000 Unfrozen
  31. # ChildEBP RetAddr Args to Child
  32. 00 0287f8c0 00000000 00000000 00000000 00000000 ntdll_772b0000!RtlUserThreadStart

从这次windbg的输出中可以看到熟悉的模块名字,就连寄存器也以x86架构的形式输出:

  1. 0:003:x86> r
  2. eax=771e9390 ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=00000000
  3. eip=772c01e4 esp=0287f8bc ebp=00000000 iopl=0 nv up ei pl nz na po nc
  4. cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
  5. ntdll_772b0000!RtlUserThreadStart:
  6. 772c01e4 89442404 mov dword ptr [esp+4],eax ss:002b:0287f8c0=00000000

最后,再次执行!wow64exts.sw命令,windbg又切换回x64模式,输出的内容跟文章开头一样~

参考:windows Internal 6th

Debugging WOW64

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/247226
推荐阅读
相关标签
  

闽ICP备14008679号