使用WinDbg —— .NET篇 (二)

来源:互联网 发布:融资软件 编辑:程序博客网 时间:2024/05/22 02:02

转载请注明出处:http://blog.csdn.net/ecjtu_luowei/article/details/44260453

四、观察行为

4.1 设置断点

讲设置断点前,先看段代码

using System;

 

namespace Ext1

{

    class Program

    {

        static void M1()

        {

            Console.WriteLine("M1");

        }

 

        static void M2()

        {

            Console.WriteLine("M2");

        }

 

        static void Main(string[] args)

        {

            M1();

            Console.Read();

            M1();

            M2();

        }

    }

}

设置断点的方式有很多,关键在于设置断点的位置和已知条件。可以设置断点的命令分别有,标准命令:bpbubmSOS扩展命令:!bpmdSOSEX扩展命令:!mbp。接下来我会简单介绍每个命令的使用,大家可以根据不同的使用环境和条件可以灵活使用这些命令。

0:004> .loadby sos clr

0:004> !name2ee Ext1.exe Ext1.Program.M1

Module:      00152e94

Assembly:    Ext1.exe

Token:       06000001

MethodDesc:  00153794

Name:        Ext1.Program.M1()

JITTED Code Address: 001b00a8

0:004> bp 001b00a8

0:004> bl

 0 e 001b00a8     0001 (0001)  0:**** 

0:004> g

Breakpoint 0 hit

eax=0000000d ebx=003eefdc ecx=02434b0c edx=00000000 esi=00000000 edi=003eef50

eip=001b00a8 esp=003eef2c ebp=003eef38 iopl=0         nv up ei pl zr na pe nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246

001b00a8 55              push    ebp

加载该程序后,通过g命令,g命令就是Go的意思,让程序继续运行,程序会执行到Read方法等待用户的输入,这个时候在调试器上使用快捷键Ctrl+Break中断程序,可以看到CLR已经被加载,然后如上表命令进行操作,首先通过!name2ee命令得到被编译过的M1方法地址0x004700a0,然后通过bp [Address]设值断点。继续执行程序,这个时候程序会自动中断,中断的地址就是刚刚设置的断点位置(EIP寄存器就是储存的下个指令所在的地址)。在上面的调试过程,还使用了bl命令查看断点列表,可以看到有一行数据输出:

0 e 004700a0     0001 (0001)  0:**** 

0:表示断点的ID

e:表示enable,表示该断点是有效的,还有一个状态是u,表示该断点还没找到位置,原因可能是对应的模块没有加载

004700a0:表示断点的地址

0001 (0001)(0001)表示至少要执行(hit)到该断点对应的地址1次才能触发该断点,0001 表示还剩下1次就能触发,也就是下次执行到该地址就能触发。设置断点hit的次数10次如:“~0 bp 004700a0 10

0:****0是进程ID****表示任何线程都可以触发该断点,如果只有ID0的线程能触发该线程,那么该值为:0:~000。设置某特定线程触发断点的命令如:“~0 bp 004700a0

按道理这后面应该还有关于断点的模块和方法信息,但是因为是托管代码,机器码都是临时生成的,所以找不到对应的模块和方法,这也导致了bubm命令没什么用。

bubm的使用都是依赖于非托管模块的符号,bu主要用来设置延迟性的断点,比如说某一模块还没加载到进程中的时候;bm主要是通过调试符号来模糊查找设置断点。另外bcbdbe分别是清除所有断点、disable断点和enable断点的命令,因为!bpmd!mbp设置的断点有时候是延迟的断点,这个时候不能使用标准命令管理这些断点,所以对应的!bpmd!mbp设置的断点也有对应的断点管理的命令,详情可以参考帮助文档。

看到这里,读者应该注意到刚才调试的过程中依赖于M1方法已经被编译过了,如果是给还没编译过的M2方法设置断点的话,就需要借助到SOS中的!bpmd命令:

0:004> !name2ee Ext1.exe Ext1.Program.M2

Module:      00152e94

Assembly:    Ext1.exe

