惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
D
Docker
云风的 BLOG
云风的 BLOG
F
Fortinet All Blogs
F
Full Disclosure
H
Hackread – Cybersecurity News, Data Breaches, AI and More
P
Proofpoint News Feed
Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学
The GitHub Blog
The GitHub Blog
L
LangChain Blog
H
Help Net Security
B
Blog
T
Tailwind CSS Blog
V
V2EX
博客园_首页
阮一峰的网络日志
阮一峰的网络日志
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
Recent Announcements
Recent Announcements
aimingoo的专栏
aimingoo的专栏
美团技术团队
A
About on SuperTechFans
C
Cybersecurity and Infrastructure Security Agency CISA
K
Kaspersky official blog
I
InfoQ
Project Zero
Project Zero
I
Intezer
Google DeepMind News
Google DeepMind News
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Threat Research - Cisco Blogs
Last Week in AI
Last Week in AI
C
Cyber Attacks, Cyber Crime and Cyber Security
G
GRAHAM CLULEY
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
AWS News Blog
AWS News Blog
Spread Privacy
Spread Privacy
S
Securelist
Recorded Future
Recorded Future
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园 - 叶小钗
S
Security Affairs
Blog — PlanetScale
Blog — PlanetScale
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
The Hacker News
The Hacker News

博客园 - gxh973121

TeamTalk---服务端架构 找不到资产文件 project.assets.json windows 2008 VPN(PPTP/L2TP)搭建 - gxh973121 vs 调试时 QuickWatch 不能计算变量值 wireshark 分析过滤数据 go module 设置 逻辑漏洞之支付漏洞 java holdsLock()方法检测一个线程是否拥有锁 c#编程指南(十) 平台调用P-INVOKE完全掌握, 字符串和指针 Git过滤文件和文夹 VC CComboBox用法总结 WideCharToMultiByte和MultiByteToWideChar函数的用法 c++ 时间类型详解 time_t 链接报error LNK2019: unresolved external symbol错误,解决 VS2008 工程只生成dll不生成lib的解决方案 vs2010中的MSBuild输出warning MSB8012问题 在VS2010下编译和使用tesseract_ocr识别验证码 tesseract-ocr 提高验证码识别率手段之---识别码库训练方法 Windows下Qt5搭建Android开发环境笔记
Windbg在Managed App中设置函数断点的几种方法
gxh973121 · 2022-05-25 · via 博客园 - gxh973121

本文介绍两种使用Windbg在Managed App中设置断点的方法。一种是在live Debug的时候,attach到了Process之后。另外一种是动态调试的时候,如何给几个模块的特定方法下一个断点。    

         使用Windbg在Native Code里面下断点是比较方便的,bp加上一个内存地址就可以做到。但是在托管的时候给一个方法下一个断点稍微有点麻烦。因为Windbg是一个native Debugger,而Managed App在没有Jited的时候,是没有生成Native Code的。每个方法在第一次调用之后,才生成了native code。当然,这里不说ngen。

         还是先给个小程序做小白鼠:

         class Program

    {

        static void Main(string[] args)

        {

            System.Console.WriteLine("Show Params in Windbg");

            Program p = new Program();

            p.ShowParams(123456, "TestParams", 'L');

            System.Console.ReadLine();

        }

        public void ShowParams(int a, string b ,char c)

        {

        }

}

          在使用live Debug的时候,设置一个没有本地代码的方法断点不是很麻烦,首先:

          0:000> !name2ee *!FounctionParams.Program

Module: 790c2000 (mscorlib.dll)

--------------------------------------

Module: 00a82c3c (FounctionParams.exe)

Token: 0x02000002

MethodTable: 00a83038

EEClass: 00a811d8

Name: FounctionParams.Program

得到了MethodTable的地址了,然后:

         
0:000> !dumpmt -md 00a83038

EEClass: 00a811d8

Module: 00a82c3c

Name: FounctionParams.Program

mdToken: 02000002 (E:"myProject"FounctionParams"FounctionParams"bin"Debug"FounctionParams.exe)

BaseSize: 0xc

ComponentSize: 0x0

Number of IFaces in IFaceMap: 0

Slots in VTable: 7

--------------------------------------

MethodDesc Table

   Entry MethodDesc      JIT Name

79371278   7914b928   PreJIT System.Object.ToString()

7936b3b0   7914b930   PreJIT System.Object.Equals(System.Object)

7936b3d0   7914b948   PreJIT System.Object.GetHashCode()

793624d0   7914b950   PreJIT System.Object.Finalize()

00db0070   00a83020      JIT FounctionParams.Program.Main(System.String[])

00db0110   00a83028      JIT FounctionParams.Program.ShowParams

(Int32, System.String, Char)

00db00e0   00a83030      JIT FounctionParams.Program..ctor()

这里,得到了这个方法的MethodDesc的地址之后,继续:

0:000> !dumpmd 00a83028     

Method Name: FounctionParams.Program.ShowParams(Int32, System.String, Char)

Class: 00a811d8

MethodTable: 00a83038

mdToken: 06000002

Module: 00a82c3c

IsJitted: yes

m_CodeOrIL: 00db0110

可以看到,已经JIT过了,生成了本地的代码。列个时候,就有很多选择了,顺便看看native code:

0:000> !u 00db0110

Normal JIT generated code

FounctionParams.Program.ShowParams(Int32, System.String, Char)

Begin 00db0110, size 20

>>> 00db0110 83ec08          sub     esp,8

