C sharp (.NET)
.NET
简单来说,.NET 是微软开发的一个免费、跨平台、开源的开发者平台。它不仅仅是一门语言,而是一个包含语言、运行时(Runtime)和类库的完整生态系统。
-
原材料:C#、F#、VB.NET 代码。
-
产品:可以在 Windows、Linux、macOS、iOS、Android 上运行的程序。
1. 核心架构:CLR 和 FCL
-
CLR (Common Language Runtime,公共语言运行时):
-
这是 .NET 的“虚拟机”或“引擎”。
-
作用: 它负责管理内存(Garbage Collection)、线程执行、代码安全验证、异常处理等。
-
回顾你的题目: DIE 检测出的
CLR v4.0.30319就是指这个引擎的版本。你的Matrix.exe不是直接跑在 CPU 上,而是跑在 CLR 上,由 CLR 指挥 CPU 干活。
-
-
FCL (Framework Class Library,框架类库):
-
这是一堆写好的标准代码库。
-
作用: 提供像“文件读写”、“网络通信”、“加密算法”、“数据库连接”等现成功能。
-
回顾你的题目: 你在代码里看到的
System.Console.WriteLine、System.Security.Cryptography、System.Text.StringBuilder,全是 FCL 提供的现成工具。
-
2. 运行机制:从源代码到机器码(重点)
这是逆向 .NET 程序(如 Matrix.exe)之所以容易反编译的根本原因。
传统的 C/C++ 编译是直接变成机器码(0和1),很难还原。而 .NET 的流程是:
-
源代码 (Source Code):你写的
if/else、for循环。 -
编译 (Compile):C# 编译器(Roslyn)把代码编译成 MSIL (Microsoft Intermediate Language),即微软中间语言。
-
关键点: 这就是 DIE 告诉你的
MSIL。它是半成品,包含大量元数据(Metadata),保留了类名、变量名、函数名。 -
这就是为什么你可以用 dnSpy 看到几乎完美的源码,而不用看汇编。
-
-
运行时 (Runtime):当用户双击 EXE 时,CLR 启动。
-
JIT (Just-In-Time) 编译:CLR 里的 JIT 编译器把 MSIL 实时翻译成当前电脑能听懂的本机机器码 (Native Code)。
3. .NET 的版本家族
-
**.NET Framework:
-
老牌经典,仅支持 Windows。
-
版本号通常是 v2.0, v3.5, v4.x(你的题目是 v4.5.2)。
-
系统自带,兼容性好,目前主要处于维护模式。
-
-
.NET Core / .NET 5+ / .NET 6+:
-
跨平台(Windows, Linux, Mac)。
-
高性能,模块化。
-
这是微软现在的重心。
-
-
Xamarin / Mono:
-
主要用于移动端(Android/iOS)开发(比如 Unity 游戏引擎就大量使用 Mono)。
-
如果做手游逆向,遇到的大多是基于 Mono 的 .NET 环境。
-
C# 结构(dnSpy)

1. 根节点:程序集 (Assembly)
-
位置: 树状图的最顶级节点
Matrix-Int (1.0.0.0)。 -
含义: 这是一个编译后的二进制文件(
.exe或.dll)。它是部署和版本控制的最小单元。 -
逻辑: 你要分析哪个文件,就先找到这个文件的根节点。如果有多个 DLL 依赖,这里会列出一排。
2. 第一层子节点:模块 (Module)
-
位置:
Matrix-Int.exe(紫色图标)。 -
含义: 程序集通常包含一个主模块(偶尔有多模块,但很少见)。
-
逻辑: 这一层主要包含底层的 PE 头信息 (
PE)、引用的其他库 (引用) 以及所有的代码定义。绝大多数时候,你只需要关注这一层下面的内容。
3. 第二层子节点:命名空间 (Namespace)
-
位置:
{}(花括号图标) 和Matrix_Int(金色花括号)。 -
含义: 命名空间是用来组织代码的“文件夹”。
-
{}(空命名空间): 这里的代码没有定义命名空间,通常包含一些编译器生成的底层代码,或者简单的“Hello World”级代码。 -
Matrix_Int: 这是开发者自定义的命名空间。通常,核心业务逻辑都藏在名字看起来像项目名(如Matrix_Int)的命名空间里。
-
-
逻辑: 寻找
Main方法时,优先展开那个名字最像程序本身名字的命名空间。
4. 第三层子节点:类 (Class)
-
位置:
Matrix,Program,Square(带有三色方块图标)。 -
含义: 类是代码的容器。
-
Program类: 在 C# 控制台程序(Console App)中,按照约定俗成的惯例,程序的入口点通常放在名为Program的类中。 -
Matrix/Square类: 这些通常是辅助类,定义了数据结构(如矩阵)和特定算法。
-
-
逻辑:
-
找入口?找
Program。 -
找算法?找
Matrix或Util。 -
找界面逻辑?找
Form1或MainWindow。
-
5. 第四层子节点:成员 (Member)
-
位置:
Program类下方的Main,GetSquare(紫色立方体图标)。 -
含义: 这是具体的代码块。
-
Main(string[]) : void: 这是标准的 C# 入口方法。当你双击 EXE 时,系统首先执行这里的代码。注意它的图标上有一把小锁,表示它是private(私有) 的;如果是星星,表示是protected;如果是手掌,表示是public。但在 dnSpy 中,这种权限限制对你无效,你可以随意查看。 -
GetSquare(): 这是Program类里的另一个辅助方法。
-
-
逻辑: 逆向的第一步,永远是双击
Main,从这里开始顺藤摸瓜。
总结:你的寻找逻辑
当你拿到一个新的 .NET 题目时,在 dnSpy 左侧的点击顺序应该是:
-
展开程序集 (
Matrix-Int) -> 确认加载成功。 -
展开模块 (
Matrix-Int.exe) -> 进入代码区。 -
寻找核心命名空间 (
Matrix_Int) -> 避开Microsoft或System开头的系统库。 -
定位入口类 (
Program) -> 绝大多数控制台程序的入口都在这。 -
锁定入口方法 (
Main) -> 双击它,右侧就会显示代码。 -
如果不确定入口在哪里,直接选中最顶层的 程序集节点 (
Matrix-Int (1.0.0.0)),在右侧代码区找[assembly: ...]下方,通常会有Entry Point: ...的链接,点击它就能一键跳转到Main方法,省去一层层翻找的麻烦。