riga di comando e dati binari

 :: GNU/Linux :: Altro

Andare in basso

riga di comando e dati binari

Messaggio Da floatman il Ven Mar 19, 2010 7:34 pm

Siccome non è un argomento molto dibattuto, ho deciso di creare una piccola guida sulla gestione di dati binari tramite Bash.

Le prime due domande ovvie sono
Perchè trattare dati binari su Linux?
Perchè trattarli usando Bash?

La prima domanda si riferisce al fatto che in un sistema con sorgenti disponibili il patching dovrebbe essere un'attività inesistente; però in gruppi di file già compilati dove si richiedono piccole modifiche, può risultare molto più comodo patchare l'eseguibile piuttosto che modificare i sorgenti e quindi ricompilarli.

La seconda risposta è legata alla prima. È vero che esistono linguaggi migliori per queste operazioni, però per piccole modifiche, considerando il fatto che sicuramente avrete un terminale già aperto, la comodità è notevole.
'Beh, io ad esempio non ho quasi mai il terminale aperto. Che me ne faccio se ci sono le GUI?'...questa guida non è per te, hai ancora un po' di strada da fare Razz

Prendiamo un programmino minimale di esempio.
Il minimo sarebbe sarebbe una main() con un 'return 0' ma nemmeno si vedrebbe se il programma funziona, quindi cerchiamo di esserne sicuri:

Codice:
#include <stdio.h>

int main() {
   printf ("FUNZIONO!\n");
   return 0;
}
Codice:
floatman@debian:~/bashex$ gcc example.c -o example
floatman@debian:~/bashex$ ./example
FUNZIONO!
(programmazione ad alti livelli...)

