Comprimindo executáveis com o UPX

Você pode pensar em compactá-los, como nos tradicionais formatos zip, rar, tar.gz, etc. Bem, essa é uma saída temporária de armazenamento e transporte, mas para os usuários abrirem o programa, precisarão extrai-lo, o que o trará ao tamanho original de volta.

Diferentemente dessa compactação, que consiste num “empacotamento”, digamos, há a compressão de executáveis em si. Suponha que você pudesse reduzir em até 70% o tamanho do seu arquivos executáveis e bibliotecas (como as DLLs), às vezes até mais, sem nenhuma modificação no código, nem adaptações necessárias para o usuário. Ou seja, o programa ficaria menor, mas continuaria sendo executável. Ao rodá-lo, ele se auto-extrai para a memória e funciona exatamente como antes. Interessante, não?! Saiba que é possível.

Estando menores, os arquivos são transferidos facilmente pela web e gastam menos banda de download, geram instaladores menores, além de ocuparem menos espaço em geral nas mídias de armazenamento.

Os responsáveis por essa tarefa são os compressores de executáveis. Existem alguns comerciais, como o ASPack, ou gratuitos, como o Petite (estes dois para Windows). Porém o que mais se destaca, tanto em recursos, taxas de compressão e licença de uso é o UPX, que é gratuito e aberto, licenciado sob a GPL. É permitido o uso em aplicações comerciais, sem queixas ou reclamações por parte dos produtores. Isso é muito bom, você não precisa correr atrás de cracks para o ASPack, por exemplo. E uma outra coisa boa, é que o UPX está consolidado para várias plataformas. Ele conta com compilações próprias para Windows e Linux, e permite comprimir executáveis de várias plataformas (além de Windows e Linux), como DOS, Mac OS X, Windows CE, FreeBSD e até alguns dispositivos não-PCs, como Playstation I.

Há vantagens e desvantagens na compressão de arquivos dessa forma, estarei comentando os pontos positivos e negativos, para orientá-lo a decidir quando usar ou não a compressão de executáveis. Dada a qualidade e por ser aberto, vou falar do UPX.

Como funciona?

O UPX comprime os executáveis, ou arquivos que contenham código executável. Ele não foi projetado para comprimir imagens, apresentações em PPS ou arquivos txt. Ele comprime bem estes dados quando dentro de executáveis, mas é próprio para programas.

Comprimidos os dados do programa (incluindo código compilado e arquivos de dados, como imagens que existam no programa, textos, recursos, etc) seguindo especificações de cada plataforma e sistema suportados, ele adiciona um pequeno módulo escrito em assembler no início do arquivo. Esse módulo é responsável por extrair o conteúdo do arquivo para a memória e passar o controle a ele.

Seu programa deverá funcionar exatamente como antes, sem nenhuma intervenção do usuário. Ele permite também compactar DLLs, arquivos OCX e outros (que contenham no fundo código executável).

O UPX é extremamente rápido tanto para compactar como para extrair, de forma que praticamente não há redução no desempenho da sua aplicação. Pelo contrário, algumas vezes até melhora significativamente com executáveis grandes, que serão lidos da mídia bem mais rápido, por estarem em arquivos menores.

Para você ter uma idéia da velocidade de descompactação, em um antigo Pentium 100 Mhz ela chega a mais de 10 MB por segundo. Muitos programas têm executáveis com menos de 10 MB, já deu pra ver que o tempo de abertura praticamente não será modificado (isso que estamos falando num antiquado Pentium de 100 Mhz).

Sobre a taxa de compressão, é bem animadora. Em alguns casos beira os 70%. Seu programa ficará bem menor. Em alguns dos meus que testei, por exemplo, obtive esses resultados, com os programas finais funcionando normalmente:

arquivo
tamanho
original
tamanho
comprimido

Mep Texto 2.0 beta 8

1,94 MB

684 kb

Compil32 (Mep Installer 1.4)

876 kb

325 kb

CompilaMI.mll (DLL do Mep Installer)

182 kb

77 kb

MepRAM 2.2

420 kb

171 kb

Picasa2 (gerenciador de imagens do Google)

4,15 MB

1,37 MB

Winamp 2.8

628 kb

268 kb

Firefox (Mozilla Navegador 1.0.6)

6,32 MB

2,72 MB

WinRAR 3.40 beta

826 kb

380 kb

