C++ 使用 UPX 压缩 Windows 可执行文件有什么缺点吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/353634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:51:24  来源:igfitidea点击:

Are there any downsides to using UPX to compress a Windows executable?

c++delphiwinapicompressionupx

提问by Mick

I've used UPXbefore to reduce the size of my Windows executables, but I must admit that I am naive to any negative side effects this could have. What's the downside to all of this packing/unpacking?

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

Are there scenarios in which anyone would recommend NOT UPX-ing an executable (e.g. when writing a DLL, Windows Service, or when targeting Vista or Win7)? I write most of my code in Delphi, but I've used UPX to compress C/C++ executables as well.

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

On a side note, I'm notrunning UPX in some attempt to protect my exe from disassemblers, only to reduce the size of the executable and prevent cursory tampering.

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

回答by Lars Truijens

The reason is there are downsides to using EXE compressors. Most notably:

Upon startup of a compressed EXE/DLL, all of the code is decompressed from the disk image into memory in one pass, which can cause disk thrashing if the system is low on memory and is forced to access the swap file. In contrast, with uncompressed EXE/DLLs, the OS allocates memory for code pages on demand (i.e. when they are executed).

Multiple instances of a compressed EXE/DLL create multiple instances of the code in memory. If you have a compressed EXE that contains 1 MB of code (before compression) and the user starts 5 instances of it, approximately 4 MB of memory is wasted. Likewise, if you have a DLL that is 1 MB and it is used by 5 running applications, approximately 4 MB of memory is wasted. With uncompressed EXE/DLLs, code is only stored in memory once and is shared between instances.

原因是使用 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

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

回答by Oliver Giesen

I'm surprised this hasn't been mentioned yet but using UPX-packed executables also increases the risk of producing false-positives from heuristic anti-virus software because statistically a lot of malware also uses UPX.

我很惊讶尚未提及这一点,但使用 UPX 打包的可执行文件也会增加启发式防病毒软件产生误报的风险,因为统计上很多恶意软件也使用 UPX。

回答by user45336

There are three drawbacks:

有以下三个缺点:

  1. The whole code will be fully uncompressed in virtual memory, while in a regular EXE or DLL, only the code actually used is loaded in memory. This is especially relevant if only a small portion of the code in your EXE/DLL is used at each run.
  2. If there are multiple instances of your DLL and EXE running, their code can't be shared across the instances, so you'll be using more memory.
  3. If your EXE/DLL is already in cache, or on a very fast storage medium, or if the CPU you're running on is slow, you will experience reduced startup speed as decompression will still have to take place, and you won't benefit from the reduced size. This is especially true for an EXE that will be invoked multiple times repeatedly.
  1. 整个代码将在虚拟内存中完全解压缩,而在常规 EXE 或 DLL 中,只有实际使用的代码才会加载到内存中。如果每次运行时只使用 EXE/DLL 中的一小部分代码,这尤其重要。
  2. 如果您的 DLL 和 EXE 有多个实例正在运行,则它们的代码不能在这些实例之间共享,因此您将使用更多内存。
  3. 如果您的 EXE/DLL 已经在缓存中,或者在一个非常快的存储介质上,或者如果您运行的 CPU 很慢,您将遇到启动速度降低的情况,因为解压缩仍然需要进行,并且您不会受益于缩小的尺寸。对于将重复调用多次的 EXE 尤其如此。

Thus the above drawbacks are more of an issue if your EXE or DLLs contains lots of resources, but otherwise, they may not be much of a factor in practice, given the relative size of executables and available memory, unless you're talking of DLLs used by lots of executables (like system DLLs).

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

To dispell some incorrect information in other answers:

