40

我以前使用UPX来减小我的 Windows 可执行文件的大小,但我必须承认我对这可能产生的任何负面影响都很天真。所有这些打包/拆包的缺点是什么?

是否有人会建议不要对可执行文件进行 UPX 处理(例如,在编写 DLL、Windows 服务或针对 Vista 或 Win7 时)?我的大部分代码都是用 Delphi 编写的,但我也使用 UPX 来压缩 C/C++ 可执行文件。

附带说明一下,我没有运行 UPX 以试图保护我的 exe 免受反汇编程序的攻击,只是为了减小可执行文件的大小并防止粗略的篡改。

4

13 回答 13

48

原因是使用 EXE 压缩器有缺点。最为显着地:

在启动压缩的 EXE/DLL 时,所有代码都会一次性从磁盘映像解压缩到内存中,如果系统内存不足并被迫访问交换文件,这可能会导致磁盘抖动。相反,对于未压缩的 EXE/DLL,操作系统根据需要(即在执行它们时)为代码页分配内存。

压缩 EXE/DLL 的多个实例在内存中创建代码的多个实例。如果您有一个包含 1 MB 代码(压缩前)的压缩 EXE,并且用户启动了 5 个它的实例,则浪费了大约 4 MB 的内存。同样,如果您有一个 1 MB 的 DLL,并且它被 5 个正在运行的应用程序使用,那么大约会浪费 4 MB 的内存。使用未压缩的 EXE/DLL,代码仅在内存中存储一​​次,并在实例之间共享。

http://www.jrsoftware.org/striprlc.php#execomp

于 2008-12-09T18:11:41.623 回答
22

我很惊讶这还没有被提及,但是使用 UPX 打包的可执行文件也会增加启发式防病毒软件产生误报的风险,因为从统计数据来看,很多恶意软件也使用 UPX。

于 2008-12-10T10:04:54.663 回答
14

有三个缺点:

  1. 整个代码将在虚拟内存中完全解压缩,而在常规 EXE 或 DLL 中,仅将实际使用的代码加载到内存中。如果每次运行时只使用 EXE/DLL 中的一小部分代码,这一点尤其重要。
  2. 如果您的 DLL 和 EXE 有多个实例在运行,则它们的代码无法在这些实例之间共享,因此您将使用更多内存。
  3. 如果您的 EXE/DLL 已经在缓存中,或者在非常快的存储介质上,或者如果您正在运行的 CPU 很慢,您将体验到启动速度降低,因为仍然必须进行解压缩,并且您不会受益于缩小的尺寸。对于将被重复调用多次的 EXE 尤其如此。

因此,如果您的 EXE 或 DLL 包含大量资源,则上述缺点会成为一个更大的问题,但除此之外,考虑到可执行文件的相对大小和可用内存,除非您在谈论 DLL,否则它们在实践中可能不是一个重要因素许多可执行文件(如系统 DLL)使用。

要消除其他答案中的一些不正确信息:

  • UPX 不会影响您在受 DEP 保护的机器上运行的能力。
  • UPX 不会影响主流杀毒软件的能力,因为它们支持 UPX 压缩的可执行文件(以及其他可执行压缩格式)。
  • UPX 已经能够使用 LZMA 压缩有一段时间了(7zip 的压缩算法),使用 --lzma 开关。
于 2008-12-11T13:22:17.447 回答
10

唯一重要的时间大小是在从 Internet 下载期间。如果您使用的是 UPX,那么您实际上会获得比使用7-zip更差的性能(根据我的测试,7-Zip 的性能是 UPX 的两倍)。然后,当它实际上在目标计算机上被压缩时,您的性能就会降低(请参阅 Lars 的回答)。所以UPX不是文件大小的好解决方案。只需 7zip 即可。

就防止篡改而言,它也是失败的。UPX 也支持解压缩。如果有人想修改 EXE,他们会看到它是用 UPX 压缩的,然后解压缩。您可能放慢速度的可能破解程序的百分比并不能证明努力和性能损失是合理的。

更好的解决方案是使用二进制签名或至少只是一个哈希。一个简单的哈希验证系统是获取二进制文件的哈希值和一个秘密值(通常是一个 guid)。只有您的 EXE 知道秘密值,因此当它重新计算哈希以进行验证时,它可以再次使用它。这并不完美(可以检索秘密值)。理想的情况是使用证书和签名。

