Estou tentando calcular o -o
valor para extrair um .AppImage
arquivo usando unsquashfs
arquiteturas/SOs estrangeiros, mas usando objdump
em vez de readelf
para tornar a solução mais compatível com SOs como o macOS.
unsquashfs
Usage:
-o BYTES, -offset BYTES
skip BYTES at start of FILESYSTEM. Optionally a suffix of K, M or G can be given to specify Kbytes, Mbytes or Gbytes respectively (default 0
bytes).
Estou seguindo a orientação desta solução , que usa readelf
para calcular o -o
valor de deslocamento. Isso funciona muito bem no Ubuntu, mas não funciona no macOS devido à indisponibilidade geral de readelf
.
No entanto, eu gostaria de usar objdump
if possible. Eu encontrei algumas perguntas que explicam como encontrar o ponto de entrada/deslocamento de um executável binário, mas não importa quais valores eu tente, não consigo encontrar uma maneira de obter o valor correto para unsquashfs
. Estou convertendo valores hexadecimais para decimais, mas nada de objdump
corresponde aos readelf
valores abaixo, mesmo usando a equação do Employed Russian ehdr->e_entry - phdr->p_vaddr + phdr->p_offset.
.
- https://stackoverflow.com/a/71367851
- https://stackoverflow.com/a/57841768
- https://stackoverflow.com/a/16019798
Por exemplo, veja o AppImage do Audacity:
https://github.com/audacity/audacity/releases/download/Audacity-3.7.1/audacity-linux-3.7.1-x64-22.04.AppImage
- Chamar
readelf -h audacity-linux-3.7.1-x64-22.04.AppImage
me dá alguns valores úteis, comoStart of section headers
,Size of section headers
,Number of section headers
. - Em seguida, usando a lógica de Martin Vyskočil
$START_OF_SECTION + $SECTION_SIZE * $SECTION_NO
, posso obter um valor correto de191680 + 64 * 32
, que é193728
. - O comando a seguir é bem-sucedido (no macOS e no Ubuntu):
unsquashfs -o 193728 audacity-linux-3.7.1-x64-22.04.AppImage squashfs-root
... mas como posso calcular esse valor de deslocamento com objdump
em vez de readelf
?
Se você ler os bytes corretos do arquivo ELF (com uma ferramenta que pode processar arquivos binários como
python
,perl
, etc...), então você não precisareadelf -h
nemobjdump
um pouco.Um arquivo ELF começa com um cabeçalho parecido com este (veja
man elf
para uma versão não modificada):nota: o
N
inuintN_t
pode ser32
ou64
.Calculando o deslocamento necessário por
unsquashfs
Para calcular,
SECTION_OFFSET + SECTION_SIZE * SECTION_NO
você tem que extraire_shoff
,e_shentsize
ee_shnum
do cabeçalho ELF. O problema é que a localização exata deles depende da bitness (32 ou 64 bits) do arquivo ELF, e a ordem dos bytes deles depende da endianness (little ou big endian).A quantidade de bits e a quantidade de endianidade de um arquivo ELF são armazenadas em:
e_ident[4]
(indexado 0): com0x01
representação para 32 bits e0x02
para 64 bits.e_ident[5]
(0-indexado): com0x01
representação para little-endian e0x02
para big-endian.Depois de ler esses dois bytes, você saberá "onde" e "como" ler
e_shoff
,e_shentsize
come_shnum
precisão.Solução Python
O
python
comando a seguir faz exatamente como descrito acima e então gerae_shoff + e_shentsize * e_shnum
:saída:
nota: funciona com Python 2 e 3 e qualquer bitness e endianness de CPU.
Solução POSIX
Como um cabeçalho ELF tem no máximo 64 bytes de comprimento, não é muito difícil traduzir esses bytes para texto e processar o resultado. Tudo isso pode ser feito com ferramentas padrão de uma forma padrão:
saída:
nota: funciona com qualquer UNIX/Linux e qualquer bitness e endianness de CPU.