GNU/Linux >> Linux Esercitazione >  >> Linux

Esplora i binari usando questo strumento Linux completo

In 10 modi per analizzare i file binari su Linux , ho spiegato come utilizzare il ricco set di strumenti nativi di Linux per analizzare i binari. Ma se vuoi esplorare ulteriormente il tuo binario, hai bisogno di uno strumento personalizzato per l'analisi binaria. Se non conosci l'analisi binaria e hai lavorato principalmente con linguaggi di scripting, 9 strumenti GNU binutils essenziali ti aiuterà a iniziare a imparare il processo di compilazione e cosa costituisce un binario.

Perché ho bisogno di un altro strumento?

Più risorse Linux

  • Comandi Linux cheat sheet
  • Cheat sheet sui comandi avanzati di Linux
  • Corso online gratuito:Panoramica tecnica RHEL
  • Cheat sheet della rete Linux
  • Cheat sheet di SELinux
  • Cheat sheet dei comandi comuni di Linux
  • Cosa sono i container Linux?
  • I nostri ultimi articoli su Linux

È naturale chiedersi perché hai bisogno di un altro strumento se gli strumenti nativi di Linux esistenti fanno cose simili. Bene, è per gli stessi motivi per cui usi il cellulare come sveglia, per prendere appunti, come videocamera, per ascoltare musica, per navigare in Internet e, occasionalmente, per effettuare e ricevere chiamate. In precedenza, dispositivi e strumenti separati gestivano queste funzioni, come una fotocamera fisica per scattare foto, un piccolo blocco note per prendere appunti, una sveglia sul comodino per svegliarsi e così via. Avere un dispositivo per fare più cose (ma correlate) è conveniente per l'utente. Inoltre, la caratteristica killer è l'interoperabilità tra le funzioni separate.

Allo stesso modo, anche se molti strumenti Linux hanno uno scopo specifico, avere funzionalità simili (e migliori) raggruppate in un unico strumento è molto utile. Questo è il motivo per cui penso che Radare2 dovrebbe essere il tuo strumento di riferimento ogni volta che devi lavorare con i binari.

Radare2 (noto anche come r2) è un "framework di ingegneria inversa simile a Unix e set di strumenti da riga di comando", secondo il suo profilo GitHub. Il "2" nel suo nome è dovuto al fatto che questa versione è stata riscritta da zero per renderla più modulare.

Perché Radare2?

Ci sono tonnellate di strumenti Linux (non nativi) là fuori che vengono utilizzati per l'analisi binaria, quindi perché dovresti scegliere Radare2? Le mie ragioni sono semplici.

Innanzitutto, è un progetto open source con una comunità attiva e sana. Se stai cercando nuove funzionalità o disponibilità di correzioni di bug, questo è molto importante.

In secondo luogo, Radare2 può essere utilizzato sulla riga di comando e dispone di un ricco ambiente di interfaccia utente grafica (GUI) chiamato Cutter per coloro che sono più a proprio agio con le GUI. Essendo un utente Linux di lunga data, mi nutro più a mio agio con la shell. Sebbene ci sia una leggera curva di apprendimento per acquisire familiarità con i comandi di Radare2, lo paragonerei all'apprendimento di Vim. Per prima cosa impari le cose di base e, una volta che le padroneggi, passi a cose più avanzate. In pochissimo tempo, diventa una seconda natura.

Terzo, Radare2 ha un buon supporto per strumenti esterni tramite plugin. Ad esempio, lo strumento di analisi binaria e inversione Ghidra recentemente open source è popolare per la sua funzione di decompilatore, che è un elemento critico del software di inversione. Puoi installare e utilizzare il decompilatore Ghidra direttamente dalla console Radare2, che è sorprendente e ti dà il meglio di entrambi i mondi.

Inizia con Radare2

Per installare Radare2, clona semplicemente il repository ed esegui user.sh sceneggiatura. Potrebbe essere necessario installare alcuni pacchetti prerequisiti se non sono già presenti nel sistema. Una volta completata l'installazione, esegui r2 -v comando per vedere se Radare2 è stato installato correttamente:

$ git clone https://github.com/radareorg/radare2.git
$ cd radare2
$ sys/user.sh

# version

$ r2 -v
radare2 4.6.0-git 25266 @ linux-x86-64 git.4.4.0-930-g48047b317
commit: 48047b3171e6ed0480a71a04c3693a0650d03543 build: 2020-11-17__09:31:03
$

