#1(原始)---- UPX Pack ---->#2(打包)
#2(打包)- ---- UPX开箱---->#3(开箱)
#3(开箱)----- UPX Pack ----->#4(开箱) >
#4(重新包装)----- UPX打开包装---->#3(未包装)
其中#1,#2,#3和#4都有不同的哈希值。
#1 楼
如果您比较原始/解压缩文件的哈希值,则它们会有所不同,因为upx -d
不会逐位还原原始文件。实际上,UPX
解析原始文件并仅保留信息,以便打包后的数据在解压缩后可以与原始数据完全相同地执行,即原始/解压缩的文件在语义上是等效的,但在物理上是等效的^^。 /> 这是可以理解的,因为存在不影响二进制文件执行的信息,因此琐碎的实例是DOS存根的末尾与PE头的开头之间的数据。有关更多详细信息,您可以参考该类的函数
pack
,例如,用于PE的PackW32Pe
(在p_w32pe.h/cpp
中)和类unpack
(在Packer
中)的函数。可以看到packer.h/cpp
使用以下代码修改了解压缩文件的(DOS和PE)标头(为了更易于理解,我已重命名了一些变量)。首先,它解压缩并提取标头:// decompress
decompress(input_buffer, output_buffer);
upx_byte *extrainfo = output_buffer + get_le32(output_buffer + ph.u_len - 4);
memcpy(&output_header, extrainfo, sizeof (output_header));
,然后略微修改标头:
评论
但是,为什么两次打包和拆包仍然会导致文件不同?在第一轮/包装拆箱过程中保留了什么,第二轮移除了什么?
–Viktor
16-3-21在18:51
@Viktor,第一次打包和解压缩后,诸如导入表之类的东西将被重建而不是还原。此更改导致下一次打包将文件打包的方式有所不同,从而导致在拆包后重新构建表的方式有所不同。
–彼得·弗里
16-3-23在20:12
评论
我可能不明白您的问题,但是AFAIK如果我们用upx -d解包,那么我们将收到与打包前相同的二进制文件(因为此过程不依赖于打包二进制文件中嵌入的解压缩存根)?否则,如果我们让存根解压缩二进制文件,那么接收到的二进制文件就不同(我们需要修复IAT和OEP,或者存根不是标准的,那么它可以修改打包的数据)请参阅我对原始问题的编辑。我打算在评论中对此进行澄清,但是所有格式都被删除了。在对打包程序的功能进行任何假设之前,请执行受控测试并在每个步骤中对二进制文件进行哈希处理。
啊哈,您比较哈希值:)
您是否考虑过使用六角转储(对自己和对我们)可视化这四个阶段之间的差异?因为可以做很多事情来在语义上(在一定范围内)产生相同的二进制数,但是该二进制数与另一个二进制数不同。根据使用的链接器,在不同时间生成的两个文件也会产生不同的二进制文件(并因此产生哈希值)。
是的,我使用vbindiff确认二进制文件中存在差异。我还使用CFFExplorer来查看一些差异,例如对导入进行重新排序。这些文件不仅具有不同的时间戳-可执行文件中有不同的部分,并且导入的顺序也不同。