Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
DotDumper — 一个针对 DotNet Framework 文件的自动解包器和记录器 | Kitploit
工具/GitHubGitHub/advanced-threat-research/dotdumper
动态分析 (沙盒)内存取证逆向工程调试器取证分析恶意软件分析二进制分析
GitHubadvanced-threat-research/dotdumper

DotDumper

一个针对 DotNet Framework 文件的自动解包器和记录器

查看仓库
266312年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
DotDumper标志,一辆自卸卡车

DotDumper

一个针对 .NET Framework 二进制文件的自动解包和日志记录工具!此工具已在 Black Hat USA 2022 上发布。在 Black Hat Asia 2023 上,发布了 DotDumperGUI 和 DotDumperNative,同时发布了 DotDumper 1.1-stable 版本。这三个工具应配合使用:DotDumper 1.1-stable 需要 DotDumperNative 的 DLL 存在,而 DotDumperGUI 则作为图形用户界面,用于打开和过滤 DotDumper 运行生成的 JSON 输出。

以可靠方式自动检测和分类任何给定文件通常被视为恶意软件分析的“圣杯”。实现这一目标的过程充满挑战,因此这类系统的构建备受推崇。对于 .NET 二进制文件,我们的新开源工具 DotDumper 旨在协助其中的几个关键步骤:记录(内存中的)活动、转储感兴趣的内存段,以及从给定样本中提取特征。

目录

  • 为什么用 DotDumper?
  • 功能
    • 使用命令行界面
    • 日志记录与转储
    • 反射
    • (非)托管钩子
    • 易于扩展
  • 沙箱超时支持
  • 与已知工具的差异
  • 未来工作

为什么用 DotDumper?

简而言之,手动解包是一项繁琐的过程,占用了分析人员不成比例的时间。混淆的二进制文件进一步增加了分析人员解包给定文件所需的时间。当大规模扩展时,组织需要众多每天分析恶意软件的分析人员,很可能还需结合可扩展的沙箱。浪费的宝贵时间本可用于深入调查有趣的攻击活动或样本,以发现新的威胁,而不是处理广泛传播的普通恶意软件。毕竟,分析人员在寻找的是那少数几根“针”。

那么,DotDumper 带来了什么不同?通过 DotDumper 运行基于 .NET 的恶意软件样本,可以提供关键、上下文化和常见函数调用的日志文件,格式有三种(人类可读的纯文本、JSON 和 XML),同时还会复制有用的内存段。这样,分析人员可以快速浏览函数调用日志。此外,转储的文件可以被扫描以进行分类,从而对恶意软件样本及其包含的数据提供更多洞察。这显著缩短了分类和应急响应流程所需的时间,并释放了 SOC 分析人员和研究人员的时间,用于更复杂的分析需求。

功能

为了记录并转储上下文相关的函数调用及其结果,DotDumper 结合了反射和托管钩子,全部用纯 C# 编写。以下将重点介绍并详细说明关键功能,并附上 DotDumper 对打包的 AgentTesla 窃密样本的分析结果摘要,其哈希值如下。

哈希类型哈希值
SHA-256b7512e6b8e9517024afdecc9e97121319e7dad2539eb21a79428257401e5558d
SHA-1c10e48ee1f802f730f41f3d11ae9d7bcc649080c
MD523541daadb154f1f59119952e7232d6b

使用命令行界面

DotDumper 可通过命令行界面访问,并提供多种参数。下图显示了帮助菜单。请注意,并非所有参数都会介绍,而只介绍最常用的参数。

DotDumper 的命令行界面菜单

运行给定样本的最低要求是提供“-file”参数,并附上文件名或文件路径。如果提供的是完整路径,则直接使用该路径。如果提供的是文件名,则会检查当前工作目录以及 DotDumper 可执行文件所在的文件夹。

除非指定了目录名,否则“-log”文件夹名称默认设置为样本文件名(不含扩展名)。该文件夹位于 DotDumper 所在目录下,日志和转储文件将保存在其中。

如果是库文件,或者需要指定二进制文件中的替代入口点,则必须使用“-overrideEntry true”覆盖入口点。此外,还需使用“-fqcn My.NameSpace.MyClass”提供完全限定类名(包含命名空间)。这会告诉 DotDumper 要选择哪个类,并从该类中获取指定的函数名(通过“-functionName MyFunction”)。

如果所选函数需要参数,则必须使用“-argc”提供参数数量,以及所需的参数个数。参数类型和值需要按照“string|myValue int|9”的格式提供。注意,如果值中包含空格,则命令行界面上的参数需要用引号括起来,以确保它作为一个单独参数传递。

