如果我使用UPX打包可执行文件,然后使用UPX -d解压缩可执行文件,则可执行文件并不相同。我了解解压缩使用UPX打包的可执行文件的技术,但我想知道-打包/解压缩过程中的可执行文件会发生什么?这如何影响可执行文件中信息的保存? (例如,如果我编译C代码然后反编译它,那么我将丢失很多变量名信息。)相同。状态机如下所示:

#1(原始)---- UPX Pack ---->#2(打包)

#2(打包)- ---- UPX开箱---->#3(开箱)

#3(开箱)----- UPX Pack ----->#4(开箱) >
#4(重新包装)----- UPX打开包装---->#3(未包装)

其中#1,#2,#3和#4都有不同的哈希值。

评论

我可能不明白您的问题,但是AFAIK如果我们用upx -d解包,那么我们将收到与打包前相同的二进制文件(因为此过程不依赖于打包二进制文件中嵌入的解压缩存根)?否则,如果我们让存根解压缩二进制文件,那么接收到的二进制文件就不同(我们需要修复IAT和OEP,或者存根不是标准的,那么它可以修改打包的数据)

请参阅我对原始问题的编辑。我打算在评论中对此进行澄清,但是所有格式都被删除了。在对打包程序的功能进行任何假设之前,请执行受控测试并在每个步骤中对二进制文件进行哈希处理。

啊哈,您比较哈希值:)

您是否考虑过使用六角转储(对自己和对我们)可视化这四个阶段之间的差异?因为可以做很多事情来在语义上(在一定范围内)产生相同的二进制数,但是该二进制数与另一个二进制数不同。根据使用的链接器,在不同时间生成的两个文件也会产生不同的二进制文件(并因此产生哈希值)。

是的,我使用vbindiff确认二进制文件中存在差异。我还使用CFFExplorer来查看一些差异,例如对导入进行重新排序。这些文件不仅具有不同的时间戳-可执行文件中有不同的部分,并且导入的顺序也不同。

#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