确定.NET程序集是否是从同一源构建的

有没有人知道比较两个.NET程序集以确定它们是否是从“相同”源文件构建的方法? 我知道有一些差异实用程序可用,例如Reflector的插件,但我对查看GUI中的差异不感兴趣,我只是想要一种自动方式来比较二进制文件的集合,看看它们是否是从相同(或等效)的源文件。我知道多个不同的源文件可以产生相同的IL,并且意识到该过程只对IL的差异敏感,而不是原始源。 仅仅比较两个程序集的字节流的主要障碍是.NET包含一个名为“MVID”(模块版本标识符)的程序集。这似乎对每个编译都有不同的值,因此如果您构建相同的代码两次,则程序集将有所不同。 一个相关的问题是,是否有人知道如何强制MVID为每个编译相同?这将避免我们需要具有对MVID值的差异不敏感的比较过程。一致的MVID将是更可取的,因为这意味着可以使用标准校验和。 这背后的背景是,在我们被允许发布到Production之前,第三方公司负责独立审核和签署我们的版本。这包括查看源代码。他们希望独立确认我们提供的源代码与我们之前构建,测试并且当前计划部署的二进制文件相匹配。我们正在寻找一个允许它们从我们提供的源中独立构建系统的过程,并将校验和与我们测试的二进制文件的校验和进行比较。 BTW。请注意,我们正在使用持续集成,自动构建,源代码控制等。该问题与内部缺乏对源文件进入给定构建的控制无关。问题在于,第三方负责验证我们提供的来源是否与我们测试过并计划投入生产的二进制文件相同。他们不应该信任我们的任何内部系统或控件,包括构建服务器或源代码控制系统。他们所关心的只是获取与构建相关的源,自己执行构建,并验证输出是否与我们所说的部署相匹配。 比较解决方案的运行速度并不是特别重要。 谢谢     
已邀请:
使用命令行工具从IL的文本表示中过滤掉MVID和日期时间戳并不太痛苦。假设file1.exe和file2.exe是从相同的源构建的: c: temp> ildasm / all / text file1.exe | find / v“时间戳日期:”| find / v“MVID”> file1.txt c: temp> ildasm / all / text file2.exe | find / v“时间戳日期:”| find / v“MVID”> file2.txt c: temp> fc file1.txt file2.txt 比较文件file1.txt和FILE2.TXT FC:没遇到任何差异     
将类库与ILDasm v4.0.319.1进行比较时,似乎没有初始化图像库。为避免不匹配,请使用修订后的解决方案:
ildasm /all /text assembly.dll
| find /v "// Time-date stamp:"
| find /v "// MVID:"
| find /v "// Checksum:"
| find /v "// Image base:"
> assembly.dasm
入口点(图像库)实际上是可执行程序集的有趣信息,必须仔细验证。注入新的图像库是使程序完全执行其他操作的常用方法。就我而言,我正在尝试验证多线程构建的一致性,因此可以安全地跳过入口点。 关于性能的说明:我使用了为AnyCPU构建的8MB DLL,并运行了ILDasm。生成的文件大小为251MB,需要花费几分钟时间。产生的尺寸大约是32倍。     
我在.Net 4程序集上使用了Jerry Currry的解决方案,发现现在有第三个项目会因每个构建而异:校验和。在程序集中找到校验和是不是很令人惊讶?我认为在该文件中添加文件的校验和将改变校验和... 无论如何,修改后的命令是:
ildasm /all /text "assembly.dll"
| find /v "// Time-date stamp:"
| find /v "// MVID:"
| find /v "// Checksum:"
> assembly.dasm
请注意,我还通过添加斜杠稍微更改了搜索字符串,以避免无意的匹配。此命令的行应该在同一行上一起运行,拆分以便于阅读。如果文件名包含空格,则它们将需要双引号。     
根据您愿意做的工作量以及性能和/或准确性的重要性,有几种方法可以做到这一点。 Eric J.指出的一种方法是比较二进制的程序集,不包括每次编译时发生变化的部分。这个解决方案简单快捷,但可能会给你带来很多误报。一种更好的方法是使用反射向下钻取。如果性能至关重要,您可以从比较类型开始,如果匹配则转到成员定义。在检查了类型和成员定义之后,如果一切都等于那个点,你可以通过检查每个方法的实际IL来进一步检查它,通过
GetILAsByteArray
方法。即使一切都相同,但是你会发现差异,但是使用一些不同的标志或不同版本的编译器进行编译。我想说最好的解决方案是使用一个持续集成工具,用源代码控制的变更集编号标记构建(你正在使用一个,对吧?)。 相关文章     
您可以使用MonoCecil并进行一些小修改以解决问题。我做到了,你可以在这里阅读:http://groups.google.com/group/mono-cecil/browse_thread/thread/6ab42df05daa3a/49e8b3b279850f13#49e8b3b279850f13 关心弗洛里安     
您可以在此处使用Reflector Diff AddIn。     
要考虑的另一个解决方 在调试模式下编译二进制文件时,将存储源代码信息。然后你可以检查pdb是否匹配exe以及pdb行是否与源代码匹配。     

要回复问题请先登录注册