Ottieni un file binario di prova di esempio

Ora che r2 è installato, hai bisogno di un file binario di esempio per provarlo. Puoi usare qualsiasi binario di sistema (ls , bash , e così via), ma per semplificare le cose per questo tutorial, compila il seguente programma C:

$ cat adder.c 
#include <stdio.h>

int adder(int num) {
        return num + 1;
}

int main() {
        int res, num1 = 100;
        res = adder(num1);
        printf("Number now is  : %d\n", res);
        return 0;
}
$
$
$ gcc adder.c -o adder
$
$ file adder
adder: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=9d4366f7160e1ffb46b14466e8e0d70f10de2240, not stripped
$
$ ./adder
Number now is  : 101
$

Carica il file binario

Per analizzare il binario, devi caricarlo in Radare2. Caricalo fornendo il file come argomento della riga di comando a r2 comando. Sei caduto in una console Radare2 separata diversa dalla tua shell. Per uscire dalla console, puoi digitare Esci o Esci o premi Ctrl +D :

$ r2 ./adder
 -- Learn pancake as if you were radare!
[0x004004b0]> quit
$

Analizza il binario

Prima di poter esplorare il binario, devi chiedere a r2 di analizzarlo per te. Puoi farlo eseguendo aaa comando nella console r2;

$ r2 ./adder
 -- Sorry, radare2 has experienced an internal error.
[0x004004b0]>
[0x004004b0]>
[0x004004b0]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x004004b0]>

Ciò significa che ogni volta che scegli un binario per l'analisi, devi digitare un comando aggiuntivo per aaa dopo aver caricato il binario. Puoi aggirarlo chiamando r2 con -A seguito dal nome binario; questo dice a r2 di analizzare automaticamente il binario per te:

$ r2 -A ./adder
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
 -- Already up-to-date.
[0x004004b0]>

Ottieni alcune informazioni di base sul binario

Prima di iniziare ad analizzare un binario, è necessario un punto di partenza. In molti casi, questo può essere il formato del file binario (ELF, PE e così via), l'architettura per cui è stato creato il binario (x86, AMD, ARM e così via) e se il binario è a 32 bit o 64 bit . Il pratico iI di R2 comando può fornire le informazioni richieste:

[0x004004b0]> iI
arch     x86
baddr    0x400000
binsz    14724
bintype  elf
bits     64
canary   false
class    ELF64
compiler GCC: (GNU) 8.3.1 20190507 (Red Hat 8.3.1-4)
crypto   false
endian   little
havecode true
intrp    /lib64/ld-linux-x86-64.so.2
laddr    0x0
lang     c
linenum  true
lsyms    true
machine  AMD x86-64 architecture
maxopsz  16
minopsz  1
nx       true
os       linux
pcalign  0
pic      false
relocs   true
relro    partial
rpath    NONE
sanitiz  false
static   false
stripped false
subsys   linux
va       true

[0x004004b0]>
[0x004004b0]>

Importa ed esporta

Spesso, una volta che si conosce il tipo di file con cui si ha a che fare, si desidera sapere che tipo di funzioni di libreria standard utilizza il binario o apprendere le potenziali funzionalità del programma. Nel programma C di esempio in questo tutorial, l'unica funzione di libreria è printf per stampare un messaggio. Puoi vederlo eseguendo ii comando, che mostra tutte le importazioni del binario:

[0x004004b0]> ii
[Imports]
nth vaddr      bind   type   lib name
―――――――――――――――――――――――――――――――――――――
1   0x00000000 WEAK   NOTYPE     _ITM_deregisterTMCloneTable
2   0x004004a0 GLOBAL FUNC       printf
3   0x00000000 GLOBAL FUNC       __libc_start_main
4   0x00000000 WEAK   NOTYPE     __gmon_start__
5   0x00000000 WEAK   NOTYPE     _ITM_registerTMCloneTable

Il binario può anche avere i propri simboli, funzioni o dati. Queste funzioni sono generalmente mostrate in Exports . Il binario di test ha due funzioni, principale e sommatore, che vengono esportate. Il resto delle funzioni viene aggiunto durante la fase di compilazione durante la compilazione del binario. Il caricatore ha bisogno di questi per caricare il binario (per ora non preoccuparti troppo di loro):

[0x004004b0]> 
[0x004004b0]> iE
[Exports]