Alguns poucos programas apresentam problemas depois de comprimidos. Normalmente são programas que fazem verificações ou acessam a si mesmo (para leitura específica ou modificação). Acessar recursos dentro do executável normalmente não atrapalha, o próprio programa pode acessar seus recursos, mas não programas externos (já já comento isso).

Alguns programas nem rodam depois de comprimidos. Outros dão mensagens de erros de violação de acesso à memória, ou alguma coisa fica estranha. Você pode tentar usar alguns parâmetros do UPX para desativar alguns itens na compressão, muitas vezes o problema pode ser simples e ser solucionado, mesmo que o arquivo não seja comprimido ao máximo. Algumas vezes, reduzir o nível de compressão também ajuda. Nos casos em que não funcionar mesmo, então o melhor a fazer é esquecer (ou tentar usar outros compressores, mas provavelmente apresentarão os mesmos resultados).

Como usar?

Usar o UPX é fácil para o público alvo, pois ele é um programa operado via linha de comando. Isso também facilita a criação de arquivos em lotes ou scripts, comum para os programadores. Baixe a versão para a plataforma desejada em:

Uma coisa interessante é que todas as versões permitem comprimir arquivos de todas as plataformas suportadas. Ou seja, o UPX para Windows pode comprimir perfeitamente executáveis do Linux, e vice-versa (claro que o programa resultante não rodará nativamente numa plataforma que não seja a sua própria, né?!).

A sintaxe básica é chamar o UPX passando como parâmetro o nome ou caminho do arquivo desejado para compressão:

upx <arquivo>

Não é preciso se preocupar com o tipo do arquivo (executável Win32 ou Linux, DLL, OCX, etc), pois o UPX detecta automaticamente e aplica os devidos métodos.

Não se esqueça: se o caminho do arquivo tiver espaços, defina-o entre aspas no prompt de comando ou em arquivos em lote/scripts!

O nível de compressão do UPX vai de 1 a 9, sendo 1 o mais rápido (e que menos comprime) e 9 o mais lento (e que tenta comprimir mais). O padrão, caso não especificado, é o 7. Ele oferece uma ótima relação tempo/compressão, nem é recomendável mudá-lo. Veja um exemplo rodando no Windows:

index_html_m76e5c7ca

Caso você queira um backup do arquivo anterior, informe o parâmetro -k (sempre antes do nome do arquivo a ser comprimido).

Alguns parâmetros

Caso o programa comprimido não funcione, você pode tentar uma nova compressão (a partir do arquivo original!) passando alguns parâmetros, para desativar algumas coisas. Chamando o upx.exe sem parâmetros você tem a lista dos suportados. Um dos mais usados em casos de problemas é este, que infoma para não comprimir recursos (resources):

–compress-resources=0

Note que se sua aplicação possuir uma grande quantidade de imagens ou arquivos grandes embutidos, talvez o tamanho do arquivo final ao usar esse parâmetro não seja tão pequeno como você gostaria.

Uma outra dica usada para reduzir mais alguns kbytes do arquivo é remover os “relocations”, seções dos executáveis Win32/pe que que contém algumas informações digamos “inúteis” pro funcionamento do programa:

–no-reloc

Caso a compressão não seja satisfatória, você pode passar este parâmetro:

–brute

Cuidado, pois pode demorar. Ele testa várias vezes os níveis de compressão, até encontrar o nível mais adequado. Como comprime o arquivo várias vezes (descartando os resultados temporarários entre uma compressão e outra, só para ver o resultado dela), é a compressão mais lenta, e raramente apresenta grandes melhorias com relação ao padrão (nível 7).

Interfaces