Per chi non lo sapesse, una delle caratteristica principale del formato ELF (l'eseguibile binario UNIX) è quella di essere pieno di schifezze...

Codice:
floatman@debian:~/bashex$ cat example ; echo
ELF4�4 ($!444�����������(((  Q�td/lib/ld-linux.so.2GN  �K�� .�)��__gmon_
start__l@����U��S���[���������t����X[���5��%��%�h������%�������%�h�����1
�^����PTRhhQVh�����������������U��S���=�u@����-����X�9�s���B�������9�r��
���[]Ív��'U������t���t �$����Ð�L$����q�U��Q���$��������Y]�a�ÐU��]Ít&��'U
��WVS�O�Ý���{�������������)�����t$1�E�D�E�D$��$��������9�rރ�[^_]Ë$Ð�U�
�S�������t��f����Ћ���u��[]Ð�U��S���[������lH��FUNZIONO!��������t�J����o4
���o���o*��GCC: (Debian 4.3.2-1.1) 4.3.2GCC: (Debian 4.3.2-1.1) 4.3.2GCC
: (Debian 4.3.2-1.1) 4.3.2GCC: (Debian 4.3.2-1.1) 4.3.2GCC: (Debian 4.3.
2-1.1) 4.3.2GCC: (Debian 4.3.2-1.1) 4.3.2GCC: (Debian 4.3.2-1.1) 4.3.2$�
t"l$X��!�u_IO_stdin_used���B=�in8��)��O�K'/build/buildd-glibc_2.7-18lenn
y2-i386-Vh19Av/glibc-2.7/build-tree/i386-libc/csu/crti.S/build/buildd-gl
ibc_2.7-18lenny2-i386-Vh19Av/glibc-2.7/build-tree/glibc-2.7/csuGNU AS 2.
18.0��]� /tmp/ccJ86Lx9.s/build/buildd-glibc_2.7-18lenny2-i386-Vh19Av/gli
bc-2.7/build-tree/glibc-2.7/csuGNU AS 2.18.0�%$>$$>4:;I?/build/buildd-gl
ibc_2.7-18lenny2-i386-Vh19Av/glibc-2.7/build-tree/i386-libc/csu./tmpccJ8
6Lx9.s�!!!�-!!!GNU C 4.3.2short unsigned intshort int_IO_stdin_usedlong
long unsigned int/build/buildd-glibc_2.7-18lenny2-i386-Vh19Av/glibc-2.7/
build-tree/glibc-2.7/csuunsigned charinit.clong long int����t�l��������.
symtab.strtab.shstrtab.interp.note.ABI-tag.gnu.hash.dynsym.dynstr.gnu.ve
rsion.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame.ctors
.dtors.jcr.dynamic.got.got.plt.data.bss.comment.debug_aranges.debug_pubn
ames.debug_info.debug_abbrev.debug_line.debug_str.debug_ranges#(( 5HH(1�
��opp ;��PC�JK���o**X���o44 g      pT      \ytt0t��@�|�ll��������������
������������������%���oH  D 0��+P�9l�#6      (Hp�*T� \�
                                                    ��+������tinit.cini
tfini.ccrtstuff.c__CTOR_LIST____DTOR_LIST____JCR_LIST____do_global_dtors
_auxcompleted.5706dtor_idx.5708frame_dummy__CTOR_END____FRAME_END____JCR
_END____do_global_ctors_auxexample.c_GLOBAL_OFFSET_TABLE___init_array_en
d__init_array_start_DYNAMICdata_start__libc_csu_fini_start__gmon_start__
_Jv_RegisterClasses_fp_hw_fini__libc_start_main@@GLIBC_2.0_IO_stdin_used
__data_start__dso_handle__DTOR_END____libc_csu_init__bss_start_endputs@@
GLIBC_2.0_edata__i686.get_pc_thunk.bxmain_init
floatman@debian:~/bashex$ ls -lh
totale 12K
-rwxr-xr-x 1 dante dante 6,3K 19 mar 11:58 example
-rw-r--r-- 1 dante dante  71 19 mar 10:23 example.c
Una volta, quando gli HD erano piccolissimi per i nostri standard, si usava ripulire la porcheria per risparmiare spazio.
Il comando 'strip' fortunatamente è ancora presente almeno nelle grandi distribuzioni storiche.

Codice:
floatman@debian:~/bashex$ cp example example1 && strip example1
floatman@debian:~/bashex$ cat example1 ; echo
ELF4L4 (444�����������(((  Q�td/lib/ld-linux.so.2GN  �K�� .�)��__gmon_st
art__lib@����U��S���[���������t����X[���5��%��%�h������%�������%�h�����1
�^����PTRhhQVh�����������������U��S���=�u@����-����X�9�s���B�������9�r��
���[]Ív��'U������t���t�$����Ð�L$����q�U��Q���$��������Y]�a�ÐU��]Ít&��'U�
�WVS�O�Ý���{�������������)�����t$1�E�D�E�D$��$��������9�rރ�[^_]Ë$Ð�U��
S�������t��f����Ћ���u��[]Ð�U��S���[������lH��FUNZIONO!��������t�J����o4�
��o���o*��GCC: (Debian 4.3.2-1.1) 4.3.2GCC: (Debian 4.3.2-1.1) 4.3.2GCC:
 (Debian 4.3.2-1.1) 4.3.2GCC: (Debian 4.3.2-1.1) 4.3.2GCC: (Debian 4.3.2
 -1.1) 4.3.2GCC: (Debian 4.3.2-1.1) 4.3.2GCC: (Debian 4.3.2-1.1) 4.3.2.s
 hstrtab.interp.note.ABI-tag.gnu.hash.dynsym.dynstr.gnu.version.gnu.vers
 ion_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame.ctors.dtors.jcr.dy
 namic.got.got.plt.data.bss.comment(( %HH(!���opp +��P3�J;���o**H���o44
 W      `T      \itt0d��@o�|ull{�����������������������������
floatman@debian:~/bashex$ ls -lh
totale 16K
-rwxr-xr-x 1 dante dante 6,3K 19 mar 12:05 example
-rwxr-xr-x 1 dante dante 2,9K 19 mar 12:05 example1
-rw-r--r-- 1 dante dante  71 19 mar 10:23 example.c
direi che ogni commento è superfluo, come aggiunta off-topic potremmo dire che per file di maggiori dimensioni si può anche ricorrere a UPX per ridurre ulteriormente le dimensioni (il nostro esempio è troppo piccolo).
Ad esempio proviamo con gcc, dopo averlo copiato nella nostra directory di lavoro:

Codice:
floatman@debian:~/bashex$ cp /usr/bin/gcc provagcc
floatman@debian:~/bashex$ ls -lh
totale 224K
-rwxr-xr-x 1 dante dante 6,3K 19 mar 12:05 example
-rwxr-xr-x 1 dante dante 2,9K 19 mar 12:05 example1
-rw-r--r-- 1 dante dante  71 19 mar 10:23 example.c
-rwxr-xr-x 1 dante dante 203K 19 mar 12:21 provagcc
floatman@debian:~/bashex$ upx -9 provagcc
                      Ultimate Packer for eXecutables
  Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007
UPX 3.01        Markus Oberhumer, Laszlo Molnar & John Reiser  Jul 31st 2007

        File size        Ratio      Format      Name
  --------------------  ------  -----------  -----------
    207648 ->    84296  40.60%  linux/elf386  provagcc                     

Packed 1 file.
floatman@debian:~/bashex$ ls -lh
totale 104K
-rwxr-xr-x 1 dante dante 6,3K 19 mar 12:05 example
-rwxr-xr-x 1 dante dante 2,9K 19 mar 12:05 example1
-rw-r--r-- 1 dante dante  71 19 mar 10:23 example.c
-rwxr-xr-x 1 dante dante  83K 19 mar 12:21 provagcc
una riduzione del 40% non è affatto male ^^
È evidente che si vuole lavorare su un binario la sua compressione è l'ultima operazione da eseguire, perchè il file in seguito diventa ingestibile se non tramite un loading in memoria.

Per lavorare sui file binari possiamo tranquillamente utilizzare sed:

Codice:
floatman@debian:~/bashex$ sed -re 's/\(Debian 4.3.2-1.1\)/(FloatLinux 1.0)/g' example1 > example2
floatman@debian:~/bashex$ chmod 755 example2
floatman@debian:~/bashex$ cat example2 ; echo
@����U��S���[���������t����X[���5��%��%�h������%�������%�h�����1�^����PT
RhhQVh�����������������U��S���=�u@����-����X�9�s���B�������9�r�����[]Ív�
�'U������t���t  �$����Ð�L$����q�U��Q���$��������Y]�a�ÐU��]Ít&��'U��WVS�
O�Ý���{�������������)�����t$1�E�D�E�D$��$��������9�rރ�[^_]Ë$Ð�U��S����
���tlH���op����u��[]�U��S���[������Y[��FUNZIONO!��������t�J����o4���o��
�o*��GCC: (FloatLinux 1.0) 4.3.2GCC: (FloatLinux 1.0) 4.3.2GCC: (FloatLi
nux 1.0) 4.3.2GCC: (FloatLinux 1.0) 4.3.2GCC: (FloatLinux 1.0) 4.3.2GCC:
 (FloatLinux 1.0) 4.3.2GCC: (FloatLinux 1.0)4.3.2.shstrtab.interp.note.A
BI-tag.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.
init.text.fini.rodata.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data.
bss.comment(( %HH(!���opp +��P3�J;���o**H���o44 W      `T      \itt0d��
@o�|ull{�����������������������������
il nuovo file example2 va nuovamente reso eseguibile da chmod.

Bash è comunque in grado di scrivere valori esadecimali nella forma '\x[valore_hex]', possiamo testarlo direttamente con un echo (usando l'opzione -e)

Codice:
floatman@debian:~/bashex$ echo -e "\x46\x55\x4E\x5A\x49\x4F\x4E\x4F\x21"
FUNZIONO!
per questo motivo ci risulta possibile anche scrivere byte usando ad esempio sed in codifica hex, in modo da realizzare un patching vero e proprio:

Codice:
floatman@debian:~/bashex$ echo -e "\x45\x43\x43\x4F\x20\x51\x55\x49\x21"
ECCO QUI!
floatman@debian:~/bashex$ sed -re 's/\x46\x55\x4E\x5A\x49\x4F\x4E\x4F\x21/\x45\x43\x43\x4F\x20\x51\x55\x49\x21/' example2 > example3
floatman@debian:~/bashex$ cat example3 ; echo
@����U��S���[���������t����X[���5��%��%�h������%�������%�h�����1�^����PT
RhhQVh�����������������U��S���=�u@����-����X�9�s���B�������9�r�����[]Ív�
�'U������t���t  �$����Ð�L$����q�U��Q���$��������Y]�a�ÐU��]Ít&��'U��WVS�
O�Ý���{�������������)�����t$1�E�D�E�D$��$��������9�rރ�[^_]Ë$Ð�U��S����
���tlH���op����u��[]�U��S���[������Y[��ECCO QUI!��������t�J����o4���o��
�o*��GCC: (FloatLinux 1.0) 4.3.2GCC: (FloatLinux 1.0) 4.3.2GCC: (FloatLi
nux 1.0) 4.3.2GCC: (FloatLinux 1.0) 4.3.2GCC: (FloatLinux 1.0) 4.3.2GCC:
 (FloatLinux 1.0) 4.3.2GCC: (FloatLinux 1.0) 4.3.2.shstrtab.interp.note.
ABI-tag.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt
.init.text.fini.rodata.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data
.bss.comment(( %HH(!���opp +��P3�J;���o**H���o44 W      `T      \itt0d�
�@o�|ull{�����������������������������
floatman@debian:~/bashex$ chmod 755 example3
floatman@debian:~/bashex$ ./example3
ECCO QUI!
Questi sono stati soltanto dei piccoli esempi d'uso per dimostrare come eseguire piccole operazioni su file binari usando la sola riga di comando su Bash; per operazioni più complesse, come ad esempio l'individuazione dell'offset di patching, sarà necessario ricorrere a strumenti più completi.
In ogni caso è anche fondamentale non complicarsi la vita ^^
avatar
floatman

Messaggi : 844
Data d'iscrizione : 14.09.09

Visualizza il profilo dell'utente http://myville.altervista.org

Tornare in alto Andare in basso

Re: riga di comando e dati binari

Messaggio Da vikkio88 il Ven Mar 19, 2010 8:06 pm

figata! grazie floatty!
avatar
vikkio88
Admin
Admin

Messaggi : 792
Data d'iscrizione : 14.09.09
Età : 29
Località : Palermo

Visualizza il profilo dell'utente http://vikkio88.altervista.org

Tornare in alto Andare in basso

Re: riga di comando e dati binari

Messaggio Da floatman il Sab Mar 20, 2010 11:55 am

Uh grazie, ti ha appassionato Razz

_________________
HP Compaq nx6110; Debian Testing/Squeeze - Fluxbox

avatar
floatman

Messaggi : 844
Data d'iscrizione : 14.09.09

Visualizza il profilo dell'utente http://myville.altervista.org

Tornare in alto Andare in basso

Re: riga di comando e dati binari

Messaggio Da vikkio88 il Sab Mar 20, 2010 1:16 pm

floatman ha scritto:Uh grazie, ti ha appassionato Razz
perchè non avrei mai potuto immaginare che potessi usare sed su file binari! Very Happy
avatar
vikkio88
Admin
Admin

Messaggi : 792
Data d'iscrizione : 14.09.09
Età : 29
Località : Palermo

Visualizza il profilo dell'utente http://vikkio88.altervista.org

Tornare in alto Andare in basso

Re: riga di comando e dati binari

Messaggio Da Contenuto sponsorizzato


Contenuto sponsorizzato


Tornare in alto Andare in basso

Tornare in alto

- Argomenti simili

 :: GNU/Linux :: Altro

 
Permessi di questa sezione del forum:
Non puoi rispondere agli argomenti in questo forum