Token:       06000002

MethodDesc:  001537a0

Name:        Ext1.Program.M2()

Not JITTED yet. Use !bpmd -md 001537a0 to break on run.

0:004> !bpmd -md 001537a0

MethodDesc = 001537a0

Adding pending breakpoints...

0:000> g

(efc.e44): CLR notification exception - code e0444143 (first chance)

JITTED Ext1!Ext1.Program.M2()

Setting breakpoint: bp 001B00F1 [Ext1.Program.M2()]

Breakpoint 1 hit

eax=001b00e0 ebx=003eefdc ecx=024346b4 edx=00000000 esi=00000000 edi=003eef50

eip=001b00f1 esp=003eef28 ebp=003eef28 iopl=0         nv up ei pl zr na pe nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246

001b00f1 90              nop

0:000> !name2ee Ext1.exe Ext1.Program.M2

Module:      00152e94

Assembly:    Ext1.exe

Token:       06000002

MethodDesc:  001537a0

Name:        Ext1.Program.M2()

JITTED Code Address: 001b00e0

0:000> !u 001b00e0

Normal JIT generated code

Ext1.Program.M2()

Begin 001b00e0, size 21

*** WARNING: Unable to verify checksum for Ext1.exe

 

d:\Code\Ext1\Ext1\Program.cs @ 13:

>>> 001b00e0 55              push    ebp

001b00e1 8bec            mov     ebp,esp

001b00e3 833d6031150000  cmp     dword ptr ds:[153160h],0

001b00ea 7405            je      001b00f1

001b00ec e8c36f5370      call    clr!GetHistoryFileDirectory+0x8786f (706e70b4) (JitHelp: CORINFO_HELP_DBG_IS_JUST_MY_CODE)

001b00f1 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 14:

001b00f2 8b0d34214303    mov     ecx,dword ptr ds:[3432134h] ("M2")

*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\51e2934144ba15628ba5a31be2dae7dc\mscorlib.ni.dll

*** ERROR: Module load completed but symbols could not be loaded for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\51e2934144ba15628ba5a31be2dae7dc\mscorlib.ni.dll

001b00f8 e8f3d2566f      call    mscorlib_ni+0x36d3f0 (6f71d3f0) (System.Console.WriteLine(System.String), mdToken: 06000992)

001b00fd 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 15:

001b00fe 90              nop

001b00ff 5d              pop     ebp

001b0100 c3              ret

!u命令是反汇编命令,通过查看M2编译后的地址,可以看到!bmpd将断点的位置刚好设置在了M2方法的开始。!bmpd命令还可以直接通过Symbol设置断点,如: !bpmd Ext1.exe Ext1.Program.M2

如果需要在Main方法的开始设置断点,由于启动程序后,会立马执行到Read方法,而且利用Windbg启动Ext.exe的时候再第一次中断的时候还没加载CLR,所以这个时候也不能使用!bpmd命令。这种情形下,有两个办法设置断点:

0:000> .symfix

0:000> .reload

Reloading current modules

.....

0:000> .load sosex

0:000> !mbp Program.cs 18

The CLR has not yet been initialized in the process.

Breakpoint resolution will be attempted when the CLR is initialized.

0:000> g

ModLoad: 770a0000 77140000   C:\Windows\syswow64\ADVAPI32.dll

ModLoad: 775c0000 7766c000   C:\Windows\syswow64\msvcrt.dll

ModLoad: 76da0000 76db9000   C:\Windows\SysWOW64\sechost.dll

ModLoad: 76cb0000 76da0000   C:\Windows\syswow64\RPCRT4.dll

ModLoad: 75830000 75890000   C:\Windows\syswow64\SspiCli.dll

ModLoad: 75820000 7582c000   C:\Windows\syswow64\CRYPTBASE.dll

ModLoad: 71510000 7158a000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscoreei.dll

ModLoad: 75890000 758e7000   C:\Windows\syswow64\SHLWAPI.dll

ModLoad: 75e10000 75ea0000   C:\Windows\syswow64\GDI32.dll