nth paddr       vaddr      bind   type   size lib name
――――――――――――――――――――――――――――――――――――――――――――――――――――――
82   0x00000650 0x00400650 GLOBAL FUNC   5        __libc_csu_fini
85   ---------- 0x00601024 GLOBAL NOTYPE 0        _edata
86   0x00000658 0x00400658 GLOBAL FUNC   0        _fini
89   0x00001020 0x00601020 GLOBAL NOTYPE 0        __data_start
90   0x00000596 0x00400596 GLOBAL FUNC   15       adder
92   0x00000670 0x00400670 GLOBAL OBJ    0        __dso_handle
93   0x00000668 0x00400668 GLOBAL OBJ    4        _IO_stdin_used
94   0x000005e0 0x004005e0 GLOBAL FUNC   101      __libc_csu_init
95   ---------- 0x00601028 GLOBAL NOTYPE 0        _end
96   0x000004e0 0x004004e0 GLOBAL FUNC   5        _dl_relocate_static_pie
97   0x000004b0 0x004004b0 GLOBAL FUNC   47       _start
98   ---------- 0x00601024 GLOBAL NOTYPE 0        __bss_start
99   0x000005a5 0x004005a5 GLOBAL FUNC   55       main
100  ---------- 0x00601028 GLOBAL OBJ    0        __TMC_END__
102  0x00000468 0x00400468 GLOBAL FUNC   0        _init

[0x004004b0]>

Informazioni hash

Come fai a sapere se due binari sono simili? Non puoi esattamente aprire un binario e visualizzare il codice sorgente al suo interno. Nella maggior parte dei casi, l'hash di un file binario, md5sum, sha1, sha256, viene utilizzato per identificarlo in modo univoco. Puoi trovare l'hash binario usando it comando:

[0x004004b0]> it
md5 7e6732f2b11dec4a0c7612852cede670
sha1 d5fa848c4b53021f6570dd9b18d115595a2290ae
sha256 13dd5a492219dac1443a816ef5f91db8d149e8edbf26f24539c220861769e1c2
[0x004004b0]>

Funzioni

Il codice è raggruppato in funzioni; per elencare quali funzioni sono presenti all'interno di un binario, esegui afl comando. L'elenco seguente mostra le funzioni principali e sommatori. Di solito, funzioni che iniziano con sym.imp sono importati dalla libreria standard (glibc in questo caso):

[0x004004b0]> afl
0x004004b0    1 46           entry0
0x004004f0    4 41   -> 34   sym.deregister_tm_clones
0x00400520    4 57   -> 51   sym.register_tm_clones
0x00400560    3 33   -> 32   sym.__do_global_dtors_aux
0x00400590    1 6            entry.init0
0x00400650    1 5            sym.__libc_csu_fini
0x00400658    1 13           sym._fini
0x00400596    1 15           sym.adder
0x004005e0    4 101          loc..annobin_elf_init.c
0x004004e0    1 5            loc..annobin_static_reloc.c
0x004005a5    1 55           main
0x004004a0    1 6            sym.imp.printf
0x00400468    3 27           sym._init
[0x004004b0]>

Riferimenti incrociati

In C, la funzione principale è dove un programma inizia la sua esecuzione. Idealmente, altre funzioni vengono chiamate da main e, all'uscita da un programma, la funzione main restituisce uno stato di uscita al sistema operativo. Questo è evidente nel codice sorgente; tuttavia, che dire di un binario? Come puoi sapere dove viene chiamata la funzione sommatore?

Puoi usare axt comando seguito dal nome della funzione per vedere dove viene chiamata la funzione sommatore; come puoi vedere di seguito, viene chiamato dalla funzione principale. Questo è noto come riferimento incrociato. Ma cosa chiama la funzione principale stessa? Il axt main la funzione seguente mostra che viene chiamata da entry0 (Lascerò informazioni su entry0 come esercizio per il lettore):

[0x004004b0]> axt sym.adder
main 0x4005b9 [CALL] call sym.adder
[0x004004b0]>
[0x004004b0]> axt main
entry0 0x4004d1 [DATA] mov rdi, main
[0x004004b0]>

Cerca posizioni

Quando si lavora con file di testo, ci si sposta spesso all'interno di un file facendo riferimento a un numero di riga seguito da un numero di riga o di colonna; in un binario, usi gli indirizzi. Questi sono numeri esadecimali che iniziano con 0x seguito da un indirizzo. Per trovare la tua posizione in un file binario, esegui s comando. Per spostarti in una posizione diversa, usa i s comando seguito dall'indirizzo.

