2012-05-08 20 views
8

In primo luogo, ho già googled ma trova solo esempi in cui un file compresso (diciamo un .tar.gz) è incorporato in uno script di shell.Incorporare un binario eseguibile in uno script di shell

Fondamentalmente se si dispone di un programma C (hello.c) che stampa una stringa, ad esempio Hello World!.

posso compilare per ottenere un binario eseguibile

gcc hello.c -o hello 

Ora ho uno script di shell testEmbed.sh

Quello che sto chiedendo è se è possibile incorporare il binario (ciao) all'interno della script di shell in modo che quando ho eseguito

./testEmbed.sh 

esegue il binario per la stampa Ciao mondo!.

Chiarimento: Un'alternativa è che a comprimere l'eseguibile in un archivio e quindi estrarre quando lo script viene eseguito. Quello che sto chiedendo è se è possibile eseguire il programma senza quello.

Fino ad ora, stavo cercando il metodo here. Ma non funziona per me. Immagino che l'autore stia usando qualche altra distribuzione su un'altra architettura. Quindi, in pratica questo non ha funzionato per me. : P

Inoltre, se il flusso di lavoro per un programma C differisce da un Java jar, mi piacerebbe saperlo anche questo!

risposta

14

Sì, questo può essere fatto. In realtà è abbastanza simile nel concetto al tuo articolo collegato. Il trucco è usare uuencode per codificare il file binario in formato testo e poi attaccarlo alla fine del tuo script.

Lo script viene quindi scritto in modo tale che venga eseguito uudecode su se stessa per creare un file binario, cambiare i permessi quindi eseguirlo.

uuencode e uudecode sono stati originariamente creati per lo spostamento del contenuto binario sul precursore di Internet, che non gestiva bene le informazioni binarie. La conversione in testo significa che può essere spedito anche come script di shell. Se, per qualche motivo, la tua distribuzione si lamenta quando provi a eseguire uuencode, probabilmente significa che devi installarlo. Ad esempio, su Debian Squeeze:

sudo aptitude install sharutils 

otterrà gli eseguibili rilevanti per te. Ecco il processo che ho seguito. In primo luogo creare e compilare il programma C hello.c:

pax> cat hello.c 

#include <stdio.h> 
int main (void) { 
    printf ("Hello\n"); 
    return 0; 
} 

pax> gcc -o hello hello.c 

Poi creare uno script di shell testEmbed.sh, che sarà decodificare se stesso:

pax> cat testEmbed.sh 

#!/bin/bash 
rm -f hello 
uudecode $0 
./hello 
rm -f hello 
exit 

Il primo rm affermazione dimostra che l'eseguibile hello viene creato di nuovo da questo script, non lasciato in giro dalla tua compilation.Dal momento che è necessario il payload nel file pure, collegare l'eseguibile codificato alla fine di esso:

pax> uuencode hello hello >>testEmbed.sh 

In seguito, quando si esegue lo script testEmbed.sh, estrae l'eseguibile e lo esegue.

Il motivo per cui funziona è perché uudecode sembra per alcune linee marcatore nel suo input (begin e end) che sono messi lì da uuencode, quindi cerca solo di decodificare il programma codificato, non l'intero script:

pax> cat testEmbed.sh 

#!/bin/bash 
rm -f hello 
uudecode $0 
./hello 
rm -f hello 
exit 

begin 755 hello 
M?T5,[email protected]$!`0````````````(``P`!````$(,$"#0```#`[email protected]```````#0`(``' 
M`"@`'@`;``8````T````-(`$"#2`!`[email protected]````X`````4````$`````P```!0! 
: : : 
M:&%N9&QE`%]?1%1/4E]%3D1?7P!?7VQI8F-?8W-U7VEN:70`7U]B<W-?<W1A 
M<G0`7V5N9`!P=71S0$!'3$E"0U\R+C``7V5D871A`%]?:38X-BYG971?<&-? 
4=&AU;[email protected]`;6%I;@!?:6YI=``` 
` 
end 

ci sono altre cose probabilmente si dovrebbe preoccupare, come ad esempio la possibilità che il programma può richiedere librerie condivise che non esistono sul sistema di destinazione, ma il processo di cui sopra è fondamentalmente quello che ti serve.


Il processo per un file JAR è molto simile, tranne che il modo in cui viene eseguito è diverso. E 'ancora un singolo file, ma è necessario sostituire la riga:

./hello 

con qualcosa in grado di eseguire file JAR, come ad esempio:

java -jar hello.jar 
+2

Potrebbe anche essere una buona idea per aggiungere un 'trappola 'rm -f ciao' SIGINT' allo script di shell in modo che il file temporaneo viene ripulito nel caso del Ctrl-C il programma utente. –

+0

Sì, non dubito che ci siano un gran numero di miglioramenti che potresti fare a quel codice e che sia un buono. Non voglio complicarlo troppo perché sto solo cercando di superare il concetto. – paxdiablo

+0

Una spiegazione davvero bella. Grazie – Ankit

2

Il modo portatile per farlo è con il comando printf e ottale sfugge:

printf '\001\002\003' 

per stampare i byte 1, 2, e 3. Dato che probabilmente non si vuole scrivere che tutto a mano, il comando od -b può essere utilizzato per generare una discarica ottale del file, quindi è possibile utilizzare uno script sed per togliere la spazzatura e mettere i backslash giusti a posto.

+0

il comando per creare la stringa con i ottali è 'od. - b BINARYFILE | sed -n 's% [0-9] \ {4, \} \ \ ([0-9] \ {3 \}. * \)% \ 1% p' | perl -pe 's% ^% \\%; s% \% \\% g; s% \ n %% ') '. Questa stringa ottale creata è quella che' printf' deve avere come argomento. – erik

Problemi correlati