UPX打包/解包信息保存

逆向工程 开箱
2021-07-06 01:09:44

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

编辑:我已经验证在 UPX 打包/重新打包后二进制文件不一样。状态机看起来像:

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

#2(已打包)-----UPX 解包----> #3(未打包)

#3(未打包)-----UPX 包-----> #4(重新打包)

#4(重新打包)-----UPX 解压----> #3(解压)

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

1个回答

如果比较原始/解压文件的哈希值,则它们是不同的,因为upx -d不会逐位还原原始文件。实际上,UPX解析原始文件并仅保留信息,以便解压后的打包数据可以与原始文件完全相同地执行,即原始/解压文件在语义上等效但在物理上不等效^^。

这是可以理解的,因为存在不影响二进制文件执行的信息,一个简单的例子是 DOS 存根结束和 PE 头开始之间的数据。更详细的可以参考pack的功能,例如PE的PackW32Pe(in p_w32pe.h/cpp)和unpack的功能Packer(in packer.h/cpp)。

例如,我们可以看到UPX使用以下代码修改了解压文件的(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));

然后稍微修改标题:

...
output_header.headersize = rvamin;
output_header.chksum = 0;

//NEW: disable reloc stripping if ASLR is enabled
if(input_header.dllflags & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE)
    opt->win32_pe.strip_relocs = false;

// FIXME: ih.flags is checked here because of a bug in UPX 0.92
if ((opt->win32_pe.strip_relocs && !isdll) || (input_header.flags & RELOCS_STRIPPED))
{
  output_header.flags |= RELOCS_STRIPPED;
  ODADDR(PEDIR_RELOC) = 0;
  ODSIZE(PEDIR_RELOC) = 0;
}

// write decompressed file
if (output_file)
{
...