Perché il reverse engineering non può essere automatizzato?

31

Sono ancora al college per una laurea in Computer Security e ho seguito la mia prima lezione in lingua assembly il semestre precedente. Abbiamo affrontato il tema del reverse engineering e perché è una parte importante della lotta contro malware e applicazioni poco desiderate.

Durante la mia lezione abbiamo utilizzato principalmente IDA pro, ma abbiamo anche controllato alcune applicazioni simili e gratuite basate su browser.

In queste applicazioni, siamo stati in grado di ottenere così tante informazioni sulle istruzioni e sul codice di basso livello che mi stavo chiedendo perché abbiamo anche bisogno di un umano per esaminarlo e ricreare i linguaggi di livello superiore (come scrivere una versione "C") di un pezzo di malware).

Ecco la mia domanda:

Perché un programma non può utilizzare le informazioni presenti nel codice assembly e trasformarlo automaticamente in un linguaggio semplicistico?

Capisco che non sarebbe sembrato esattamente come sarebbe stato quando è stato scritto per la prima volta, ma non dovrebbe essere possibile ricrearlo in un modo che faciliti la lettura e la lettura?

È solo qualcosa che non riesco a comprendere, grazie!

    
posta PositriesElectron 22.06.2015 - 20:33
fonte

3 risposte

66

Risposta breve

È assolutamente possibile, ma l'accuratezza e la leggibilità sono una questione completamente diversa. Un chiarimento da fare: Reverse Engineering non sta decompilando.

Risposta lunga

Reverse Engineering è generalmente il processo mediante il quale si prende qualcosa (qualcosa di veramente) a parte per vedere come funziona. Disassemblare è quando si prende un file in formato binario e si interpreta il codice macchina in codice assembly. La decompilazione sta interpretando il codice assembly in un linguaggio di livello superiore.

Credo che la tua domanda sia davvero, Perché non è possibile automatizzare la decompilazione di un programma? Beh, può essere!

Esistono diversi decompilatori Java diversi. Il codice byte Java è completamente reversibile a causa della sua indipendenza dall'architettura. Ciò che diventa complicato è decompilare un linguaggio come C. Hex Rays fornisce un decodificatore C, ma C è un complicato linguaggio. Esistono 10 modi diversi per eseguire lo stesso compito. Ciò che può essere fatto in 20 righe, può essere fatto in 3, o 10. È l' interpretazione del linguaggio che rende difficile l'automazione della decompilazione.

Certo, puoi decompilare C alle sue istruzioni più semplicistiche. Quindi ottieni linee come **(*var1) = 3; o (*bytecode)(param1) che possono essere chiamate a un puntatore a funzione. Quel che è peggio è che devi ricordare che questi sono ancora solo un'interpretazione . Non posso sottolineare abbastanza. Cosa succede se l'interpretazione è sbagliata? Questo è qualcosa di cui ti devi preoccupare a livello di disassemblaggio, ma almeno ci sono una quantità ragionevole di risultati per 5-6 byte per un'istruzione. Ora devi interpretare 15-20 byte per capire una chiamata di funzione o un ciclo for. Se ci sono tecniche di ingegneria anti-reverse, rende l'interpretazione ancora più difficile.

Il contesto gioca un ruolo enorme. Qual è la differenza tra un puntatore a funzione, un puntatore char * e un uint32 ? Assolutamente nulla, tranne il contesto in cui è stato utilizzato. Le ottimizzazioni del compilatore potrebbero utilizzare __fastcall anziché __stdcall . Il che significa che ora devi interpretare i parametri per le funzioni; in pila o in un registro? Funzioni inline, macro, #defines diventeranno tutti parte di una subroutine più grande. Non esiste un modo reale per interpretare questi tipi di contesti.

    
risposta data 22.06.2015 - 20:58
fonte
16

È possibile ricreare automaticamente qualcosa che assomiglia al codice C dall'assemblaggio, ma la quantità di lavoro di supposizione che il decompilatore dovrebbe fare è monumentale.

I compilatori sono cose molto complicate che complicano la trasformazione del codice sorgente. Ottimizzazioni, sostituzioni macro / pre-compilatore, code in-lining, controllo di tipo e degli errori, collegamento statico, ecc. Il decompilatore dovrebbe indovinare (o selezionare per default) quale compilatore hai usato, quali flag del compilatore sono stati impostati, quale versione di quale sistema operativo è stato compilato, quali librerie sono state compilate, ecc.

Quindi, se hai preso un codice C, l'hai rispettato e poi decompilato, il risultato sarebbe stato niente come l'originale.

E questo è solo per produrre codice C che funziona, non abbiamo ancora parlato di leggibilità. Nomi di variabili, nomi di funzioni, ecc, vengono estratti dal compilatore e sostituiti con indirizzi non elaborati, quindi i decompilatori come quello che stai immaginando tipicamente chiamano le tue funzioni A() , B() , C() ... e tutte le variabili a , b , c perché non ha modo di conoscere la semantica (cioè cosa dovrebbero rappresentare queste cose).

La linea di fondo è che chiunque abbia un po 'di esperienza di assemblaggio direbbe che leggere il codice decompilato è in realtà più difficile della lettura dell'assembly raw. (Con alcune eccezioni: Java, ad esempio, decompila in modo abbastanza pulito).

    
risposta data 22.06.2015 - 20:58
fonte
2

Devo ancora trovare un documento o un software che automatizzi completamente il reverse engineering, ma ci sono alcuni campi particolarmente interessati all'automazione per reverse engineering , come l'analisi forense. L'automazione inversa dell'ingegneria non è (almeno al momento) pensata per automatizzare completamente l'intero processo di reverse engineering, ma almeno alcune parti in modo che sia possibile ridimensionare la procedura su un intero file system. Questo è ad esempio descritto in questo articolo :

Introduction

This article will address the growing need for automation in reverse engineering (Reverse Engineering Automation), how the introduction of automation into the research process can save valuable time and aid the retrieval of information without which, either our research would be less thorough, or it would be conducted on a significantly smaller scale.

Also in this article, I will present examples of automation scripts, and will make them accessible via my Github account. I also invite you to add further examples, beyond those examples found in this article, and to send me Pull Requests, so that I can add them.

Why is Automation Needed in Reverse Engineering?

First of all, I feel it is important to point out that Reverse Engineering Automation saves investigation time but does not replace the rest of the process, and secondly, for reasons including the following:

  1. Repeated actions.
  2. Dynamic code fragments that are detected at a later stage of the program (Crypters, Packers).
  3. Bypassing software protections, such as SSDT.
  4. Allocating memory of the software running within Ollydbg

L'articolo prosegue descrivendo alcuni strumenti come OllyDBG-Python e OllyDBG-Playtime e alcuni frammenti di codice che sono anche disponibili qui e qui in opensource.

    
risposta data 22.09.2015 - 19:28
fonte

Leggi altre domande sui tag