PDA

View Full Version : exepack by Shelwien


Simorq
18-08-2018, 20:39
exepack (https://encode.ru/threads/2989-exepack)As part of adding sfx support for my archive format, I made a standalone x64flt3/delta/plzma archiver.
Then I thought that it can be used to bundle multifile apps into a single exe file, just as well.

Loader stub unpacks app archive to a temp folder, then runs first executable there with current commandline.
Temp folder is deleted on exit.

Exepack version 1 [12.08.2018 10:04].
Copyright (c) 2018 ConeXware, Inc. All Rights Reserved.

Usage:

exepack c32|c64|w32|w64 exe-file|directory output-exe-file [startup-file]

c32 = console 32-bit stub (19456 bytes)
c64 = console 64-bit stub (22016 bytes)
c32f = console 32-bit stub (29184 bytes), speed-opt build
c64f = console 64-bit stub (31232 bytes), speed-opt build
c32z = console 32-bit stub (62976 bytes), zstd, speed-opt build
c64z = console 64-bit stub (83456 bytes), zstd, speed-opt build
w32 = GUI 32-bit stub (won't create a console window for GUI app)
w64, w32f, w64f, w32z, w64z

startup-file = .exe by default; name/suffix to run after unpacking

Examples:
exepack.exe w32 cmp.exe cmp1.exe -- pack a single GUI executable
exepack.exe c32 ..\7zdll_x32 pa32.exe 7z.exe -- pack a directory, run 7z.exe

Download (http://nishi.dreamhosters.com/u/exepack_v1.7z)

It is also a valuable tool for ISDONE:D

Golden-Mask
21-12-2018, 13:26
The decompression for the program is as follows:

int srcPos; /* start at the end of the packed exe, because the unpacker works downwards */
int dstPos;
int commandByte, lengthWord, fillByte;

/* skip all 0xff bytes (they're just padding to make the packed exe's size a multiple of 16 */
while (*srcPos == 0xff) {
srcPos--;
}

/* unpack */
do {
commandByte = *(srcPos--);

switch (commandByte & 0xFE) {
/* (byte)value (word)length (byte)0xb0 */
/* writes a run of <length> bytes with a value of <value> */
case 0xb0:
lengthWord = (*(srcPos--))*0x100;
lengthWord += *(srcPos--);
fillByte = *(srcPos--);
for (i = 0; i < lengthWord; i++) {
*(dstPos--) = fillByte;
}
break;
/* (word)length (byte)0xb2 */
/* copies the next <length> bytes */
case 0xb2:
lengthWord = (*(srcPos--))*0x100;
lengthWord += *(srcPos--);
for (i = 0; i < lengthWord; i++) {
*(dstPos--) = *(srcPos--);
}
break;
/* unknown command */
default:
printf("Unknown command %x at position %x\n", commandByte, srcPos);
exit(1);
break;
}
} while ((commandByte & 1) != 1); /* lowest bit set => last block */