其他较少使用的选项,如“-raceTime”或“-deprecated”,在默认设置下是安全的,但未来可能会因 .NET Framework 的更改而需要调整。目前它们在命令行界面中公开,以便在需要时轻松进行更改,即使届时使用的是旧版 DotDumper。

日志记录与转储

日志记录和转储是 DotDumper 的两项核心功能。为尽量减少分析所需的时间,日志应能为分析人员提供上下文。为此,对于每个被记录的函数调用,DotDumper 向分析人员提供以下信息:

  • 基于函数调用者的堆栈跟踪
  • 有关调用来源的程序集对象的信息,包括名称、版本和加密哈希值
  • 父程序集(如果调用并非来自原始样本)
  • 函数参数的类型、名称和值
  • 函数返回值的类型、名称和值(如果有)
  • 与给定函数调用对应的已转储到磁盘的文件列表

注意,每个转储文件的名称为该文件的 SHA-256 哈希值。

为了说明上述内容,以下提供一段日志摘录。该摘录展示了前述 AgentTesla 样本的详细信息,其中它使用 .NET 的 Assembly.Load 函数加载了第二阶段。

被拦截的 Assembly.Load(byte[] rawAssembly) 函数调用的日志

首先,给出本地系统时间,以及原始函数的返回类型、名称和参数。其次,给出堆栈跟踪,显示样本的 main 函数指向一个构造函数,初始化组件,并调用了两个自定义函数。Assembly.Load 函数是从“NavigationLib.TaskEightBestOil.GGGGGGGGGGGGGGGGGGGG(String str)”中调用的。这为分析人员提供了上下文,以便在需要时找到围绕此调用的代码。

然后,给出程序集调用顺序的信息。加载的阶段越多,就越难看出调用是通过哪些阶段产生的。通常,一个阶段会加载下一个阶段,但在某些情况下,后面的阶段会以非线性的方式使用前面的阶段。此外,还提供了原始程序集的信息,以进一步丰富分析人员的数据。

接下来,给出父哈希值。一个阶段的父阶段是前一个阶段,在此示例中尚未出现。新加载的阶段将以此阶段作为父阶段。这有助于分析人员更轻松地关联事件。

最后,存储函数的返回类型和返回值,以及传递给挂钩函数的每个参数的类型、名称和值。如果任何变量大小超过 100 字节,则将其存储到磁盘中。然后在日志中插入一个引用,指向该文件,而不是显示值。设置此阈值是为了避免日志打印时出现卡顿,因为某些数组可能有数千个索引。

反射

根据微软的文档,反射的最佳概括是“……提供封装程序集、模块和类型的对象”。简而言之,这允许动态创建和调用恶意软件样本中的 .NET 类和函数。DotDumper 包含一个反射加载器,使分析人员能够加载和分析可执行文件和库,只要它们是基于 .NET Framework 的。

要使用该加载器,必须选择在命令行界面中覆盖入口点,并指定类(包括其所在命名空间)以及给定文件中的函数名。可选地,可以为指定函数提供参数,支持所有原生类型及其数组。原生类型的示例包括 int、string、char,以及数组如 int[]、string[]、char[]。所有参数都通过命令行界面提供,需要同时指定类型和值。

如果不覆盖入口点,则使用默认入口点。默认情况下,会向样本的 main 函数传递一个空字符串数组,就像样本不带参数执行一样。

此外,加载器经常使用反射来调用下一阶段中给定类中的某个函数。有时,还会传递参数,这些参数随后用于解密资源。在上述 AgentTesla 样本中,就出现了这种情况。DotDumper 的与调用相关的钩子会记录这些事件,如下所示。

被拦截的调用第二阶段的钩子

第一行中的函数名并非 .NET Framework 的内部函数,而是对第二阶段中某个特定函数的调用。函数签名中列出了三个参数的类型和名称。它们的值可以在函数参数信息部分找到。这使得分析人员可以使用给定参数值在自定义加载器中加载第二阶段,甚至可以使用 DotDumper 通过加载先前转储的阶段并提供参数来实现。

(非)托管钩子

在介绍托管钩子之前,需要了解钩子的工作原理。这里有两个主要变量:目标函数和一个受控函数(称为钩子)。简单来说,目标函数(即 Assembly.Load)所在的内存被修改,改为跳转到钩子。这样一来,程序的执行流程就被改变了。钩子可以执行任意操作,并可选择调用原始函数,之后将执行返回给调用者,并在需要时传递返回值。下图说明了这一过程。

