WinDbg 从模块中获取命名空间

WinDbg get namespaces from modules

我想在 CustomSpace 命名空间的每个方法上使用来自 sosex.dll 的命令 !mbm 放置断点。但是要怎么做呢?

PlayWithReference - 项目名称。

我试着用命令 !lm 观察加载了哪些模块

0:000> lm
start    end        module name
00f60000 00f68000   PlayWithReference   (deferred)             
72480000 724d4000   MSCOREE    (deferred)             
73fc0000 74090000   KERNEL32   (deferred)             
760f0000 762c8000   KERNELBASE   (deferred)             
76f00000 7708c000   ntdll      (export symbols)       C:\windows\SYSTEM32\ntdll.dll

然后使用命令 x 我观察了模块

中的函数
0:000> x PlayWithReference!*
*** WARNING: Unable to verify checksum for PlayWithReference.exe
<MSIL:00f60059         > PlayWithReference!Foo2 (void)
<MSIL:00f60071         > PlayWithReference!Main (void)
<MSIL:00f60026         > PlayWithReference!Foo1 (void)
<MSIL:00f6012f         > PlayWithReference!<Foo1>b__1_0 (void)
<MSIL:00f6000f         > PlayWithReference!get_Address (void)
<MSIL:00f60016         > PlayWithReference!set_Address (void)
<MSIL:00f60007         > PlayWithReference!set_Name (void)
<MSIL:00f60000         > PlayWithReference!get_Name (void)
<MSIL:00f6001e         > PlayWithReference!Foo (void)

x - 命令从模块返回函数名称但没有关于命名空间的信息。

如果我将使用 !mbm CustomSpace.Program.Foo,它将放置断点并正常工作。但是如果没有命名空间,我只能做类似 !mbm *Foo 的事情,在这种情况下,它将在所有具有该名称的函数上放置断点。怎么做?

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace NotWorkingName
{
    public class Employee
    {
        public string Name { get; set; }

        public string Address { get; set; }
    }

    class Program
    {
        public static void Foo()
        {
            Employee employee = new Employee();
        }
        public static void Foo1()
        {
            var t = Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < 3; i++)
                {
                    Foo2();
                }
            });
            t.Wait();
        }

        public static void Foo2()
        {
            Thread.Sleep(1000);
            Console.WriteLine("Foo2");
        }

        static void Main(string[] args)
        {
            List<string> TestReferences = new List<string>();
            for (int i = 0; i < 100000; i++)
            {
                TestReferences.Add(i.ToString());
            }
            Employee employee = new Employee();
            employee.Name = "Test";
            employee.Name = "Test1";
            Console.WriteLine(employee.Name);
            Foo1();
            Employee employee1 = new Employee();
            Employee employee2 = new Employee();
            Employee employee3 = new Employee();
            Employee employee4 = new Employee();
            Employee employee5 = new Employee();
            Employee employee6 = new Employee();
            Employee employee7 = new Employee();
            Employee employee8 = new Employee();
            Employee employee9 = new Employee();
            Employee employee10 = new Employee();
            Employee employee11 = new Employee();
            Foo();
            Console.Write("The end");
        }
    }
}

试试这个(使用旧的 SOS):

'a'只是要求有第二个参数

!name2ee PlayWithReference a
Module:      00007ff8d5be2838
Assembly:    PlayWithReference.exe

0:099> !dumpmodule -mt 0007ff8d5be2838
(...)


Types defined in this module

              MT    TypeDef Name
------------------------------------------------------------------------------
00007ff8d5be3250 0x02000024 NotWorkingName.Employee
00007ff8d5be34a0 0x02000029 NotWorkingName.Program

Types referenced in this module

              MT    TypeRef Name
------------------------------------------------------------------------------
00007ff93324a260 0x02000010 System.Collections.IEnumerable

(...)

要获取所有 类 的方法,请执行以下操作:

!dumpmt -md 00007ff8d5be3250
(...)

MethodDesc Table
           Entry       MethodDesc    JIT Name
00007ff8d53044a8 00007ff8d5be2fc0   NONE NotWorkingName.Employee.set_Name()
00007ff8d53044b8 00007ff8d5be2fd0   NONE NotWorkingName.Employee.get_Name()
(...)

不漂亮,但有效