I nomi delle funzioni sono come etichette, rappresentate internamente da indirizzi. Se il nome della funzione è in binario (non rimosso), puoi utilizzare i s comando seguito dal nome della funzione per passare a un indirizzo di funzione specifico. Allo stesso modo, se vuoi saltare all'inizio del binario, digita s 0 :

[0x004004b0]> s
0x4004b0
[0x004004b0]>
[0x004004b0]> s main
[0x004005a5]>
[0x004005a5]> s
0x4005a5
[0x004005a5]>
[0x004005a5]> s sym.adder
[0x00400596]>
[0x00400596]> s
0x400596
[0x00400596]>
[0x00400596]> s 0
[0x00000000]>
[0x00000000]> s
0x0
[0x00000000]>

Vista esadecimale

Spesso, il binario grezzo non ha senso. Può aiutare a visualizzare il binario in modalità esadecimale insieme alla sua rappresentazione ASCII equivalente:

[0x004004b0]> s main
[0x004005a5]>
[0x004005a5]> px
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x004005a5  5548 89e5 4883 ec10 c745 fc64 0000 008b  UH..H....E.d....
0x004005b5  45fc 89c7 e8d8 ffff ff89 45f8 8b45 f889  E.........E..E..
0x004005c5  c6bf 7806 4000 b800 0000 00e8 cbfe ffff  ..x.@...........
0x004005d5  b800 0000 00c9 c30f 1f40 00f3 0f1e fa41  [email protected]
0x004005e5  5749 89d7 4156 4989 f641 5541 89fd 4154  WI..AVI..AUA..AT
0x004005f5  4c8d 2504 0820 0055 488d 2d04 0820 0053  L.%.. .UH.-.. .S
0x00400605  4c29 e548 83ec 08e8 57fe ffff 48c1 fd03  L).H....W...H...
0x00400615  741f 31db 0f1f 8000 0000 004c 89fa 4c89  t.1........L..L.
0x00400625  f644 89ef 41ff 14dc 4883 c301 4839 dd75  .D..A...H...H9.u
0x00400635  ea48 83c4 085b 5d41 5c41 5d41 5e41 5fc3  .H...[]A\A]A^A_.
0x00400645  9066 2e0f 1f84 0000 0000 00f3 0f1e fac3  .f..............
0x00400655  0000 00f3 0f1e fa48 83ec 0848 83c4 08c3  .......H...H....
0x00400665  0000 0001 0002 0000 0000 0000 0000 0000  ................
0x00400675  0000 004e 756d 6265 7220 6e6f 7720 6973  ...Number now is
0x00400685  2020 3a20 2564 0a00 0000 0001 1b03 3b44    : %d........;D
0x00400695  0000 0007 0000 0000 feff ff88 0000 0020  ...............
[0x004005a5]>

Smontaggio

Se stai lavorando con binari compilati, non c'è codice sorgente che puoi visualizzare. Il compilatore traduce il codice sorgente in istruzioni in linguaggio macchina che la CPU può comprendere ed eseguire; il risultato è il binario o eseguibile. Tuttavia, è possibile visualizzare le istruzioni di montaggio (mnemonici) per dare un senso a ciò che sta facendo il programma. Ad esempio, se vuoi vedere cosa sta facendo la funzione principale, puoi cercare l'indirizzo della funzione principale usando s main e quindi esegui il pdf comando per visualizzare le istruzioni di smontaggio.

Per comprendere le istruzioni di montaggio, è necessario fare riferimento al manuale di architettura (x86 in questo caso), alla sua interfaccia binaria dell'applicazione (la sua ABI o alle convenzioni di chiamata) e avere una conoscenza di base di come funziona lo stack:

[0x004004b0]> s main
[0x004005a5]>
[0x004005a5]> s
0x4005a5
[0x004005a5]>
[0x004005a5]> pdf
            ; DATA XREF from entry0 @ 0x4004d1
