我怎么知道“组装”是否确实改变了?

时间:2010-07-23 08:25:33

标签: c# comparison file-comparison

我在VS2005中创建了一个简单的“Hello World”应用程序。这是一个直接的控制台应用程序;它只包含以下几行:

Console.WriteLine("Hello World");
Console.ReadLine();

当我尝试重建相同的控制台应用程序而不执行任何更改(只需按下重建按钮)时,我得到一个微妙的不同可执行文件。 (我从第一个和第二个生成的可执行文件中生成了一个SHA-1哈希,它是不同的!)

为什么在没有代码更改时会有所不同?实际改变了什么?我使用十六进制编辑器进行比较,只看到几个不同的字节。

我想我的最终问题是,我怎么知道“集会”是否确实改变了? (当然不看文件版本,文件大小等)

修改

到目前为止,我们已经确定差异在于PE头(时间戳和一些调试数据)。在重新发明轮子之前,是否存在忽略PE头的“装配比较”工具?

谢谢, 伊恩

3 个答案:

答案 0 :(得分:6)

差异将是

  • PE标头中的时间戳
  • 调试数据的GUID(如果存在)

(根据您发布的其他输出,可能还有更多内容?)要查看这些内容,请在VS命令提示符下的两个程序集上运行dumpbin /all /rawdata:none

要正确地执行此操作,您必须编写一个理解这一点并忽略这些字节的比较工具 - 或者获取可执行文件的副本,清除时间戳和GUID,然后比较这些版本。或者,在紧要关头,您可以使用类似fc /b的内容作为controlfreak建议并假设如果有< 20个字节不同(4个用于时间戳,16个用于GUID)然后它可能是相同的。

你可能会使用清除时间戳的程序集 - AFAIK它只用于缓存其他DLL中的导出符号偏移量,如果你把它挂起来 - 但它可能更安全。如果你真的需要二进制相同的程序集,我建议你改变你的进程,这样你就不会进行清理构建,除非你真的需要它。

答案 1 :(得分:2)

从Visual Studio命令提示符,您可以进行更详细的比较:

  • 您可以使用dumpbin的输出比较PE标头:

    dumpbin /HEADERS assembly.dll
    
  • 或者您可以使用ildasm比较PE标头和装配中嵌入的IL代码:

    ildasm /ALL /TEXT assembly1.dll > dump1.txt
    ildasm /ALL /TEXT assembly2.dll > dump2.txt
    fc dump1.txt dump2.txt        
    

    /ALL选项将转储DOS和PE头,CLR头,程序集元数据和反汇编的IL。但是,它不包含嵌入的资源。如果您的assmembly包含嵌入资源,则可以使用/OUT选项。这将为每个嵌入式资源创建一个单独的文件,您可以使用自己喜欢的diff工具进行比较,例如:的WinMerge:

    ildasm /ALL /TEXT /OUT:folder1\dump.txt folder1\assembly.dll
    ildasm /ALL /TEXT /OUT:folder2\dump.txt folder2\assembly.dll
    

答案 2 :(得分:0)

在命令行上 fc / b< oldfile> < newfile>