一: .NET 框架
1. 宏观概念
.NET 是一个虚拟的运行时环境,包含了一个虚拟执行引擎(CLR)及一组相关的框架库,画图如下:

1) ECMA
是一份实现.NET运行时的规格文档。
参考网址:https://learn.microsoft.com/en-us/dotnet/fundamentals/standards
2)CLR
通用语言运行时,我们 C#, VB.NET 语言的托管环境,也是我们高级调试重点研究的东西。
3).NET框架
一些基础框架及中间件,比如:WPF,WinForm,WebApi,MVC 等。
4).NET应用程序
这是我们的应用程序,基于这些 .NET 框架之上。
2. .NET应用的编译流程
一般来说, .NET 程序存在两层编译。
1)编译器编译
将我们的 C# 程序通过 Visual Studio 等编译工具转成 IL 代码。
2) JIT
CLR 运行时调用 JIT 组件将 IL 代码 转成 机器代码。
框架图如下:

二:PE头及Window加载器
1. 什么是 PE 文件
PE 文件,又叫可移植可执行的文件格式(Portable Executable),它的一个非常大的作用就是帮助 Windows加载器
执行程序的入口。
对于 .NET 程序的PE文件,有几点要注意。
1)AddressOfEntryPoint
程序的入口点相对偏移地址,即 (exe+AddressOfEntryPoint)。
2)DIRECTORY_ENTRY_COM_DESCRIPTOR
.NET程序独有的节点配置。
MajorRuntimeVersion,MinorRuntimeVersion:CLR 的上下限版本。
MetaData:元数据相对偏移位置 (RVA)
EntryPointToken :Main 函数的标记。

参考案例:Example_2_1_1
2. 案例演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| ModLoad: 00400000 00408000 Example_2_1_1.exe ModLoad: 77800000 779a3000 ntdll.dll ModLoad: 60650000 606a2000 C:\Windows\SysWOW64\MSCOREE.DLL ModLoad: 753d0000 754c0000 C:\Windows\SysWOW64\KERNEL32.dll ModLoad: 767c0000 769d4000 C:\Windows\SysWOW64\KERNELBASE.dll (1030.4e74): Break instruction exception - code 80000003 (first chance) eax=00000000 ebx=00000000 ecx=5a430000 edx=00000000 esi=77811ff4 edi=778125bc eip=778b1a42 esp=0019fa20 ebp=0019fa4c 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!LdrpDoDebuggerBreak+0x2b: 778b1a42 cc int 3
0:000> u 00400000+000027A6 Example_2_1_1!COM+_Entry_Point <PERF> (Example_2_1_1+0x27a6): 004027a6 ff2500204000 jmp dword ptr [Example_2_1_1!COM+_Entry_Point <PERF> (Example_2_1_1+0x2000) (00402000)]
0:000> dp 00402000 L1 00402000 00002785
|
这里的偏移 2785
,正好是 mscoree.dll 下的 _CorExeMain 方法,截图如下:

参考案例:Example_2_1_1
3. 一个小知识
windbg 有一个伪寄存器命令 $exentry
,可以直接告诉当前exe的入口点地址。
1 2 3 4 5 6 7
| 0:006> ? $exentry Evaluate expression: 4204454 = 004027a6
0:006> u 004027a6 Example_2_1_1!COM+_Entry_Point <PERF> (Example_2_1_1+0x27a6): 004027a6 ff2500204000 jmp dword ptr [Example_2_1_1!COM+_Entry_Point <PERF> (Example_2_1_1+0x2000) (00402000)]
|
三:应用程序域
1. 简介
对于Windows上的应用程序,大家都知道是按照 进程
进行隔离的,架构图如下:

.NET 将这种进程隔离级别缩小到了 应用程序域 (AppDomain)
层,即一个进程会有多个 应用程序域
,然后将 程序 部署在 应用程序域
上,架构图如下:

1) SystemDomain
- 系统级作用域,用于创建其他作用域。
- 将 mscorlib.dll 加载到 共享应用程序域中。
- 记录字符串池中的字符串常量
- 初始化特定异常,(OutofMemoryException,StackOverflowException)
2)ShardDomain
- 加载 System 命名空间下的基本类型(String,Enum,ValueType)
3) Domain1
2. windbg 验证
参考案例:Example_2_1_1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| 0:006> !dumpdomain -------------------------------------- System Domain: 5086caf8 LowFrequencyHeap: 5086ce1c HighFrequencyHeap: 5086ce68 StubHeap: 5086ceb4 Stage: OPEN Name: None -------------------------------------- Shared Domain: 5086c7a8 LowFrequencyHeap: 5086ce1c HighFrequencyHeap: 5086ce68 StubHeap: 5086ceb4 Stage: OPEN Name: None Assembly: 005e3ab8 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll] ClassLoader: 005e3b80 Module Name 7b841000 C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
-------------------------------------- Domain 1: 00593ca0 LowFrequencyHeap: 0059410c HighFrequencyHeap: 00594158 StubHeap: 005941a4 Stage: OPEN SecurityDescriptor: 005950e8 Name: Example_2_1_1.exe Assembly: 005e3ab8 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll] ClassLoader: 005e3b80 SecurityDescriptor: 005e3a20 Module Name 7b841000 C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Assembly: 005eb3c8 [D:\markdown\dreams\v_debug\2.【第二章】CLR和Windows加载器及引用程序域介绍\Example\Example_2_1_1\bin\Debug\Example_2_1_1.exe] ClassLoader: 005eb2b8 SecurityDescriptor: 005eb1b0 Module Name 021d4044 D:\markdown\dreams\v_debug\2.【第二章】CLR和Windows加载器及引用程序域介绍\Example\Example_2_1_1\bin\Debug\Example_2_1_1.exe
|