ModLoad: 76e40000 76f40000   C:\Windows\syswow64\USER32.dll

ModLoad: 76c90000 76c9a000   C:\Windows\syswow64\LPK.dll

ModLoad: 77210000 772ad000   C:\Windows\syswow64\USP10.dll

ModLoad: 75ea0000 75f00000   C:\Windows\SysWOW64\IMM32.DLL

ModLoad: 77140000 7720c000   C:\Windows\syswow64\MSCTF.dll

ModLoad: 70450000 70ae2000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll

ModLoad: 70370000 70443000   C:\Windows\SysWOW64\MSVCR110_CLR0400.dll

(7d4.e5c): Unknown exception - code 04242420 (first chance)

ModLoad: 6f3b0000 7036f000   C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\51e2934144ba15628ba5a31be2dae7dc\mscorlib.ni.dll

*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\51e2934144ba15628ba5a31be2dae7dc\mscorlib.ni.dll

ModLoad: 76f40000 7709c000   C:\Windows\syswow64\ole32.dll

*** WARNING: Unable to verify checksum for Ext1.exe

ModLoad: 6e9a0000 6ea0e000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll

Breakpoint: JIT notification received for method Ext1.Program.Main(System.String[]) in AppDomain 00515fe0.

Breakpoint set at Ext1.Program.Main(System.String[]) in AppDomain 00515fe0.

Breakpoint 1 hit

eax=002e0050 ebx=0029f3d4 ecx=02452254 edx=00000001 esi=00000000 edi=0029f340

eip=002e0067 esp=0029f320 ebp=0029f328 iopl=0         nv up ei pl zr na pe nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246

002e0067 90              nop

0:000> .loadby sos clr

0:000> !name2ee Ext1.exe Ext1.Program.Main

Module:      00182e94

Assembly:    Ext1.exe

Token:       06000003

MethodDesc:  001837ac

Name:        Ext1.Program.Main(System.String[])

JITTED Code Address: 002e0050

0:000> !u 002e0050

Normal JIT generated code

Ext1.Program.Main(System.String[])

Begin 002e0050, size 3b

 

d:\Code\Ext1\Ext1\Program.cs @ 18:

>>> 002e0050 55              push    ebp

002e0051 8bec            mov     ebp,esp

002e0053 83ec08          sub     esp,8

002e0056 894dfc          mov     dword ptr [ebp-4],ecx

002e0059 833d6031180000  cmp     dword ptr ds:[183160h],0

002e0060 7405            je      002e0067

002e0062 e84d704070      call    clr!JIT_DbgIsJustMyCode (706e70b4)

002e0067 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 19:

002e0068 ff159c371800    call    dword ptr ds:[18379Ch] (Ext1.Program.M1(), mdToken: 06000001)

002e006e 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 20:

002e006f e84852a86f      call    mscorlib_ni+0x9b52bc (6fd652bc) (System.Console.Read(), mdToken: 06000983)

002e0074 8945f8          mov     dword ptr [ebp-8],eax

002e0077 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 21:

002e0078 ff159c371800    call    dword ptr ds:[18379Ch] (Ext1.Program.M1(), mdToken: 06000001)

002e007e 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 22:

002e007f ff15a8371800    call    dword ptr ds:[1837A8h] (Ext1.Program.M2(), mdToken: 06000002)

002e0085 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 23:

002e0086 90              nop

002e0087 8be5            mov     esp,ebp

002e0089 5d              pop     ebp

002e008a c3              ret

还有一个办法是当加载CLR的时候中断运行,这个时候Windbg可以加载sos,如果需要设置断点,需要等到clrjit.dll被加载(下表中的sxe ld clrjit.dll就是指当加载clrjit.dll的时候自动中断),然后利用!bmpd设置断点:

0:000> sxe ld clrjit.dll

0:000> g

(8e8.ea4): Unknown exception - code 04242420 (first chance)

ModLoad: 6e9a0000 6ea0e000 C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll

eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=7efdd000 edi=003aeaf4