Para facilitar as coisas, existem várias interfaces para o UPX, de programadores independentes. Uma delas é o simples UPX Front End (https://www.codex.com.br/software/MostraSoftware.asp?ID=73), e outra é o KebraByte, esta criada por mim:

index_html_m76df52e7

O KebraByte pode ser baixado em https://www.mephost.com/software/kebra_byte.htm.


Sobre proteção e impossibilidades de uso

Estando comprimidos, os arquivos são bem diferentes dos originais. Editores de recursos (como o Resource Hacker) não poderão acessar os recursos do programa, pois a estrutura dele será diferente. Seria como você tentar ler algo num arquivo .zip sem descomprimi-lo. Modificações com editores hexadecimais também serão frustradas, visto que você modificará dados de um arquivo compactado, e não do seu programa. Por exemplo, não dará para localizar nem substituir strings do programa comprimido. Se você alterar um byte sequer com um editor hexadecimal, pode ser que o programa nem funcione.

O próprio UPX acrescenta uma camada de proteção nesse quesito, que impede que o arquivo seja executado caso esteja corrompido (como com um vírus infiltrado, por exemplo).

Isso dá a “falsa” idéia da proteção. Realmente os arquivos ficam protegidos, a maioria dos usuários não conseguirá alterar seu programa. Mas… Existem descompactadores (sim, já inventaram de tudo!). O UPX mesmo, permite descompactar arquivos que foram comprimidos por ele. Procurando no Google pelas palavras certas, muitas vezes você encontra descompactadores para vários tipos de arquivos e compressores (alguns suspeitos, concordo). Ou seja, você até pode usar o UPX para reforçar a proteção do programa contra modificações, mas não conte só com isso, especialmente em aplicações comerciais.

Uma dica que violaria a licença do UPX (mas que já vi algumas pessoas usarem, e particularmente já usei) é substituir a string “upx” no arquivo resultante. No arquivo comprimido, o UPX insere o módulo para extração, e ele contém a palavra “upx”. Com um editor hecadecimal, você pode trocar as primeiras ocorrências de “upx” por outra coisa qualquer com 3 caracteres, assim o UPX deixará de reconhecer o arquivo e não poderá descompactá-lo. Como as posições das palavras irão variar de arquivo para arquivo, devido o tamanho e características particulares de cada um, fica bem dificultada a descompressão. Quem diz que isso é uma violação à licença são os próprios produtores, que incentivam distribuir o seu arquivo comprimido pelo UPX sem modificações após a compressão. Cabe à consciência de cada um 🙂

Nota: quando fiz com alguns arquivos, substituí as 3 primeiras ocorrências da palavra “upx”; substituindo todas, alguns programas deixavam de funcionar.

Para descompactar arquivos que foram comprimidos pelo UPX, basta dar o comando:

upx -d <arquivo>

Nem sempre o arquivo descomprimido será exatamente igual ao original. Por exemplo, se os relocations forem removidos do arquivo, eles não terão como ser “recolocados” no arquivo final.

Alguns arquivos simplesmente não têm como ser comprimidos. Normalmente são arquivos que já tiveram sua estrutura compacta por outros arquivos, ou são basicamente arquivos de dados (como um zip comprimido num sfx, um pacote auto-extraível). Arquivos que fazem verificações em si mesmos (para segurança ou para garantir a integridade dos dados), como instaladores de programas, não funcionarão depois da compressão. Se sua aplicação é instalável, comprima seus arquivos antes de gerar o instalador.

Quando não usar compressores de executáveis

Toda essa “maravilha” não é recomendável em alguns casos. Estando compactados dessa forma, os segmentos comuns dos arquivos ou DLLs não serão compartilhados usando recursos do sistema operacional. Se seu programa é muito grande, ou tem como objetivo que o usuário mantenha uma ou duas instâncias dele (mesmo pequeno), tudo bem, é bom utilizar a compressão. Mas se for um programa que exija várias instâncias, fica complicado, pois cada uma ocupará na memória RAM o espaço completo referente ao tamanho dos dados do programa. Traduzindo, quando várias instâcias de um programa não comprimido são carregadas, o sistema operacional compartilha o espaço de memória dos dados comuns dos programas, como funções, recursos, etc. Estando comprimidos, se forem abertas várias instâncias, estes pontos comuns não serão compartilhados, o que consumirá mais memória. Como dito e como você mesmo pode concluir, para a maioria dos programas, até vale a compressão, mas vale ficar atento a este caso.

Lembre-se também que você não pode sair modificando quaisquer arquivos de terceiros. Apesar de funcionar para programas já instalados para uso pessoal (eu, por exemplo, compacto com o UPX o Fireworks.exe, para abri-lo mais rápido), você não pode redistribuir arquivos comprimidos que não sejam seus, ou pelo menos que não sejam livres.

Bom trabalho!

Postado por
Siga em:
Compartilhe
Deixe seu comentário
Assine nossa Newsletter
Assine nossa newsletter e receba nossa seleção de conteúdo sobre tecnologia, games, IA e internet em seu email.
Veja também
Publicações Relacionadas
Img de rastreio
Localize algo no site!