Perché vorresti guardare il codice IL?

6

Stavo leggendo un post sul blog su Channel 9 sul rilascio di un decompilatore .NET / CLR open source. Mi chiedevo perché dovresti decompilare un'applicazione .NET / CLR e osservare il suo codice IL? Sono solo curioso.

[Edit]

E ci sono usi per i decompilatori durante la fase di sviluppo?

[Edit]

Sono un po 'perverso; Voglio sapere quando è stata l'ultima volta che hai usato un decompilatore per un progetto di sviluppo software, e perché?

    
posta skizeey 22.04.2011 - 17:56
fonte

6 risposte

1

Ho dovuto guardarlo più volte di quanto avrei voluto ammettere. L'ultima volta è stato perché abbiamo dovuto migrare un numero di applicazioni a un nuovo server di database. Inclusi in questo set di app c'erano numerosi quelli che avevano una stringa di connessione hard-coded e nessuna sorgente nel controllo di versione. A quel punto hai due opzioni, decompila, correggi e ricompila o usa una voce di file host per impostare come viene risolto il nome del server. Entrambi sono meno che ideali, sebbene la via di decompilazione sia meno dannosa.

Ho anche dovuto usare uno in lue della documentazione per un sistema CMS acquistato dalla mia azienda. La documentazione fornita dal fornitore era spesso sbagliata e incredibilmente incompleta. L'uso di un decompilatore ha risolto una serie di problemi, tra cui la rivelazione di un bug relativo a 64 bit che non avrei mai immaginato esistesse senza un decompilatore.

    
risposta data 25.04.2011 - 02:01
fonte
14