钩子安装和使用的流程图

了解什么是钩子对于理解托管钩子至关重要。托管代码在虚拟且受管理的环境中执行,例如 .NET 运行时或 Java 虚拟机。获取托管函数所在的内存地址与 C 等非托管语言不同。一旦正确获取了两个函数的地址,就可以通过使用 unsafe C# 直接访问内存,并结合 .NET 的互操作性服务调用原生 Windows API 功能来设置钩子。

自 DotDumper v1.1-stable 起,DotDumper 还可以挂钩非托管(或称为原生)函数。函数重定向可以是托管函数与非托管函数之间的任意组合,但有一个重要限制:任何使用托管钩子的非托管函数将无法正确读取堆栈上的值。因此,需要一个原生组件(称为 DotDumperNative)。该组件通过命名管道与 DotDumper 本身通信,从而使用其集中式日志系统,同时拦截非托管调用并能够访问堆栈上的函数参数。

易于扩展

由于 DotDumper 是用纯 C# 编写的,没有任何外部依赖,开发人员可以轻松使用 Visual Studio 扩展该框架。代码在本文档、GitHub 上以及类、函数和源代码行内都有文档说明。结合清晰的命名方案,任何人都可以根据需要修改该工具,从而最大限度地减少理解该工具所需的时间和精力。相反,它让开发人员和分析人员能够专注于改进该工具。

沙箱超时支持

虽然沙箱超时支持功能没有改动,但之前没有文档说明。由于 DotDumper 会执行给定的文件,因此执行会一直持续到样本终止。恶意软件经常进入“等待”状态,必须满足特定条件才能重新激活,或者恶意软件会通过进程注入在其他进程中继续执行。例如,在傀儡进程中创建的新线程只有在完成后才会返回。

为避免卡住,DotDumper 有一个停滞处理程序。每次记录钩子的结果时,计数器都会递增。如果该计数器在连续三个 20 秒间隔后没有变化,DotDumper 会认为遇到了停滞状态。在这种情况下,系统时间会被设置为 2200 年 12 月 30 日 12:00,以强制沙箱超时,之后它会通过日志通知分析人员并自我终止。当当前日期到新设置日期之间经过的时间超过通常的 5 或 10 分钟时,就会发生沙箱超时。即使沙箱运行时间设置为数小时或数天,也会被超时期限超过。

提前终止分析的原因是为了节省时间和资源,因为设置 10 分钟超时的提交可能实际上只需 2 分钟就能运行完毕。因此,借助停滞处理程序,可以在相同时间内运行多个样本。停滞处理程序的逻辑概述如下所示。

停滞处理程序的流程图

与已知工具的差异

在明确了 DotDumper 的目标和功能后,它似乎与已知的公开工具(如 ILSpy、dnSpyEx、de4dot 或 pe-sieve)存在重叠。请注意,本文无意宣称某个工具优于另一个,而是说明它们之间的差异。

DotDumper 的目标是记录并转储针对 .NET 样本的关键、上下文和常见函数调用。ILSpy 是一个 .NET 反汇编器和反编译器,但不允许执行文件。dnSpyEx(及其前身 dnSpy)利用 ILSpy 作为反汇编和反编译组件,同时添加了调试器。这允许手动检查和操作内存。de4dot 仅用于解混淆 .NET 二进制文件,提高代码的人类可读性。比较中的最后一个工具 pe-sieve 旨在检测和转储正在运行的进程中的恶意软件,而不考虑所使用的编程语言。下表提供了上述工具的图形化概览。

总结不同工具用途的表格

未来工作

DotDumper 处于持续的审查和开发中,所有工作主要集中在两个领域:错误修复和新功能添加。在开发过程中,代码经过了测试,但由于挂钩了可能发生变化的 .NET Framework 函数,因此代码中很可能存在错误。遇到错误的任何人都欢迎在 GitHub 仓库中提交 issue,届时会对其进行调查。也可以通过 GitHub 仓库提出新功能建议。对于有 GitHub 账号的人,或者更愿意私下沟通的人,请随时通过我的 Twitter 发送私人消息。

不用说,如果您在分析过程中使用过 DotDumper,或者以创造性的方式使用过它,欢迎在公开或私下联系我!没有什么比听到自制工具被使用更让人高兴的了!

DotDumper 还有更多的惊喜,一旦准备好,就会向社区发布更新!

下载工具