dnspy在保存的时候出错

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dnspy在保存的时候出错相关的知识,希望对你有一定的参考价值。

提示:Error calculating max stack value. If the method's obfuscated, set CilBody.KeepOldMaxStack or MetadataOptions.Flags (KeepOldMaxStack, global option) to ignore this error. Otherwise fix your generated CIL code so it conforms to the ECMA standard.Instruction operand is nullInstruction is nullOperand is not a local/arg

参考技术A nity项目打包后的代码都在Assembly-CSharp.dll里,直接使用dnSpy打开即可修改,并且编译追问

不懂就别在这里装懂,谁告诉你这是unity的了?
复制别人的答案还少了个字母,你是真的菜

参考技术B 像这种情况你的.dll文件应该是加了壳,但是不影响dnspy对其进行修改保存,脱壳了之后应该就不会有这种提示了

支持 dotnet 6 的 dnSpy 神器版本

官方的 dnSpy 在 2021 时,由于某些吃瓜的原因 wtfsck 将 dnSpy 给 Archived 掉,在大佬被哄好之前,预计是不再更新。最新官方版本对 dotnet 6 的支持较弱,对于很多 dotnet 6 应用都无法成功调试,附加调试上去将会让应用卡住。好在 dnSpy 是开源的,也刚好 lsj 大佬改得动,于是改了一个支持 dotnet 6 的版本

什么是 dnSpy 神器?请看 神器如 dnSpy,无需源码也能修改 .NET 程序 - walterlv

我现在使用最多的调试工具,除了 VisualStudio 之外,就是 dnSpy 工具了。使用 dnSpy 可以让我方便调试用户端的应用。在完成了将团队里面最大的项目升级到 dotnet 6 时,就在升级过程遇到了一些问题,想要调试,却发现没有合适的工具,详细请看 dotnet 6 在 Win7 系统证书链错误导致 HttpWebRequest 内存泄露

为了让我减少加班,我请了 lsj 帮忙改改 dnSpy 神器,让 dnSpy 可以调试 dotnet 6 的应用

这是支持 dotnet 6 版本的 dnSpy 神器下载地址,也是修改之后开源的地址:https://github.com/kkwpsv/dnSpy/releases/tag/6.1.9

如果大家下载不了,可以发邮件让我用其他方式发给你

那改好了是不是就完成了?还有一个问题是为什么 dnSpy 对 dotnet 6 的支持较弱呢?有以下几个原因,对应的修复方法还请看 lsj 的改动 https://github.com/kkwpsv/dnSpy/commit/a217b257453147c5d9db45070f7555f6395329bf

如 [DAC][DBI] ICorDebugModule::GetMetaDataInterface fails in net6.0 for "Anonymously Hosted DynamicMethods Assembly" in unit test project. · Issue #62977 · dotnet/runtime 所说的原因,由于 "Anonymously Hosted DynamicMethods Assembly" 没有定义 IMetaDataImport2 接口,因此在 https://github.com/dnSpy/dnSpy/blob/2b6dcfaf602fb8ca6462b8b6237fdfc0c74ad994/Extensions/dnSpy.Debugger/dnSpy.Debugger.DotNet.CorDebug/Impl/ModuleCreator.cs#L94-L96 将拿到空,如以下代码,将抛出 InvalidOperationException 错误

var comMetadata = dnModule.CorModule.GetMetaDataInterface<IMetaDataImport2>();
            if (comMetadata is null)
                throw new InvalidOperationException();

修复的方式就是不抛出异常,而是自己定义一个 继承 DmdLazyMetadataBytes 类型的 DmdLazyMetadataBytesNull 类型,进行返回,如以下代码

if (comMetadata is null)
                // "Anonymously Hosted DynamicMethods Assembly" not implement IMetaDataImport2, we just return DmdLazyMetadataBytesNull
                return () => new DmdLazyMetadataBytesNull();

同时在 DmdAppDomainImpl.cs 里面,返回 DmdNullMetadataReader 即可,如此也许会影响读取程序集的信息,但好过无法调试

这个 "Anonymously Hosted DynamicMethods Assembly" 没有定义 IMetaDataImport2 接口,也影响 https://github.com/dnSpy/dnSpy/blob/2b6dcfaf602fb8ca6462b8b6237fdfc0c74ad994/Extensions/dnSpy.Debugger/dnSpy.Debugger.DotNet.CorDebug/dndbg/Engine/CorAssembly.cs#L56-L60 的代码,如以下代码,拿到的 ManifestModule 是空值。好在这里只是在 dnSpy 应用的 Debug 模式才会炸掉

var module = ManifestModule;
                Debug2.Assert(module is not null);

修复的方法只是将 Assert 的代码干掉即可

经过以上更改,就可以让 dnSpy 支持 dotnet 6 的调试

嗯,现在我觉得 dnSpy 作者做的还是太对了,我似乎越来越觉得开源也是一个不对的事情,那就是 SB 太多了。本来今天是想着将 dnSpy 在堆栈网上广告一下,造福一下国外的小伙伴。可惜遇到了傻比,最后我将问题和回答都删除了。这个事让我更加理解了很多开源作者最后选择了闭源的做法,以及让我更加佩服维护社区的大佬们。有人问,原作者关闭了 dnSpy 的瓜是什么?其中一个瓜就是被傻子给气的,开源了不收钱了,反而被当成理所当然,还要这要那,不满足了还被骂。具体的瓜还请自己去找了

我认为所有的参与开源和分享知识的行为都理应受到表扬称赞,共同维护一个良好的开发者生态

十分感谢 wtfsck 大佬提供的 dnSpy 神器,和 lsj 让 dnSpy 支持 dotnet 6 调试

以上是关于dnspy在保存的时候出错的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSUserDefaults 保存高分时出错

求助,aix中,能否用shell命令,每次执行的时候,自动将crontab作业前天出错的日志保存到另一个文本中

Spring的代理问题,类型转化出错

保存核心数据时出错

python,import语法出错

在CoreData中保存数据时出错