【问题标题】:WinDbg: how to set a native breakpoint for .net programWinDbg:如何为 .net 程序设置本机断点
【发布时间】:2018-03-12 14:41:47
【问题描述】:

给定一个简单的 .NET 程序(来自https://docs.microsoft.com/en-us/dotnet/framework/interop/platform-invoke-examples):

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;

class Sample
{
    static void Main(string[] args)
    {
        MessageBox(IntPtr.Zero, "TEST", "TEST", 0);
    }
    [DllImport("user32.dll", SetLastError=true)]
    private static extern int MessageBox(IntPtr hwnd, String text, String title, uint type);
}

程序调用本机 Win32 函数MessageBox。 我想在 WinDbg 中的本机函数上设置一个断点。对于 API 文档,函数位于 user32.dll 中,因此我使用 bpuser32!MessageBox 处设置断点。

我运行 WinDbg,文件/打开可执行文件,打开程序的 exe,进入调试器。然后我执行了bp user32!MessageBoxW,但它说我:“无法解析bp表达式'user32!MessageBoxW',添加延迟bp”。

因此,如果我继续使用g,我将不会进入断点并出现错误:

"断点 0 的偏移表达式求值失败。 检查无效符号或语法错误。”

更新:
请参阅已接受的问题 - user32!MessageBox 不正确,应使用 user32!MessageBoxW。该消息“无法解析bp表达式'user32!MessageBoxW',添加延迟的bp”完全可以,只是说还没有加载任何符号。

【问题讨论】:

  • 使用user32!.MessageBoxWuser32!.MessageBoxA - user32!MessageBox 不存在

标签: c# .net winapi pinvoke windbg


【解决方案1】:

具有字符串参数的Windows API函数通常有两个版本,后缀为AW。 C/C++ SDK 定义了在编译器预处理步骤中选择一个或另一个。

在 WinDbg 中,您可以键入 bp user32!MessageBox,然后键入 Tab 以循环浏览已知符号/导出,但如果您使用延迟符号查找,则仅在加载 user32 后才有效。

如果您不想处理所有问题,您可以在两者上设置断点:

bp user32!MessageBoxA
bp user32!MessageBoxW 

WinDbg 将显示如下内容:

0:000> bp user32!MessageBoxA
Bp expression 'user32!MessageBoxA' could not be resolved, adding deferred bp
0:000> bp user32!MessageBoxW 
Bp expression 'user32!MessageBoxW' could not be resolved, adding deferred bp
0:000> g
ModLoad: 76d90000 76e3e000   C:\windows\SysWOW64\ADVAPI32.dll
...
ModLoad: 763a0000 764b6000   C:\windows\SysWOW64\USER32.dll
...    
ModLoad: 741d0000 74258000   C:\windows\SysWOW64\uxtheme.dll
ModLoad: 72700000 7276e000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
Breakpoint 0 hit
...
USER32!MessageBoxA:
76405f69 8bff            mov     edi,edi

【讨论】:

  • 抱歉误导性问题,但我确实尝试使用 W/A 功能,请参阅更新后的问题
  • 哦,好的,该消息“无法解析 Bp 表达式'user32!MessageBoxA',添加延迟 bp”似乎是合法的,实际上是断点命中。谢谢。
【解决方案2】:

当您刚刚使用 Open Executable 启动应用程序时,尚未加载 user32。

0:000> lm
start    end        module name
00d80000 00d88000   MessageBoxWTest   (deferred)             
73750000 737a4000   MSCOREE    (deferred)             
764a0000 76570000   KERNEL32   (deferred)             
76690000 76867000   KERNELBASE   (deferred)             
77b70000 77cfd000   ntdll      (export symbols)       C:\WINDOWS\SYSTEM32\ntdll.dll

因此 WinDBG 将无法加载和查找符号。 在这里你有两个选择:

  1. 使用bu Break Unresolved(延迟断点也使用它)。在这种情况下,调试器正在等待与您指定要加载的名称完全相同的符号。如果您输入错误,则不会命中断点。就像你的问题一样。
  2. 使用sxe ld name 命令等待特定模块加载,然后找到符号并设置断点。

_

0:000> sxe ld user32
0:000> g
ModLoad: 77030000 770a8000   C:\WINDOWS\SysWOW64\ADVAPI32.dll
ModLoad: 74720000 747dd000   C:\WINDOWS\SysWOW64\msvcrt.dll
ModLoad: 763e0000 76423000   C:\WINDOWS\SysWOW64\sechost.dll
ModLoad: 768f0000 769ae000   C:\WINDOWS\SysWOW64\RPCRT4.dll
ModLoad: 74590000 745b0000   C:\WINDOWS\SysWOW64\SspiCli.dll
ModLoad: 74580000 7458a000   C:\WINDOWS\SysWOW64\CRYPTBASE.dll
ModLoad: 761b0000 76207000   C:\WINDOWS\SysWOW64\bcryptPrimitives.dll
ModLoad: 736d0000 7374d000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscoreei.dll
ModLoad: 76430000 76475000   C:\WINDOWS\SysWOW64\SHLWAPI.dll
ModLoad: 75e00000 76046000   C:\WINDOWS\SysWOW64\combase.dll
ModLoad: 77a50000 77b67000   C:\WINDOWS\SysWOW64\ucrtbase.dll
ModLoad: 770b0000 770d2000   C:\WINDOWS\SysWOW64\GDI32.dll
ModLoad: 76050000 761ae000   C:\WINDOWS\SysWOW64\gdi32full.dll
ModLoad: 76870000 768ec000   C:\WINDOWS\SysWOW64\msvcp_win.dll
ModLoad: 770e0000 77255000   C:\WINDOWS\SysWOW64\USER32.dll
eax=00000000 ebx=00800000 ecx=00000000 edx=00000000 esi=0337c030 edi=0337bf90
eip=77bdea0c esp=0113d424 ebp=0113d470 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
ntdll!ZwMapViewOfSection+0xc:
77bdea0c c22800          ret     28h

在这里,我们在加载 USER32 后立即停止。现在,WinDBG 可以为其加载符号,我们可以找到它们。

0:000> x user32!MessageBox*
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\SysWOW64\USER32.dll - 
7714f8b0          USER32!MessageBoxA (<no parameter info>)
7714f8e0          USER32!MessageBoxExA (<no parameter info>)
7714f910          USER32!MessageBoxExW (<no parameter info>)
7714f940          USER32!MessageBoxIndirectA (<no parameter info>)
7714fa40          USER32!MessageBoxIndirectW (<no parameter info>)
7714faa0          USER32!MessageBoxTimeoutA (<no parameter info>)
7714fb50          USER32!MessageBoxTimeoutW (<no parameter info>)
7714fce0          USER32!MessageBoxW (<no parameter info>)

然后我们可以设置一个断点,肯定会被命中。

0:000> bp USER32!MessageBoxA
0:000> bp USER32!MessageBoxW
0:000> g
Breakpoint 0 hit
eax=7714f8b0 ebx=00000006 ecx=00000000 edx=00000004 esi=03023b48 edi=00d3f350
eip=7714f8b0 esp=00d3f26c ebp=00d3f320 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
USER32!MessageBoxA:
7714f8b0 8bff            mov     edi,edi
0:000> bl
     0 e Disable Clear  7714f8b0     0001 (0001)  0:**** USER32!MessageBoxA
     1 e Disable Clear  7714fce0     0001 (0001)  0:**** USER32!MessageBoxW

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-20
    • 2019-08-04
    • 2012-06-01
    • 1970-01-01
    相关资源
    最近更新 更多