使用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();
}
}
}
设置断点的方式有很多,关键在于设置断点的位置和已知条件。可以设置断点的命令分别有,标准命令:bp、bu、bm;SOS扩展命令:!bpmd;SOSEX扩展命令:!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,****表示任何线程都可以触发该断点,如果只有ID为0的线程能触发该线程,那么该值为:0:~000。设置某特定线程触发断点的命令如:“~0 bp 004700a0”
按道理这后面应该还有关于断点的模块和方法信息,但是因为是托管代码,机器码都是临时生成的,所以找不到对应的模块和方法,这也导致了bu和bm命令没什么用。
bu和bm的使用都是依赖于非托管模块的符号,bu主要用来设置延迟性的断点,比如说某一模块还没加载到进程中的时候;bm主要是通过调试符号来模糊查找设置断点。另外bc、bd、be分别是清除所有断点、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格式的消息显示,X和Y分别代表当前调试的进程ID和线程ID。因为有许多命令都是跟当前调试的进程和线程线程相关,如!clrstack,!dumpstack等。所以有时有需求切换当前进程,切换可以通过Process and Thread窗口实现(根据需要选择要切换的进程或进程):
或者通过命令,“| s”和“~ s”分别用来切换进程和线程:
4.3 查看线程
通过“!threads”命令可以查看当前进程的所有托管线程的简要信息:
命令输出信息首先是所有托管线程的一个概要信息,从这部分信息里面就能看出线程是不是是不是正常。紧接着是表格式的输出每个托管线程的概要信息,第一列没有title,这个是Windbg调试器维护的线程ID,切换线程命令或当前线程信息等都是指的这列所代表的值;ID这一列就是ManagedThreadId属性值;OSID指的对应的系统线程ID;ThreadOBJ指非托管线程结构对象的地址,这个值有点鸡肋,因为是非托管对象地址,不能直接通过!do查看这个线程对象的详细信息;State指线程的当前状态,这个值看不懂没关系,SOS提供了!threadstate命令帮助理解,如下表Table1;GC Mode为Preemptive的时候表明当前线程执行的位置是非托管代码,同时也表明GC可以随时提高该线程的优先级(唤醒)或者回收该线程,当值为Cooperative表明当前线程执行中断的位置是停在托管代码的地方,这个时候GC也会等待当前线程完成它的工作,才能有所作为;GC Alloc Context在该线程分配对象的时候可能会用到,这个在后面再细讲;Domain指所处的域,可以通过!dumpdomain,查看域相关信息,如下表Table2;Lock Count表明线程占据了多少托管锁;Apt表明线程是MTA模式还是STA模式,同时可以使用!comstate可以打印出所有线程的com apartment模式,如下表Table3,Ukn表示Unknow,非托管线程会显示值为Ukn;Exception表明当前线程最后抛出的托管类型的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
- 使用WinDbg —— .NET篇 (二)
- 使用WinDbg —— .NET篇 (一)
- 使用WinDbg —— .NET篇 (三)
- 使用WinDbg —— .NET篇 (四)
- 使用WinDbg —— .NET篇 (五)
- 使用WinDbg —— .NET篇 (六)
- 使用WinDbg —— .NET篇 (七)
- 使用WinDbg —— .NET篇 (八)
- 使用WinDbg —— .NET篇 (九)
- 使用WinDbg —— .NET篇 (十)
- 使用WinDbg —— .NET篇 (十一)
- 使用WinDbg —— .NET篇 (十二)
- 使用WinDbg —— .NET篇 (十三)
- WinDBG 使用教学(二)
- 使用Windbg 调试.Net程序
- 使用Windbg调试.Net应用程序
- 使用Windbg 调试.Net程序
- 使用WinDbg调试Windows内核(二)
- 女人必须气质过人
- ssh免密码登录
- 第1周-项目3-时间类(增加n)
- 在centos6.5下更新python
- main之前执行
- 使用WinDbg —— .NET篇 (二)
- Objective-C基础——protocol
- Java数据导入(读)Excel文件 解析
- Java enum使用
- JPA注解查询
- Verilog学习总结
- ERROR 1044 (42000): Access denied for user ”@’localhost’ to database ‘mysql’
- 【Cocos2d-x】问题解决记录--解决extensions库编译报错问题
- 通过BufferedInputStream bufferedOutputStream读写文件