mcpField
A
analyzing-dotnet-assemblies

analyzing-dotnet-assemblies

github.com/trilwu安全17759 次安装12 周前更新
代码仓库

关于 analyzing-dotnet-assemblies

面向恶意软件分析人员及无源码 Windows 应用审查者的 .NET 程序集分析安全技能。内容涵盖反编译、混淆与加壳、运行时转储,以及恶意软件行为检查。

主要功能

  1. 01识别托管程序集和发布模式
  2. 02将程序集反编译为可读代码
  3. 03检测并处理常见混淆器
  4. 04从内存转储托管模块
  5. 05使用 dnSpyEx 调试和修补程序集

适用场景

  1. 01无源码审查 Windows 应用或服务
  2. 02分析 .NET 恶意软件加载器及其后续阶段
  3. 03恢复内存中 PowerShell 或 C# 加载器的逻辑

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/trilwu/secskills --skill analyzing-dotnet-assemblies

安装后在 Claude Code 中输入/analyzing-dotnet-assemblies确认已加载。

详细介绍

分析 .NET 程序集

.NET 会编译为带有完整元数据的 IL,因此未混淆的程序集可以反编译为接近原始代码的 C#。所以有趣的问题不是“如何读取它”,而是“有什么在阻碍”:加壳器、混淆器、运行时加载器,或是将托管代码隐藏在本机宿主中的发布模式。

适用场景

  • file 报告文件为 PE,且二进制文件包含 CLR 标头或 mscoree.dll
  • ILSpy 或 dnSpy 可以打开程序集,但名称已被篡改或方法体为空
  • 分析 .NET 恶意软件、加载器或红队工具
  • 在没有源代码的情况下审查 Windows 桌面应用或服务应用
  • 从 PowerShell 或 C# 内存加载器中恢复逻辑

不适用场景

  • Unity IL2CPP — 使用 reversing-unity-il2cpp;C# 已编译为本机代码
  • Xamarin/MAUI 移动应用 — 使用 reversing-xamarin-maui 提取容器,然后返回此处处理 DLL
  • 疑似恶意软件,尚未隔离时 — 首先使用 analyzing-malware
  • Go 或 Rust 二进制文件 — 使用对应的技能

确认它是托管代码

# Linux
file target.exe                                 # "Mono/.Net assembly"
rg -a -o 'BSJB|mscoree\.dll|System\.Private\.CoreLib' target.exe | head

# Windows
dotnet-tool: ildasm /text target.exe | head
# CLR header presence in the optional header data directory 14 is the real test
发现的内容发布模式处理方法
托管 PE,引用了 mscorlib/System.Private.CoreLib依赖框架直接反编译
包含嵌入式托管捆绑包的本机 PE单文件发布先提取捆绑包
没有任何 IL 元数据的本机 PENativeAOT不属于 .NET 逆向工程 — 使用 analyzing-binaries
没有入口点的 .dll库反编译;在其他位置查找调用方
# Single-file publish: the managed assemblies are appended as a bundle
# Extract with a bundle extractor, or carve on the manifest header
ilspycmd --list-bundle target.exe 2>/dev/null || binwalk -Me target.exe

反编译

ilspycmd target.dll -o ./decompiled -p       # -p writes a project structure
# GUI: dnSpyEx (maintained fork), ILSpy, dotPeek
# dnSpyEx also debugs and edits assemblies, which is why it is the default choice

rg -n 'https?://|ConnectionString|ApiKey|password|Convert\.FromBase64String' ./decompiled | head -40

按以下顺序阅读:入口点、以产品命名的类型,然后是引用网络、加密或进程 API 的内容。除非要跟踪特定闭包,否则跳过生成的类型(<>c__DisplayClass、<Module>)。

在处理混淆前先识别混淆器

明确混淆工具后,反混淆成本很低;不明确时,成本就很高。

detect-it-easy target.exe          # or DIE's CLI: diec
# Look for: ConfuserEx, .NET Reactor, SmartAssembly, Eazfuscator, Babel,
#           Dotfuscator, Agile.NET, Obfuscar
rg -a -o 'ConfuserEx|Reactor|SmartAssembly|Eazfuscator|Babel|DotNetPatcher' target.exe
# de4dot handles the classic obfuscators automatically
de4dot target.exe -o cleaned.exe
de4dot -p cr target.exe            # force a specific profile when detection fails
# ConfuserEx specifically: use a maintained unpacker fork, since de4dot's
# built-in support predates later ConfuserEx versions

