如何在没有第三方.NET 库源码的情况,调试第三库代码?
大家好,我是沙漠尽头的狼。
本方首发于 Dotnet9,介绍使用 dnSpy 调试第三方.NET 库源码,行文目录:
安装 dnSpy
编写示例程序
调试示例程序
调试.NET 库原生方法
总结
1. 安装 dnSpy
dnSpy 是一款功能强大的.NET 程序反编译工具,可以对.NET 程序进行反编译,代替库文档的功能,代码丢失或者损坏可直接恢复,所以能在完全没有源码的情况下即时调试程序,甚至还能修改程序!
Github 有二进制可执行程序下载地址,也有源码可以自行编译,本文使用前者,Github 地址是:https://github.com/dnSpy/dnSpy
2. 编写示例程序
示例为一个桌面程序,输入数字,右侧回显输入的数字是奇数还是偶数:
示例代码比较简单,界面绑定和 ViewModel 关系截图看完所有:
奇偶判断由类 TestTool 的 TellMeOddEven 方法返回,再回看回显,咦,0 是奇数?1 是偶数?
TestTool 类是其他库定义,我假装你没有源码哈,虽然你有:
类具体定义如下:
3. 调试示例程序
打开 dnSpy,将主程序引用的 TestDll 拖入:
可以看到反编译后的代码:
反编译出来的方法定义会和第三方源码可能不同,以下是一些可能导致不同反编译结果的因素:
编译器优化:不同版本的编译器可能会对代码进行不同的优化,例如使用不同的算法、数据结构或者代码重排等。这些优化可能会导致反编译出来的代码结构和顺序不同,本文示例使用 .NET 8 开发,.NET Framework 编译的库可能反编译出来与源码几乎一致。
反编译工具更新:dnSpy 本身也会不断更新,以适应新的.NET 版本和编译器特性。这些更新可能会改变反编译算法和策略,从而导致不同版本的 dnSpy 反编译结果不一致。
代码简单,对比源码和反编译的代码查看,对整型入参除 2 取余,如果等于 1 判断为偶数,否则为奇数,当然这是错的,假如代码逻辑复杂,可以用 dnSpy 调试。
运行测试程序,并在 dnSpy 中给方法打断点,在调试菜单附加测试程序,就和 VS 中操作类似:
4. 调试.NET 库方法
上面调试示例程序的方法可用于其他第三方.NET 库,那么.NET 自身库方法呢?
方法类似,找到.NET 库对应类、对应方法,运行目标程序,然后打断点。.NET 库方法这样找:点击【文件】》【从 GAC 打开】=》搜索目标库,双击库,再查找目标方法,后面调试步骤就是一样了:
5. 总结
技术交流加群请添加站长微信号:dotnet9com
文中示例代码:MultiVersionLibrary
dnSpy 很强大的,还能直接监视第三方代码的变量、修改值等,就和你使用 VS 开发自己的程序一样,了解更多用法还请查看文章开头给的链接https://github.com/dnSpy/dnSpy, 这篇大佬的文章也不错,建议看看:《神器如 dnSpy,无需源码也能修改 .NET 程序》。
对了,示例程序中奇偶数判断不对,我又没代码我想纠正怎么办?
解决这个问题,上面大佬的文章您可以拜读了,下一篇站长继续讲解第三方库拦截,能实现不修改第三方库达到修改方法逻辑和返回结果的效果,可以提前预习快学会这个技能-.NET API 拦截技法,当然下一篇会有新知识点:非公有类非公有方法拦截技法。
以原仓库两张 dnSpy 调试第三方库的动图结束本文:
版权声明: 本文为 InfoQ 作者【沙漠尽头的狼】的原创文章。
原文链接:【http://xie.infoq.cn/article/a723fb4daa1fb18b8879771d5】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论