Свободные альтернативы UPX для сжатия исполняемых файлов
Ищу свободные альтернативы к UPX (Ultimate Packer for eXecutables).
Причины:
- Часть кода UPX защищена авторскими правами.
- UPX добавляет информацию об авторских правах создателей в сжатые исполняемые файлы и запрещает её удалять.
Есть ли какие-нибудь свободные альтернативы, которые, как и UPX, обеспечивают возможность запуска сжатого исполняемого файла без распаковки?
Может быть, есть способ упаковать сжатый в другой программе файл в новый исполняемый?
Ответы (2 шт):
Автор решения: eri
→ Ссылка
Для Виндовс нашел список упаковщиков PE: http://pect.atspace.com/
- ASPACK
- BAMBAM
- CRUNCH
- EXE32PACK
- EXPRESSOR
- EZIP
- FSG
- JDPACK
- MEW10
- MEW11 SE
- NEOLITE
- NsPACK
- PACKLITE
- PACKMAN
- PCSHRINKER
- PECOMPACT
- PEDIMINISHER
- PEPACK
- PEQUAKE
- PETITE
- PEX
- PKLITE32
- POLYENE
- SHRINKER32
- TELOCK
- THUNDERBOLT
- UPACK
- UPX
- WWPACK32
Автор решения: eri
→ Ссылка
Для Линукса можно упаковать готовый экзешник таким образом:
packed.c
#define _GNU_SOURCE
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <lzma.h>
#include "bin.h"
int main(int argc, char *argv[], char *envp[]) {
int fd = memfd_create(argv[0], 0);
lzma_stream strm = LZMA_STREAM_INIT;
lzma_filter filters[LZMA_FILTERS_MAX + 1];
filters[0].id = LZMA_FILTER_LZMA2;
static lzma_options_lzma opt_lzma;
filters[0].options = &opt_lzma;
lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT);
filters[1].id = LZMA_VLI_UNKNOWN;
lzma_ret ret = lzma_raw_decoder(&strm, filters);
if (ret != LZMA_OK)
return EXIT_FAILURE;
uint8_t *inbuf;
uint8_t outbuf[BUFSIZ];
strm.next_in = NULL;
strm.avail_in = BUFSIZ;
strm.next_out = outbuf;
strm.avail_out = sizeof(outbuf);
lzma_action action = LZMA_RUN;
for (ssize_t i = 0; i < bin_len; i += BUFSIZ) {
strm.next_in = &(bin[i]);
strm.avail_in = BUFSIZ;
if (i + BUFSIZ > bin_len) {
action = LZMA_FINISH;
strm.avail_in = bin_len - i;
}
do {
strm.next_out = outbuf;
strm.avail_out = sizeof(outbuf);
ret = lzma_code(&strm, action);
if ((ret != LZMA_OK) && (ret != LZMA_STREAM_END))
return EXIT_FAILURE;
else
write(fd, outbuf, (BUFSIZ - strm.avail_out));
} while (strm.avail_out == 0);
}
lzma_end(&strm);
fchmod(fd, S_IRWXU);
return fexecve(fd, argv, envp);
}
build.sh
#!/bin/bash
if [ -z "$1" ]; then
echo "Ошибка: Не хватает аргумента командной строки."
exit 1
fi
IN=$1
OUT=$(basename "$1")"_compressed"
echo -e "#include <sys/types.h>\n\nconst unsigned char bin[] = {" > bin.h
cat $IN | lzma -9 --format=raw | xxd -i >> bin.h
echo -e "};\n\nconst ssize_t bin_len = sizeof(bin) / sizeof(bin[0]);" >> bin.h
gcc ./packed.c -Os -flto -s -Wl,-s -Wl,--gc-sections -o $OUT -llzma
strip -s $OUT
Использование:
# Установка необходимых пакетов
apt install gcc liblzma-dev xxd xz-utils binutils
# Сборка сжатого исполняемого файла (например, /usr/bin/nano)
./build.sh /usr/bin/nano
# Запуск собранного файла
./nano_compressed
Исполнимый файл будет распакован в память. Имя файлу присвоено не будет и поэтому возможны проблемы с этим связанные. Замените тогда memfd_creat на tmpfile или creat.