各混淆层的表现及处理方法:

混淆层表现处理方法
名称篡改Class1.method_3、Unicode/不可见名称仅影响外观 — 阅读时重命名;de4dot 可还原部分名称
字符串加密到处都是 <Module>.Decrypt(12345)运行解密器:使用 de4dot,或动态调用该方法
控制流扁平化针对状态变量的大型 switch使用 de4dot 的 CFG 清理功能,或动态读取
代理/委托调用每次调用都通过辅助函数使用 de4dot 进行去虚拟化
防篡改/反调试在 dnSpy 调试器下运行失败修补检查,或在解密后转储
虚拟化(Agile.NET、KoiVM)完全无法识别 IL使用去虚拟化工具(KoiVM 可用 OldRod)或动态分析
本机桩代码封装 IL运行时解密托管代码从内存转储 — 这是可靠的方法

**从内存转储是通用的脱困方法。**无论使用什么加壳器,CLR 最终都必须持有真实 IL 才能执行。让它加载,然后转储:

# MegaDumper / ExtremeDumper / pe-sieve — dump loaded managed modules from a
# running process, then decompile the dump
pe-sieve /pid <pid> /dmode 3

这与加壳本机恶意软件的“让它自行解包”方法相同;运行任何可疑内容前,请参阅 analyzing-malware 了解隔离措施。

调试和修补

# dnSpyEx: set breakpoints in decompiled C#, inspect locals, edit method bodies,
# and save the modified assembly. This is unusually powerful — you can change a
# license check or a validation result and immediately re-run.

修补工作流:在 dnSpyEx 中编辑 IL 或反编译后的 C#,保存程序集,然后重新运行。保存时强名称签名会失效 — 可以移除强名称要求;如果应用会自行验证哈希,则挂钩该检查。对于应用本身会验证的签名程序集,修补通常不是合适的工具;应改为在运行时挂钩。

.NET 恶意软件笔记

.NET 被广泛用于加载器和常见 RAT,其特征很鲜明:

  • Assembly.Load(byte[]) — 在内存中解密的第二阶段。找到解密例程,离线运行并分析生成的程序集。这是最常见的 .NET 恶意软件模式。
  • Activator.CreateInstance 加反射,用于隐藏真实的调用图。
  • AmsiScanBuffer / EtwEventWrite 补丁 — 搜索字节模式,或搜索此前调用的 GetProcAddress。
  • P/Invoke 声明([DllImport])揭示原生能力: VirtualAlloc、CreateRemoteThread、SetWindowsHookEx。
  • 资源和卫星程序集中可能存放加密载荷 — 务必枚举资源节。
rg -n 'DllImport|Assembly\.Load|CreateInstance|FromBase64String|RijndaelManaged|AmsiScanBuffer' ./decompiled | head -30
ilspycmd --list-resources target.dll

提取出的第二阶段交由此技能处理;能力和 IOC 输出交给 analyzing-malware,检测内容交给 engineering-detections。

应当驳斥的理由

  • “名称毫无意义,混淆太严重了。” 名称混淆是最薄弱的一层。结构、字符串和 P/Invoke 都完好无损。
  • “de4dot 失败了,所以无法反混淆。” 找出混淆器并使用对应的专用解包器,或者从内存中转储。
  • “这是原生 EXE,所以不是 .NET。” 检查是否使用了单文件发布,以及是否存在包装托管代码的原生存根。
  • “字符串已加密。” 解密器就在程序集里。调用它。
  • “我反编译了加载器,那就是恶意软件。” 加载器只是第一阶段。找到 Assembly.Load,并还原它加载的内容。
  • “我会手动阅读扁平化的控制流。” 运行清理工具,或者在 dnSpyEx 中调试并观察实际执行路径。

参考资料

  • analyzing-malware — 遏制、能力模型和 IOC
  • analyzing-binaries — NativeAOT 和原生存根分析
  • reversing-unity-il2cpp、reversing-xamarin-maui — 其他 .NET 容器
  • engineering-detections — 将还原出的行为转化为规则
  • dnSpyEx、ILSpy/ilspycmd、de4dot、Detect It Easy、pe-sieve、OldRod

评论

支持 Markdown