【问题标题】:How can I investigate issues after obfuscation in .net?如何在 .net 中进行混淆后调查问题?
【发布时间】:2026-01-11 09:05:02
【问题描述】:

我正在尝试使用ConfuserEx 混淆一个库,但之后我的应用程序因MissingMethodException 而崩溃,堆栈跟踪指向第一次使用混淆的类和有问题的方法是被重命名的方法。我不知道在哪里找到它的调用或其他用法,所以不清楚我应该检查什么。我的猜测是在 JIT 过程中发生了异常。

只应用了重命名混淆,我有映射来反转它。

我查看了混淆模块和重命名版本的方法肯定存在。

在混淆模块上运行 PEVerify.exe 也会出现一些错误(下面仅提供一小段摘录):

[IL]: Error: [d:\1\Confused\my.dll : _YGbNngBKpRxvvy7NkSKSrcvDmJG_::_17w1GiROq6y1aWRw9wWSUGOde1C_][mdToken=0x60003cd] Method does not exist.
Method does not exist.
Method does not exist.
[IL]: Error: [d:\1\Confused\my.dll : _cdMM5QrQwL2ksRGa1UJRmJUkVTd_::.ctor][mdToken=0x60006c8][offset 0x00000002] Unable to resolve token.
[IL]: Error: [d:\1\Confused\my.dll : ClassXyz::_tGtv2dtaIMIA6LoHXu7DwMxfvlS_][mdToken=0x6000732] Method does not exist.
[IL]: Error: [d:\1\Confused\my.dll : ClassXyz::_tk0zK3VXciZeRsH2nVWBZ6jNVdE_][mdToken=0x6000733] Method does not exist.
[IL]: Error: [d:\1\Confused\my.dll : ClassXyz::_tGtv2dtaIMIA6LoHXu7DwMxfvlS_][mdToken=0x6000732] Method does not exist.
[IL]: Error: [d:\1\Confused\my.dll : ClassXyz::_tk0zK3VXciZeRsH2nVWBZ6jNVdE_][mdToken=0x6000733] Method does not exist.
[IL]: Error: [d:\1\Confused\my.dll : ClassXyz::_PkJlSB6sykBdsQ8OXX3CBVEXudk_][mdToken=0x6000735] Method does not exist.
[IL]: Error: [d:\1\Confused\my.dll : ClassXyz::_AYy29oWv1vnvKJP5Q1lcxUcQZRd_][mdToken=0x6000757] Method does not exist.

我已准备好调试混淆过程以搜索出了什么问题……但我不知道要查找什么。我如何找出代码的哪一部分正在尝试使用旧方法名称? 如何使用 PEVerify 的输出,例如mdTokens 将如何帮助我?

【问题讨论】:

  • 作为观察或其他要考虑的事情,您可能正在使用反射(通过字符串文字)来访问类型或成员,因此代码可能不“知道”重命名。
  • 不存在成员的反射通常返回null或至少抛出其他异常类型。此特定异常来自无效程序集。混淆过程中出现问题,程序集中的某些链接已损坏。

标签: .net obfuscation peverify


【解决方案1】:

只是需要耐心。首先,使用 WinDbg 启动该应用程序并让该应用程序崩溃。然后您可以看到详细的异常信息,例如调用堆栈和寄存器。在 ILSpy 等工具的帮助下,您可以准确地看到缺少哪种方法。最后分析混淆日志文件找到原始方法。

典型的解决方法是尝试从混淆中排除该方法,以查看问题是否已解决。但是可能还有其他解决方法,或者根本没有解决方案,只能修复混淆器。

我是 Obfuscar 的当前维护者,以上是我在调试 Obfuscar 问题时的个人经验。希望对你有所帮助。

【讨论】:

  • 我想我必须先学习一点 WinDbg... 现在我有来自有问题的线程的巨大堆栈跟踪,在 clr.dll 中结束 deepeep (!EEStack 的输出,因为@987654323 @ 与 VS 调试器相比没有显示任何新内容),我不知道下一步该做什么......
  • @IvanDanilov !pe -nested?
  • dropbox.com/s/dq4bqh3z8gl0vv7/windbg.log?dl=0(我已经重命名了一些类型名,否则保持不变)
【解决方案2】:

如果使用/tokens 开关运行,这些令牌可以在 ildasm 结果中看到。喜欢ildasm.exe asm.dll /out=asm.il /tokens。在这种情况下,ildasm 在每个定义和引用附近生成 MD 令牌。因此可以对 PEVerify 报告的令牌进行简单的文本搜索。

这是使用/tokens 运行时 ildasm 生成的 IL 的示例:

  .method /*060035D5*/ private hidebysig newslot virtual final 
          instance void  b() cil managed
  {
    .override [mscorlib/*23000001*/]System.IDisposable/*01000051*/::Dispose /*01000051::0A000069*/ 

请注意,ildasm 不会在标记前添加 0x(可能是为了简洁起见),因此您应该对 060006c8 进行不区分大小写的搜索,而不是 0x060006c8

【讨论】:

    【解决方案3】:

    根据我开发SeeUnsharp .NET Obfuscator 的经验,运行时出现MissingMethodException 表示您要执行的程序集在IL 代码中对成员的引用无效或缺失。 IL 代码是 .NET CLI 编译器生成的,可能包含对不需要存在的方法的引用。如果您在 C# 中执行此操作,C# 编译器会告诉您。

    PEVerify 在编译器(在本例中为混淆器)没有捕获此错误并告诉您缺少哪个方法,或者至少在哪个 IL 偏移量处有缺陷的方法调用位于哪个方法中。您可以使用ILSpy,启用元数据令牌显示并切换到IL模式,找到相关说明。来自 PEVerify 的剩余错误可能会在运行时造成麻烦,这就是为什么 SeeUnsharp 总是通过 PEVerify 运行混淆程序集以确保输出有效。

    我会说这是来自 ConfuserEx 的问题。当我在 IL 处理期间以错误的方式连接事物时,我也遇到了这些异常。当你找到了缺失方法的原件后,你可以通过某种方式检查它是否是特殊的。是虚拟的吗?是接口方法吗?是否涉及动态类型?最终,从重命名中排除该方法可能是一种解决方案。

    MSDN blogs 中还有关于此错误的更多信息。

    【讨论】:

    • 是的,这绝对是 ConfuserEx 的问题。我试图在那里找到并解决问题。但是来自 PEVerify 的消息没有说明它在哪里找到了对该方法的引用——只是没有找到什么方法。可能是引用错误(未正确重命名),而不是缺少该方法本身。问题是如何找出缺失的细节。 PEVerify 报告目标程序集不一致并且有问题……这很明显。