Ci sono diversi motivi per usare un decompilatore, ma tutti si riducono al desiderio di capire come funziona un programma. Alcuni motivi specifici:

  • Se dovuto ad es. un errore del disco hai perso il codice sorgente in un programma che hai scritto, ma hai ancora una versione compilata in giro, e il decompilatore può fare qualcosa di comprensibile, quindi non devi ricominciare da capo. (Per le persone senza controllo di versione e backup, soprattutto)
  • Per capire come aggirare certe protezioni che gli altri inseriscono nei loro programmi. Questo potrebbe essere legale (ad esempio se è necessario per l'interoperabilità), a seconda delle circostanze e delle leggi locali.
  • Allo stesso modo, può aiutare a capire come funziona un formato di file opaco o un protocollo non documentato utilizzato da un programma (in genere anche per l'interoperabilità).
  • Può aiutare a compilare i compilatori - se quello che ottieni non è equivalente a quello che hai inserito, allora c'è un bug da qualche parte. Normalmente l'equivalenza non è banale da decidere, a causa della possibilità che le ottimizzazioni del compilatore modificino la struttura del programma abbastanza estesamente (in effetti, nel caso generale, probabilmente si riduce al problema dell'arresto, rendendolo indecidibile).
  • La pagina di Wikipedia rimanda a un'altra pagina che elenca una serie di altri usi: "Perché la decompilazione? "

[EDIT] Altri ancora dai commenti:

  • Osservando come un pezzo di codice è ottimizzato, ad es. per vedere se il codice è ottimizzato nel modo desiderato o per confrontare come sono ottimizzati due pezzi di codice. Ciò può aiutare a scrivere codice più leggibile, assicurando che sia ottimizzato allo stesso modo (o migliore), o sapere se sacrificare la leggibilità potrebbe valerne la pena perché l'ottimizzatore "capisce" meglio il codice.
  • Capire come funziona un pezzo di codice scarsamente documentato.
risposta data 22.04.2011 - 18:18
fonte
4

E ci sono usi per i decompilatori durante la fase di sviluppo?

Ci sono molti usi per questo. Ricorda che il codice che scrivi è tradotto in qualcosa che la macchina può capire. Quello che presumi che stia facendo e quello che fa in realtà possono essere due cose completamente diverse. Un grande esempio è quando hai bisogno di un pezzo di codice molto veloce. Sapere esattamente dove il compilatore rende le sue ottimizzazioni è la chiave (aspetta perché questo metodo viene spinto nello stack ???? ecc.). Puoi guardare il codice e indovinare cosa dovrebbe fare, ma non lo sai finché non guardi realmente a cosa è stato creato.

    
risposta data 22.04.2011 - 19:25
fonte
3

C'è una ragione molto tipica per cui devi consultare IL-code.

Si è verificato un problema con una libreria che si sta utilizzando e che, per qualche motivo, non funziona come previsto (o addirittura non funziona affatto). Non hai la fonte e non hai idea del perché improvvisamente fallisce (o hai una buona idea e hai bisogno di capire un modo per evitare che ciò accada).

Essendo in grado di decompilare il codice, è possibile ottenere una forma leggibile dal punto di vista del programma sottostante, che è quindi possibile analizzare, magari anche eseguire il debug, per capire cosa effettivamente fa il codice e quindi capire cosa è andato storto e come per risolverlo o aggirarlo.

In pratica metti finestre nella scatola nera.

-
E per rispondere alla tua domanda su quanto frequentemente faccio questo: su quasi tutti i progetti, in quanto tutti hanno librerie di terze parti. In media sulla dimensione di circa una volta alla settimana in media.

    
risposta data 24.04.2011 - 23:22
fonte
1

Se stai generando tipi in fase di esecuzione utilizzando Reflection.Emit, l'ispezione di IL è quasi necessaria durante lo sviluppo. È estremamente utile sia per vedere come il codice esistente assomiglia a una guida, sia per garantire che il tuo codice sia generato correttamente (insieme ai test ovviamente).

    
risposta data 23.04.2011 - 02:00
fonte
1

Poco più di 10 anni fa, si avvicinava questa apocalisse. L'anno 2000 era vicino, e c'era tutto questo vecchio software che conservava anni come due cifre e non poteva gestire l'anno 2000. Gli aerei sarebbero caduti dal cielo, le attrezzature ospedaliere stavano per fermarsi e i robot industriali furono andando a ribellarsi contro i loro padroni e sterminare la razza umana.

L'infame bug del millennio. Un non-evento in pratica, ma in gran parte probabilmente perché di tutto il lavoro svolto durante il panico.

Un problema è rappresentato dal fatto che molte banche e altre imprese dipendevano dal software (spesso scritto in COBOL) vecchio di decenni e per il quale il codice sorgente era stato perso da tempo. Avevano rimandato questo problema per molto tempo comprando sempre nuove macchine che erano compatibili con il vecchio, ma non avrebbe funzionato più.

Non so come questi problemi siano stati risolti nella pratica, ma immagino ci fossero tre approcci principali ...

  1. Decompilazione e altri approcci di reverse engineering per creare codice "sorgente" che potrebbe essere corretto.

  2. In casi molto semplici, analisi diretta e patch dei binari - o almeno disassemblaggio piuttosto che decompilazione.

  3. Riqualificazione (di almeno componenti chiave) da zero.

Un caso estremo, ma questo tipo di problema si presenta abbastanza spesso. Fino a poco tempo fa, il controllo di versione del codice sorgente era inusuale e, anche con backup e archiviazione sistematici, a lungo termine ci sono sempre le transizioni da un sistema all'altro dove le cose possono perdere senza che nessuno se ne accorga.

In un certo senso, non è diverso da quella cruciale carta delle polizze assicurative o da qualsiasi altra cosa che non riesci a trovare dall'ultima volta che hai cambiato casa.

Un'altra possibilità è che la decompilazione sia utile per l'apprendimento dei tipi di codice generati dai compilatori esistenti, se stai pensando di scrivere un nuovo compilatore per .NET o una piattaforma simile basata su VM.

    
risposta data 23.04.2011 - 04:36
fonte

Leggi altre domande sui tag