┌ 55: int main (int argc, char **argv, char **envp);
│           ; var int64_t var_8h @ rbp-0x8
│           ; var int64_t var_4h @ rbp-0x4
│           0x004005a5      55             push rbp
│           0x004005a6      4889e5         mov rbp, rsp
│           0x004005a9      4883ec10       sub rsp, 0x10
│           0x004005ad      c745fc640000.  mov dword [var_4h], 0x64    ; 'd' ; 100
│           0x004005b4      8b45fc         mov eax, dword [var_4h]
│           0x004005b7      89c7           mov edi, eax
│           0x004005b9      e8d8ffffff     call sym.adder
│           0x004005be      8945f8         mov dword [var_8h], eax
│           0x004005c1      8b45f8         mov eax, dword [var_8h]
│           0x004005c4      89c6           mov esi, eax
│           0x004005c6      bf78064000     mov edi, str.Number_now_is__:__d ; 0x400678 ; "Number now is  : %d\n" ; const char *format
│           0x004005cb      b800000000     mov eax, 0
│           0x004005d0      e8cbfeffff     call sym.imp.printf         ; int printf(const char *format)
│           0x004005d5      b800000000     mov eax, 0
│           0x004005da      c9             leave
└           0x004005db      c3             ret
[0x004005a5]>

Ecco lo smontaggio per la funzione sommatore:

[0x004005a5]> s sym.adder
[0x00400596]>
[0x00400596]> s
0x400596
[0x00400596]>
[0x00400596]> pdf
            ; CALL XREF from main @ 0x4005b9
┌ 15: sym.adder (int64_t arg1);
│           ; var int64_t var_4h @ rbp-0x4
│           ; arg int64_t arg1 @ rdi
│           0x00400596      55             push rbp
│           0x00400597      4889e5         mov rbp, rsp
│           0x0040059a      897dfc         mov dword [var_4h], edi     ; arg1
│           0x0040059d      8b45fc         mov eax, dword [var_4h]
│           0x004005a0      83c001         add eax, 1
│           0x004005a3      5d             pop rbp
└           0x004005a4      c3             ret
[0x00400596]>

Stringhe

Vedere quali stringhe sono presenti all'interno del binario può essere un punto di partenza per l'analisi binaria. Le stringhe sono codificate in un codice binario e spesso forniscono suggerimenti importanti per spostare l'attenzione sull'analisi di determinate aree. Esegui iz comando all'interno del binario per elencare tutte le stringhe. Il binario di prova ha solo una stringa codificata nel binario:

[0x004004b0]> iz
[Strings]
nth paddr      vaddr      len size section type  string
―――――――――――――――――――――――――――――――――――――――――――――――――――――――
0   0x00000678 0x00400678 20  21   .rodata ascii Number now is  : %d\n

[0x004004b0]>

Stringhe di riferimento incrociato

Come con le funzioni, puoi incrociare le stringhe per vedere da dove vengono stampate e capire il codice che le circonda:

[0x004004b0]> ps @ 0x400678
Number now is  : %d

[0x004004b0]>
[0x004004b0]> axt 0x400678
main 0x4005c6 [DATA] mov edi, str.Number_now_is__:__d
[0x004004b0]>

Modalità visiva

Quando il tuo codice è complicato con più funzioni chiamate, è facile perdersi. Può essere utile avere una vista grafica o visiva di quali funzioni vengono chiamate, quali percorsi vengono presi in base a determinate condizioni, ecc. Puoi esplorare la modalità visiva di r2 usando il VV comando dopo essere passati a una funzione di interesse. Ad esempio, per la funzione sommatore:

[0x004004b0]> s sym.adder
[0x00400596]>
[0x00400596]> VV

Debugger

Finora hai eseguito analisi statiche:stai solo guardando le cose nel binario senza eseguirlo. A volte è necessario eseguire il binario e analizzare varie informazioni in memoria in fase di esecuzione. Il debugger interno di r2 ti consente di eseguire un file binario, inserire punti di interruzione, analizzare i valori delle variabili o scaricare il contenuto dei registri.

Avvia il debugger con -d flag e aggiungi il -A flag per eseguire un'analisi mentre il binario viene caricato. È possibile impostare punti di interruzione in vari punti, come funzioni o indirizzi di memoria, utilizzando il db <function-name> comando. Per visualizzare i punti di interruzione esistenti, usa dbi comando. Dopo aver posizionato i punti di interruzione, inizia a eseguire il binario utilizzando dc comando. Puoi visualizzare lo stack usando il dbt comando, che mostra le chiamate di funzione. Infine, puoi scaricare il contenuto dei registri usando il drr comando:

$ r2 -d -A ./adder
Process with PID 17453 started...
= attach 17453 17453
bin.baddr 0x00400000
Using 0x400000
asm.bits 64
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
 -- git checkout hamster
