riga di comando e dati binari
2 partecipanti
riga di comando e dati binari
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
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:
Per chi non lo sapesse, una delle caratteristica principale del formato ELF (l'eseguibile binario UNIX) è quella di essere pieno di schifezze...
Il comando 'strip' fortunatamente è ancora presente almeno nelle grandi distribuzioni storiche.
Ad esempio proviamo con gcc, dopo averlo copiato nella nostra directory di lavoro:
È 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:
Bash è comunque in grado di scrivere valori esadecimali nella forma '\x[valore_hex]', possiamo testarlo direttamente con un echo (usando l'opzione -e)
In ogni caso è anche fondamentale non complicarsi la vita ^^
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
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!
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
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
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
È 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{�����������������������������
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!
- 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!
In ogni caso è anche fondamentale non complicarsi la vita ^^
Re: riga di comando e dati binari
perchè non avrei mai potuto immaginare che potessi usare sed su file binari!floatman ha scritto:Uh grazie, ti ha appassionato
Permessi in questa sezione del forum:
Non puoi rispondere agli argomenti in questo forum.