eip=77cefc52 esp=003ae9c8 ebp=003aea1c iopl=0         nv up ei pl zr na pe nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246

ntdll!ZwMapViewOfSection+0x12:

77cefc52 83c404          add     esp,4

0:000> .loadby sos clr

0:000> !bpmd Ext1.exe Ext1.Program.Main

Found 1 methods in module 00202e94...

MethodDesc = 002037ac

Adding pending breakpoints...

0:000> g

(8e8.ea4): CLR notification exception - code e0444143 (first chance)

JITTED Ext1!Ext1.Program.Main(System.String[])

Setting breakpoint: bp 00280067 [Ext1.Program.Main(System.String[])]

Breakpoint 0 hit

eax=00280050 ebx=003af554 ecx=027f2254 edx=00000001 esi=00000000 edi=003af4c0

eip=00280067 esp=003af4a0 ebp=003af4a8 iopl=0         nv up ei pl zr na pe nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246

00280067 90              nop

0:000> !name2ee Ext1.exe Ext1.Program.Main

Module:      00202e94

Assembly:    Ext1.exe

Token:       06000003

MethodDesc:  002037ac

Name:        Ext1.Program.Main(System.String[])

JITTED Code Address: 00280050

0:000> !u 00280050

Normal JIT generated code

Ext1.Program.Main(System.String[])

Begin 00280050, size 3b

 

d:\Code\Ext1\Ext1\Program.cs @ 18:

>>> 00280050 55              push    ebp

00280051 8bec            mov     ebp,esp

00280053 83ec08          sub     esp,8

00280056 894dfc          mov     dword ptr [ebp-4],ecx

00280059 833d6031200000  cmp     dword ptr ds:[203160h],0

00280060 7405            je      00280067

00280062 e84d704670      call    clr!GetHistoryFileDirectory+0x8786f (706e70b4) (JitHelp: CORINFO_HELP_DBG_IS_JUST_MY_CODE)

00280067 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 19:

00280068 ff159c372000    call    dword ptr ds:[20379Ch] (Ext1.Program.M1(), mdToken: 06000001)

0028006e 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 20:

*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\51e2934144ba15628ba5a31be2dae7dc\mscorlib.ni.dll

*** ERROR: Module load completed but symbols could not be loaded for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\51e2934144ba15628ba5a31be2dae7dc\mscorlib.ni.dll

0028006f e84852ae6f      call    mscorlib_ni+0x9b52bc (6fd652bc) (System.Console.Read(), mdToken: 06000983)

00280074 8945f8          mov     dword ptr [ebp-8],eax

00280077 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 21:

00280078 ff159c372000    call    dword ptr ds:[20379Ch] (Ext1.Program.M1(), mdToken: 06000001)

0028007e 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 22:

0028007f ff15a8372000    call    dword ptr ds:[2037A8h] (Ext1.Program.M2(), mdToken: 06000002)

00280085 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 23:

00280086 90              nop

00280087 8be5            mov     esp,ebp

00280089 5d              pop     ebp

0028008a c3              ret

4.2 控制线程和进程

前面讲到command窗口输入命令的地方,左边有个X:Y格式的消息显示,XY分别代表当前调试的进程ID和线程ID。因为有许多命令都是跟当前调试的进程和线程线程相关,如!clrstack!dumpstack等。所以有时有需求切换当前进程,切换可以通过Process and Thread窗口实现(根据需要选择要切换的进程或进程):

 

或者通过命令,“| s”和“~ s”分别用来切换进程和线程:

 

4.3 查看线程

通过“!threads”命令可以查看当前进程的所有托管线程的简要信息:

 

