Archive: Can somebody explain me how I can use upx


Can somebody explain me how I can use upx
Now I have bat file with next context:


del Weight.exe
upx --best --crp-ms=999999 --nrv2d -o Weight.exe WareHouse.exe
pause

I've read the manual, but I don't understand.
Can you explain me, what I have to write instead "$%TEMP%\exehead.tmp" that this commands will be identical?

!packhdr "$%TEMP%\exehead.tmp" '"C:\Program Files\UPX\upx.exe" "$%TEMP%\exehead.tmp"'

Manual says:
[skip]
Specify a temporary file name (such as "temp.dat") and a command line (such as "C:\program files\upx\upx -9 temp.dat") to compress the header.

Russian:
Укажите имя временного файла (такое как "temp.dat") и команду (например, "C:\program files\upx\upx -9 temp.dat")

The temporary name could be any file name (maybe there are some restrictions), you can use the same name as in example (i.e. "temp.dat").
(Имя временного файла может быть любым (возможно есть какие-то ограничения), Вы можете использовать такое же имя как и в примере ("temp.dat"))


I understand this, but where should I write the executable name?
Am I wrong that upx only pack the executables?


You should not write executable name (except for OutFile attribute).
As I wrote, you should write name for temporary file, wich will be compressed. And then (in the second parameter) that name is used at command line.
UPX compresses files in several executable formats. Extensions of this files are only used by OS, UPX determines file format by it's header.


But when I pack the executable with first script (before compiling nsi-script) installer size is smaller in 15-20%. Why?


I suppose it's because UPX packs whole executable, not only header (as it described in manual).


This code is more efficient for me


!define UPXParams '"upx --best --crp-ms=999999 --nrv2d -o ${OutputEXEName} ${InputEXEName}"'
!system ${UPXParams}

installer size 1.57 MB
then this

!packhdr "$%TEMP%\exehead.tmp" '"upx --best --crp-ms=999999 --nrv2d" "$%TEMP%\exehead.tmp"'

installer size 1.89 MB

What exactly are you trying to compress? The first piece of code doesn't compress the installer itself. You can't compress the installer before it's created. Even more, you can't use UPX to compress the complete installer because it'll fail the CRC check. The data after the header/stub is compressed anyway.

What's this ${InputEXEName}? Is it the executable you're distributing? If that's the case, the second piece of code won't change it because it compresses the installer header and not the files the installer extracts.

If you want to compress the distributed executable, the first piece of code is the way to go. However, know that your installer might be bigger because compressing compressed data doesn't usually give the best results.


Originally posted by kichik

What's this ${InputEXEName}? Is it the executable you're distributing? If that's the case, the second piece of code won't change it because it compresses the installer header and not the files the installer extracts.
Yes, this is that I wanted to know.
By the way, if I choose another compressor the first part of code executed every time. How could I change this? Only via version compare?

The first piece of code will be executed every time, no matter which compressor you use. !system is only conditioned by !if[def]. !system is executed when you build the installer.

What exactly are you trying to do? What versions do you wish to compare? Do you want to compress the executable only if it's of a certain version? Why not compress it every time?


Originally posted by kichik
Why not compress it every time? [/B]
Is there any reason to do it?
e.g. I set "Best Compressor" and every time when installer compressing more and more he will be pack with !system every time!
I think this solution is will be good for me...:

section PackExecutable

${GetFileVersion} ${OutputEXEName} $0
${GetFileVersion} ${InputExeName} $1

${VersionCompare} $0 $1 $2

${If} $2 == 2
!delfile ${OutputEXEName}
!system ${UPXParams}
${EndIf}

SectionEnd

... if !delfile don't give compilation error when file isn't exists!

That won't work because GetFileVersion and VersionCompare are run time instructions. Variables such as $2 are also usable only at run time.

-Stu


Originally posted by Afrow UK
That won't work because GetFileVersion and VersionCompare are run time instructions. Variables such as $2 are also usable only at run time.

-Stu
So, what you advice?

Going back to what Kichik already pointed out:

From Kichik:

You can't compress the installer before it's created. Even more, you can't use UPX to compress the complete installer because it'll fail the CRC check. The data after the header/stub is compressed anyway.
In other words, UPX can only compress the exe header not the full EXE when used from within your script. And, if you try to compress the full EXE after it's created, then you'll run into CRC errors when you try to run it.

In my opinion, the savings you'd gain with UPX (or any other EXE compressor) would be minimal at best, which makes me wonder why you'd even want to bother. (Consider this: A barebones do nothing script compiled with NSIS compiles to about 34K. 34K is tiny!)

So my advice would be that if you want to compress the full EXE, then just specify the compression method as solid lzma in your script. (command: SetCompressor /SOLID lzma) You won't get much better compression than that. (If you do, it will be very minimal at best.)