[0x7f77b0a28030]>
[0x7f77b0a28030]> db main
[0x7f77b0a28030]>
[0x7f77b0a28030]> db sym.adder
[0x7f77b0a28030]>
[0x7f77b0a28030]> dbi
0 0x004005a5 E:1 T:0
1 0x00400596 E:1 T:0
[0x7f77b0a28030]>
[0x7f77b0a28030]> afl | grep main
0x004005a5    1 55           main
[0x7f77b0a28030]>
[0x7f77b0a28030]> afl | grep sym.adder
0x00400596    1 15           sym.adder
[0x7f77b0a28030]>
[0x7f77b0a28030]> dc
hit breakpoint at: 0x4005a5
[0x004005a5]>
[0x004005a5]> dbt
0  0x4005a5           sp: 0x0                 0    [main]  main sym.adder+15
1  0x7f77b0687873     sp: 0x7ffe35ff6858      0    [??]  section..gnu.build.attributes-1345820597
2  0x7f77b0a36e0a     sp: 0x7ffe35ff68e8      144  [??]  map.usr_lib64_ld_2.28.so.r_x+65034
[0x004005a5]> dc
hit breakpoint at: 0x400596
[0x00400596]> dbt
0  0x400596           sp: 0x0                 0    [sym.adder]  rip entry.init0+6
1  0x4005be           sp: 0x7ffe35ff6838      0    [main]  main+25
2  0x7f77b0687873     sp: 0x7ffe35ff6858      32   [??]  section..gnu.build.attributes-1345820597
3  0x7f77b0a36e0a     sp: 0x7ffe35ff68e8      144  [??]  map.usr_lib64_ld_2.28.so.r_x+65034
[0x00400596]>
[0x00400596]>
[0x00400596]> dr
rax = 0x00000064
rbx = 0x00000000
rcx = 0x7f77b0a21738
rdx = 0x7ffe35ff6948
r8 = 0x7f77b0a22da0
r9 = 0x7f77b0a22da0
r10 = 0x0000000f
r11 = 0x00000002
r12 = 0x004004b0
r13 = 0x7ffe35ff6930
r14 = 0x00000000
r15 = 0x00000000
rsi = 0x7ffe35ff6938
rdi = 0x00000064
rsp = 0x7ffe35ff6838
rbp = 0x7ffe35ff6850
rip = 0x00400596
rflags = 0x00000202
orax = 0xffffffffffffffff
[0x00400596]>

Decompilatore

Essere in grado di comprendere l'assemblaggio è un prerequisito per l'analisi binaria. Il linguaggio assembly è sempre legato all'architettura su cui è costruito il binario e su cui dovrebbe funzionare. Non esiste mai una mappatura 1:1 tra una riga di codice sorgente e codice assembly. Spesso, una singola riga di codice sorgente C produce più righe di assemblaggio. Quindi, leggere il codice assembly riga per riga non è ottimale.

È qui che entrano in gioco i decompilatori. Tentano di ricostruire il possibile codice sorgente in base alle istruzioni di montaggio. Questo NON è MAI esattamente lo stesso del codice sorgente utilizzato per creare il binario; è una rappresentazione ravvicinata della sorgente basata sull'assembly. Inoltre, tieni presente che le ottimizzazioni del compilatore che generano codice assembly diverso per velocizzare le cose, ridurre le dimensioni di un binario, ecc., renderanno più difficile il lavoro del decompilatore. Inoltre, gli autori di malware spesso oscurano deliberatamente il codice per scoraggiare un analista di malware.

Radare2 fornisce decompilatori tramite plugin. Puoi installare qualsiasi decompilatore supportato da Radare2. Visualizza i plugin correnti con r2pm -l comando. Installa un esempio r2dec decompilatore con r2pm install comando:

$ r2pm  -l
$
$ r2pm install r2dec
Cloning into 'r2dec'...
remote: Enumerating objects: 100, done.
remote: Counting objects: 100% (100/100), done.
remote: Compressing objects: 100% (97/97), done.
remote: Total 100 (delta 18), reused 27 (delta 1), pack-reused 0
Receiving objects: 100% (100/100), 1.01 MiB | 1.31 MiB/s, done.
Resolving deltas: 100% (18/18), done.
Install Done For r2dec
gmake: Entering directory '/root/.local/share/radare2/r2pm/git/r2dec/p'
[CC] duktape/duktape.o
[CC] duktape/duk_console.o
[CC] core_pdd.o
[CC] core_pdd.so
gmake: Leaving directory '/root/.local/share/radare2/r2pm/git/r2dec/p'
$
$ r2pm  -l
r2dec
$