命令输出信息首先是所有托管线程的一个概要信息,从这部分信息里面就能看出线程是不是是不是正常。紧接着是表格式的输出每个托管线程的概要信息,第一列没有title,这个是Windbg调试器维护的线程ID,切换线程命令或当前线程信息等都是指的这列所代表的值;ID这一列就是ManagedThreadId属性值;OSID指的对应的系统线程IDThreadOBJ指非托管线程结构对象的地址,这个值有点鸡肋,因为是非托管对象地址,不能直接通过!do查看这个线程对象的详细信息;State指线程的当前状态,这个值看不懂没关系,SOS提供了!threadstate命令帮助理解,如下表Table1GC ModePreemptive的时候表明当前线程执行的位置是非托管代码,同时也表明GC可以随时提高该线程的优先级(唤醒)或者回收该线程,当值为Cooperative表明当前线程执行中断的位置是停在托管代码的地方,这个时候GC也会等待当前线程完成它的工作,才能有所作为;GC Alloc Context在该线程分配对象的时候可能会用到,这个在后面再细讲;Domain指所处的域,可以通过!dumpdomain,查看域相关信息,如下表Table2Lock Count表明线程占据了多少托管锁;Apt表明线程是MTA模式还是STA模式,同时可以使用!comstate可以打印出所有线程的com apartment模式,如下表Table3Ukn表示Unknow,非托管线程会显示值为UknException表明当前线程最后抛出的托管类型的Exception

Table1:查看线程状态

0:004> !threadstate 2a020 

    Legal to Join

    CoInitialized

    In Multi Threaded Apartment

    Fully initialized

 

Table2:查看域信息

0:000> !dumpdomain 005b5fe0 

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

Domain 1:           005b5fe0

LowFrequencyHeap:   005b6434

HighFrequencyHeap:  005b647c

StubHeap:           005b64c4

Stage:              OPEN

SecurityDescriptor: 005b7bd0

Name:               Ext1.exe

Assembly:           005f8968 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]

ClassLoader:        005fc240

SecurityDescriptor: 005f88d0

  Module Name

6def1000    C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

 

Assembly:           00603bf0 [D:\Code\Ext1\Ext1\bin\Debug\Ext1.exe]

ClassLoader:        00603cf0

SecurityDescriptor: 005feac8

  Module Name

00142e94    D:\Code\Ext1\Ext1\bin\Debug\Ext1.exe

 

Table3:查看Com Apartment Mode

0:000> !comstate

     ID     TEB   APT    APTId CallerTID Context

  0  fdc 7efdd000 MTA        0         0 00704fc0

  1  9b0 7efda000 Ukn

  2  bdc 7efd7000 MTA        0         0 00704fc0

  3  aa8 7ef9f000 Ukn

 

4.4 查看线程栈

查看托管代码调用堆栈可以使用命令!clrstack,使用参数 -p -l分别附带显示参数和局部变量信息,-a参数是表示显示参数和局部变量信息。!clrstack只会打印出当前线程的调用堆栈,使用标准命令辅助 ~*e !clrstack会打印出所有线程的堆栈信息。

0:000> !clrstack

OS Thread Id: 0xfdc (0)

Child SP       IP Call Site

0037ed6c 003b00a0 Ext1.Program.M1() [d:\Code\Ext1\Ext1\Program.cs @ 8]

0037ed70 003b007e Ext1.Program.Main(System.String[]) [d:\Code\Ext1\Ext1\Program.cs @ 21]

0037ef04 6fb22652 [GCFrame: 0037ef04] 

查看托管代码和非托管代码的调用堆栈信息使用命令!dumpstack,由于信息太多,就没有全部复制出来:

0:000> !dumpstack

OS Thread Id: 0xfdc (0)

Current frame: (MethodDesc 00143794 +0 Ext1.Program.M1())

ChildEBP RetAddr  Caller, Callee

0037ed68 003b007e (MethodDesc 001437ac +0x2e Ext1.Program.Main(System.String[])), calling (MethodDesc 00143794 +0 Ext1.Program.M1())

0037ed78 6fb22652 clr!CallDescrWorkerInternal+0x34

0037ed84 6fb3264f clr!CallDescrWorkerWithHandler+0x6b, calling clr!CallDescrWorkerInternal

0037ed98 6fb32608 clr!CallDescrWorkerWithHandler+0x20, calling clr!_alloca_probe

...