消除其他答案中的一些错误信息:

  • UPX will not affect your ability to run on DEP-protected machines.
  • UPX will not affect the ability of major anti-virus software, as they support UPX-compressed executables (as well as other executable compression formats).
  • UPX has been able to use LZMA compression for some time now (7zip's compression algorithm), use the --lzma switch.
  • UPX 不会影响您在受 DEP 保护的机器上运行的能力。
  • UPX 不会影响主要反病毒软件的能力,因为它们支持 UPX 压缩的可执行文件(以及其他可执行压缩格式)。
  • UPX 已经能够使用 LZMA 压缩一段时间了(7zip 的压缩算法),使用 --lzma 开关。

回答by Jim McKeeth

The only time size matters is during download off the Internet. If you are using UPX then you actually get worse performance than if you use 7-zip(based on my testing 7-Zip is twice as good as UPX). Then when it is actually left compressed on the target computer your performance is decreased (see Lars' answer). So UPX is not a good solution for file size. Just 7zip the whole thing.

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

As far as to prevent tampering, it is a FAILas well. UPX supports decompressing too. If someone wants to modify the EXE then they will see it is compress with UPX and then uncompress it. The percentage of possible crackers you might slow down does not justify the effort and performance loss.

至于防止篡改,它也是失败的。UPX 也支持解压。如果有人想修改 EXE,那么他们会看到它是用 UPX 压缩的,然后解压缩它。您可能减慢速度的可能破解者的百分比并不能证明付出的努力和性能损失是合理的。

A better solution would be to use binary signing or at least just a hash. A simple hash verification system is to take a hash of your binary and a secret value (usually a guid). Only your EXE knows the secret value, so when it recalculates the hash for verification it can use it again. This isn't perfect (the secret value can be retrieved). The ideal situation would be to use a certificate and a signature.

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

回答by Greg Hewgill

The final size of the executable on disk is largely irrelevant these days. Your program may load a few milliseconds faster, but once it starts running the difference is indistinguishable.

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

Some people may be more suspicious of your executable just because it is compressed with UPX. Depending on your end users, this may or may not be an important consideration.

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

回答by skamradt

If your only interest is in decreasing the size of the executables, then have you tried comparing the size of the executable with and without runtime packages? Granted you will have to also include the sizes of the packages overall along with your executable, but if you have multiple executables which use the same base packages, then your savings would be rather high.

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

Another thing to look at would be the graphics/glyphs you use in your program. You can save quite a bit of space by consolidating them to a single Timagelist included in a global data module rather than have them repeated on each form. I believe each image is stored in the form resource as hex, so that would mean that each byte takes up two bytes...you can shrink this a bit by loading the image from a RCData resource using a TResourceStream.

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

回答by skamradt

There are no drawbacks.

没有缺点。

But just FYI, there is a very common misconception regarding UPX as--

但仅供参考,关于 UPX 有一个非常普遍的误解——

resources are NOT just being compressed

资源不仅仅是被压缩

Essentially you are building a new executable that has a "loader" duty and the "real" executable, well, is being section-stripped and compressed, placed as a binary-data resource of the loader executable (regardless the types of resources were in the original executable).

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

Using reverse-engineering methods and toolseither for education purposes or otherwill show you the information regarding the "loader executable", and not variable information regarding the original executable.

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

executable uncompressed by UPX

由 UPX 解压缩的可执行文件

executable compressed by UPX

由 UPX 压缩的可执行文件

回答by TheSmurf

The last time I tried to use it on a managed assembly, it munged it so bad that the runtime refused to load it. That's the only time I can think of that you wouldn't want to use it (and, really, it's been so long since I tried that that the situation may even be better now). I've used it extensively in the past on all types of unmanaged binaries, and never had an issue.

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

回答by TheSmurf

IMHO routinely UPXing is pointless, but the reasons are spelled above, mostly, memory is more expensive than disk.

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

Erik: the LZMA stub might be bigger. Even if the algorithm is better, it does not always be a net plus.

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

回答by TheSmurf

Virus scanners that look for 'unknown' viruses can flag UPX compressed executables as having a virus. I have been told this is because several viruses use UPX to hide themselves. I have used UPX on software and McAfee will flag the file as having a virus.

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