00db0113 890c24          mov     dword ptr [esp],ecx

00db0116 89542404        mov     dword ptr [esp+4],edx

00db011a 833d082ea80000 cmp     dword ptr ds:[0A82E08h],0

00db0121 7405            je      00db0128

00db0123 e81f823779      call    mscorwks!JIT_DbgIsJustMyCode (7a128347)

00db0128 90              nop

00db0129 90              nop

00db012a 83c408          add     esp,8

00db012d c20800          ret     8

感觉和方法本身的代码不是很像,不过也就是他了,这个时候下断点可以有很多选择:

在地址上面下断点:

0:000> bp 00db0110

用BPMD命令在这个方法的MethodDesc上面下断点:

0:000> !bpmd -md 00a83028     

MethodDesc = 00a83028

Setting breakpoint: bp 00DB0110 [FounctionParams.Program.ShowParams(Int32, System.String, Char)]

That will work。

如果是动态调试下面,该如何做呢?这个比较麻烦点:

使用Windbg的Open Executable File菜单,打开上面编写的测试的引用程序:

0:000> sxe ld:mscorjit

0:000> g

ModLoad: 79060000 790b6000   C:"WINDOWS"Microsoft.NET"Framework"v2.0.50727"mscorjit.dll

eax=00000000 ebx=00000000 ecx=00d90000 edx=7c90eb94 esi=00000000 edi=00000000

eip=7c90eb94 esp=0012e554 ebp=0012e648 iopl=0 nv up ei ng nz ac pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000296

ntdll!KiFastSystemCallRet:

7c90eb94 c3              ret

接着查看线程:

0:000> !threads

ThreadCount: 2

UnstartedThread: 0

BackgroundThread: 1

PendingThread: 0

DeadThread: 0

Hosted Runtime: no

Hosted Runtime: no

                                      PreEmptive   GC Alloc          

       ID       Context       Domain   Count APT Exception

   0    1   013f16d0:013f1fe8 0015c410    2 MTA

   2    2   00000000:00000000 0015c410     0 MTA (Finalizer)

接着就查看这个domain:

0:000> !dumpdomain 0015c410    

--------------------------------------

Domain 1: 0015c410

LowFrequencyHeap: 0015c434

HighFrequencyHeap: 0015c48c

StubHeap: 0015c4e4

Stage: OPEN

SecurityDescriptor: 0015d740

Name: FounctionParams.exe

Assembly: 0019f408

[C:"WINDOWS"assembly"GAC_32"mscorlib"2.0.0.0__b77a5c561934e089"mscorlib.dll]

ClassLoader: 0019f4a0

SecurityDescriptor: 0019be58

 Module Name

790c2000

C:"WINDOWS"assembly"GAC_32"mscorlib"2.0.0.0__b77a5c561934e089"mscorlib.dll

Assembly: 001a6b90

[E:"myProject"FounctionParams"FounctionParams"bin"Debug"FounctionParams.exe]

ClassLoader: 001a7270

SecurityDescriptor: 001a6a58

 Module Name

00a82c3c

E:"myProject"FounctionParams"FounctionParams"bin"Debug"FounctionParams.exe

然后查看module的信息:

0:000> !dumpmodule -mt 00a82c3c

Name: E:"myProject"FounctionParams"FounctionParams"bin"Debug"FounctionParams.exe

Attributes: PEFile

Assembly: 001a6b90

LoaderHeap: 00000000

TypeDefToMethodTableMap: 00a80038

TypeRefToMethodTableMap: 00a80040

MethodDefToDescMap: 00a8008c

FieldDefToDescMap: 00a8009c

MemberRefToDescMap: 00a800a0

FileReferencesMap: 00a800ec

AssemblyReferencesMap: 00a800f0

MetaData start address: 00402094 (1580 bytes)

Types defined in this module

      MT    TypeDef Name

------------------------------------------------------------------------------

00a83038 0x02000002 FounctionParams.Program

Types referenced in this module

      MT    TypeRef Name

------------------------------------------------------------------------------

790fd0f0 0x01000001 System.Object

恩,找到MT的地址了:

0:000> !dumpmt -md 00a83038

EEClass: 00a811d8

Module: 00a82c3c

Name: FounctionParams.Program

mdToken: 02000002 (E:"myProject"FounctionParams"FounctionParams"bin"Debug"FounctionParams.exe)

BaseSize: 0xc

ComponentSize: 0x0

Number of IFaces in IFaceMap: 0

Slots in VTable: 7

--------------------------------------

MethodDesc Table

   Entry MethodDesc      JIT Name

79371278   7914b928  PreJIT System.Object.ToString()

7936b3b0   7914b930   PreJIT System.Object.Equals(System.Object)

7936b3d0   7914b948   PreJIT System.Object.GetHashCode()

793624d0   7914b950   PreJIT System.Object.Finalize()

00a8c011   00a83020     NONE FounctionParams.Program.Main(System.String[])

00a8c015   00a83028     NONE FounctionParams.Program.ShowParams

(Int32, System.String, Char)

00a8c019   00a83030     NONE FounctionParams.Program..ctor()

恩,这个时候还没有被JIT,正好可以在这个地方下一个断点,当执行到这个方法的时候就触发断点:

0:000> !bpmd -md 00a83028    

MethodDesc = 00a83028    

Adding pending breakpoints...

恩,到这个地方,就给这个managed的方法,而且是没jited的给加上了一个断点。恩,两种不同的情况下下断点的方法。