同样!dumpstack命令只会打印当前线程的堆栈信息,要想打印所有的线程的堆栈信息,同样可以使用标准命令辅助~*e !dumpstack。但是这个命令会打印出所有线程的堆栈信息,如果程序使用的线程比较多的时候,打印出来的信息往往冗长有余。如果仅仅是需要打印出托管线程的托管代码和非托管代码的堆栈信息,可以使用命令!eestack:

0:000> !eestack

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

Thread   0

Current frame: (MethodDesc 00143794 +0 Ext1.Program.M1())

ChildEBP RetAddr  Caller, Callee

0037ed68 003b007e (MethodDesc 001437ac +0x2e Ext1.Program.Main(System.String[])), calling (MethodDesc 00143794 +0 Ext1.Program.M1())

0037ed78 6fb22652 clr!CallDescrWorkerInternal+0x34

0037ed84 6fb3264f clr!CallDescrWorkerWithHandler+0x6b, calling clr!CallDescrWorkerInternal

...

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

Thread   2

Current frame: ntdll!ZwWaitForMultipleObjects+0x15

ChildEBP RetAddr  Caller, Callee

...

 

4.5 反编译

反汇编的命令有标准命令u或者扩展命令!u,对于net程序来说!u命令打印出来的汇编语言会默认相应打印出源代码的文件位置和行号,对于看不到源代码的程序并且是为了静态分析这段汇编程序的人来,这多出来的源代码文件位置和行号无任何意义,但是我们可以根据出问题的callstack的行号信息和和!u打印出来的行号信息进行对比分析,也是能分析出一些蛛丝马迹出来。当然!u的使用不止这个好处,!u支持的参数更方便反汇编net程序,参数可以是托管代码的虚拟地址或者方法描述符地址。!u不仅支持打印源代码的文件位置和行号,通过 -gcinfo参数会对应多打印出一些GC信息,参数-ehinfo会对应多打印出代码中exception相关的中的信息:

0:000> u 00143794

00143794 0100            add     dword ptr [eax],eax

00143796 0021            add     byte ptr [ecx],ah

00143798 05002800a0      add     eax,0A0002800h

0014379d 003b            add     byte ptr [ebx],bh

0014379f 0002            add     byte ptr [edx],al

001437a1 0003            add     byte ptr [ebx],al

001437a3 2006            and     byte ptr [esi],al

001437a5 0028            add     byte ptr [eax],ch

0:000> !u -gcinfo 00143794

Normal JIT generated code

Ext1.Program.M1()

Begin 003b00a0, size 21

 

d:\Code\Ext1\Ext1\Program.cs @ 8:

003b00a0 55              push    ebp

003b00a1 8bec            mov     ebp,esp

003b00a3 833d6031140000  cmp     dword ptr ds:[143160h],0

003b00aa 7405            je      003b00b1

003b00ac e80370a06f      call    clr!JIT_DbgIsJustMyCode (6fdb70b4)

003b00b1 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 9:

003b00b2 8b0d30215503    mov     ecx,dword ptr ds:[3552130h] ("M1")

0018        reg ECX becoming live

003b00b8 e833d3f467      call    mscorlib_ni+0x36d3f0 (682fd3f0) (System.Console.WriteLine(System.String), mdToken: 06000992)

001D        reg ECX becoming dead

003b00bd 90              nop

 

d:\Code\Ext1\Ext1\Program.cs @ 10:

003b00be 90              nop

003b00bf 5d              pop     ebp

003b00c0 c3              ret

对于笔者这种菜鸟来说,反汇编如同鸡肋一般,因为我没那个耐心去分析大段的汇编程序,我最多看下代码中怎么处理exception的信息。如果读者也不喜欢看汇编的话,还有个命令适合分析代码,就是!dumpil,这个命令会打印出IL

0:000> !dumpil 00143794

ilAddr = 00b620d0

IL_0000: nop 

IL_0001: ldstr "M1"

IL_0006: call System.Console::WriteLine 

IL_000b: nop 

IL_000c: ret 

 

0 0
原创粉丝点击