wenmo8 发布的文章

这是一个很常见的问题,我们几乎总是遇到。想象一下这样一种情况,我们从某个地方得到一个内存转储,想看看在那里运行的是什么操作系统,安装了什么SP。。为此,有一个非常简单的命令。

0:000>vertarget
Windows 7 Version 7601 (Service Pack 1) MP (8 procs) Free x86 compatible
Product: WinNt, suite: SingleUserTS
kernel32.dll version: 6.1.7601.24475 (win7sp1_ldr.190516-0600)
Machine Name:
Debug session time: Fri Dec  6 09:36:00.000 2019 (UTC + 8:00)
System Uptime: 0 days 0:51:15.649
Process Uptime: 0 days 0:00:41.000
  Kernel time: 0 days 0:00:05.000
  User time: 0 days 0:00:13.000

我发现在代码中使用win32api时,需要多次监视最后一个win32错误!(在每次使用API后调用GetLastError()是不可行的解决方案!).. 在Visual Studio中,它们提供了一个非常好的小特性。你可以在“监视”窗口中写入@err,hr

同样,您可以使用另一个伪寄存器@eax来监视函数返回值!(如果您正在查看某些Win32 API的返回值,也可以执行@eax,hr来查找整数后面的文本消息。)

假设有一种情况,您从客户那里得到一个内存转储,需要模块(DLL、EXE、OCX等)来进一步调试。。(.NET模块可用于通过反向工程查看源代码。)
我们可以使用windbg目录中的clr10\sos.dll保存所有模块(在获取内存转储时由目标进程加载)。有趣的是,sos.dll不仅可以提取托管模块,还可以保存所有本机/非托管模块!

先加载sos模块

 

然后用!sam <path> OR !SaveAllModule <path> 提取特定磁盘位置上的模块。

 

如果您想查看任何windbg扩展所支持的命令,可以采用各种方法。

  • 你可以用!<ext_name>.help命令查看该扩展支持的所有命令。用扩展模块名替换<ext_name>。(注意:只有特定扩展支持help命令时,此操作才有效。)
  • 您可以在Dependency Walker中打开扩展DLL,它将在导出的功能面板中显示所有命令!command它背后没有任何魔力,它只是一个事实,WinDbg有非常简单的扩展模型,在这里您需要为每个命令实现导出的函数。当我们在Windbg中使用调试器扩展命令时,Windbg只是为那个函数执行GetProcAddress并调用它。依赖性walker具有显示模块导出函数的功能。