于 2008-12-09T18:39:38.227 回答
5

如今,磁盘上可执行文件的最终大小在很大程度上无关紧要。您的程序加载速度可能会快几毫秒,但一旦开始运行,差异就无法区分了。

有些人可能对您的可执行文件更加怀疑,因为它是用 UPX 压缩的。根据您的最终用户,这可能是也可能不是重要的考虑因素。

于 2008-12-09T18:05:52.553 回答
2

上次我尝试在托管程序集上使用它时,它的表现非常糟糕,以至于运行时拒绝加载它。这是我唯一一次想到你不想使用它(而且,真的,我已经很久没有尝试过了,现在情况可能会更好)。我过去曾在所有类型的非托管二进制文件中广泛使用它,并且从未遇到过问题。

于 2008-12-09T18:00:26.310 回答
2

如果您唯一感兴趣的是减小可执行文件的大小,那么您是否尝试过比较带有和不带有运行时包的可执行文件的大小?当然,您还必须包括整个包的大小以及您的可执行文件,但如果您有多个使用相同基本包的可执行文件,那么您的节省会相当高。

要查看的另一件事是您在程序中使用的图形/字形。您可以通过将它们合并到包含在全局数据模块中的单个 Timagelist 中来节省相当多的空间,而不是在每个表单上重复它们。我相信每个图像都以十六进制形式存储在表单资源中,因此这意味着每个字节占用两个字节......您可以通过使用 TResourceStream 从 RCData 资源加载图像来缩小这一点。

于 2008-12-09T21:32:35.600 回答
2

没有缺点。

但仅供参考,对于 UPX 存在一个非常普遍的误解,即——

资源不只是被压缩

本质上,您正在构建一个具有“加载器”职责的新可执行文件,并且“真正的”可执行文件正在被分段和压缩,放置为加载器可执行文件的二进制数据资源(无论资源类型在原始可执行文件)。

出于教育目的或其他目的使用逆向工程方法和工具将向您显示有关“加载程序可执行文件”的信息,而不是有关原始可执行文件的可变信息。

由 UPX 解压缩的可执行文件

由UPX压缩的可执行文件

于 2015-10-21T18:24:16.803 回答
1

恕我直言,常规的 UPXing 是没有意义的,但原因如上所述,主要是内存比磁盘贵。

Erik:LZMA 存根可能更大。即使算法更好,也并不总是净加成。

于 2009-04-25T22:32:21.940 回答
1

寻找“未知”病毒的病毒扫描程序可以将 UPX 压缩的可执行文件标记为有病毒。有人告诉我这是因为一些病毒使用 UPX 来隐藏自己。我在软件上使用了 UPX,McAfee 会将文件标记为病毒。

于 2009-05-02T00:47:14.437 回答
1

UPX 有这么多误报的原因是它的开放许可允许恶意软件作者使用和修改它而不受惩罚。当然,这个问题是行业固有的,但遗憾的是,伟大的 UPX 项目被这个问题所困扰。

更新:请注意,随着 Taggant 项目的完成,假设 UPX 支持它,使用 UPX(或其他任何东西)而不会导致误报的能力将得到增强。

于 2010-09-26T16:34:14.673 回答
0

我相信它可能无法在打开了DEP(数据执行保护)的计算机上运行。

于 2008-12-09T18:48:26.057 回答
0

当 Windows 加载二进制文件时,它所做的第一件事称为导入/导出表解析。即,无论导入表中指示的 API 和 DLL 是什么,它都会首先将 DLL 加载到随机生成的基地址中。并且在 DLL 的函数中使用基地址加上偏移量,这些信息将被更新到 Import Table。

EXE 没有导出表。

所有这些甚至在跳转到原始入口点执行之前就发生了。

然后在它从入口点开始执行之后,EXE 会在开始解压算法之前运行一小段代码。这段小代码也意味着所需的 Windows API 将非常小,导致导入表很小。

但是在解压二进制文件后,如果它开始使用之前未解析的任何 Windows API,那么它很可能会崩溃。因此,解压缩例程必须在执行解压缩代码之前解析和更新解压缩代码中所有引用的 Window API 的导入表。

参考:

在此处输入图像描述

https://malwaretips.com/threads/malware-analysis-2-pe-imports-static-analysis.62135/

于 2020-04-22T16:17:56.917 回答