Vista decompilatore

Per decompilare un binario, carica il binario in r2 e analizzalo automaticamente. Passa alla funzione di interesse, in questo esempio sommatore, usando il s sym.adder comando, quindi usa il pdda comando per visualizzare l'assembly e il codice sorgente decompilato affiancati. Leggere questo codice sorgente decompilato è spesso più facile che leggere riga per riga:

$ r2 -A ./adder
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
 -- What do you want to debug today?
[0x004004b0]>
[0x004004b0]> s sym.adder
[0x00400596]>
[0x00400596]> s
0x400596
[0x00400596]>
[0x00400596]> pdda
    ; assembly                               | /* r2dec pseudo code output */
                                             | /* ./adder @ 0x400596 */
                                             | #include <stdint.h>
                                             |  
    ; (fcn) sym.adder ()                     | int32_t adder (int64_t arg1) {
                                             |     int64_t var_4h;
                                             |     rdi = arg1;
    0x00400596 push rbp                      |    
    0x00400597 mov rbp, rsp                  |    
    0x0040059a mov dword [rbp - 4], edi      |     *((rbp - 4)) = edi;
    0x0040059d mov eax, dword [rbp - 4]      |     eax = *((rbp - 4));
    0x004005a0 add eax, 1                    |     eax++;
    0x004005a3 pop rbp                       |    
    0x004005a4 ret                           |     return eax;
                                             | }
[0x00400596]>

Configura le impostazioni

Man mano che ti sentirai più a tuo agio con Radare2, vorrai cambiarne la configurazione per adattarla al tuo modo di lavorare. Puoi visualizzare le configurazioni predefinite di r2 usando il e comando. Per impostare una configurazione specifica, aggiungi config = value dopo la e comando:

[0x004005a5]> e | wc -l
593
[0x004005a5]> e | grep syntax
asm.syntax = intel
[0x004005a5]>
[0x004005a5]> e asm.syntax = att
[0x004005a5]>
[0x004005a5]> e | grep syntax
asm.syntax = att
[0x004005a5]>

Per rendere permanenti le modifiche alla configurazione, inseriscile in un file di avvio denominato .radare2rc che r2 legge all'avvio. Questo file si trova solitamente nella tua home directory; in caso contrario, puoi crearne uno. Alcune opzioni di configurazione di esempio includono:

$ cat ~/.radare2rc 
e asm.syntax = att
e scr.utf8 = true
eco solarized
e cmd.stack = true
e stack.size = 256
$

Esplora di più

Hai visto abbastanza funzionalità di Radare2 per orientarti nello strumento. Poiché Radare2 segue la filosofia Unix, anche se puoi fare varie cose dalla sua console, utilizza un set separato di binari sottostanti per svolgere le sue attività.

Esplora i binari autonomi elencati di seguito per vedere come funzionano. Ad esempio, le informazioni binarie visualizzate nella console con iI Il comando può essere trovato anche usando il rabin2 <binary> comando:

$ cd bin/
$
$ ls
prefix  r2agent    r2pm  rabin2   radiff2  ragg2    rarun2   rasm2
r2      r2-indent  r2r   radare2  rafind2  rahash2  rasign2  rax2
$

Cosa ne pensi di Radare2? Condividi il tuo feedback nei commenti.


Linux
  1. Condivisione di file open source con questo strumento Linux

  2. Ispeziona le capacità dei binari ELF con questo strumento open source

  3. Esegui il debug di Linux usando ProcDump

  4. Come confrontare tre file in Linux usando lo strumento diff3

  5. Utilizzo dello strumento Screenshot di GNOME in Linux come un professionista

Visualizza le informazioni di rete in Linux utilizzando quale strumento IP

Come confrontare i file in Linux usando lo strumento Meld (Diff/Merge).

Utilizzo di SSH Port Forwarding come strumento di sicurezza in Linux

Utilizzo del comando Watch in Linux

Come clonare o eseguire il backup del disco Linux utilizzando lo strumento di imaging Clonezilla

Come sincronizzare l'ora con NTP in Linux utilizzando Chrony Tool