La maggior parte delle applicazioni Android non sono compilate in codice nativo, sono compilate in Java, che le fa eseguire in bytecode su una macchina virtuale.
Come risultato, è possibile prendere il bytecode, e generare codice sorgente Java che verrà ricompilato nello stesso bytecode. Qualsiasi ottimizzazione avviene durante la ricompilazione dinamica in codice nativo, che avviene per qualsiasi codice che viene colpito durante l'esecuzione, e rimane nella VM solo finché il programma non termina.
Non è possibile recuperare cose come i nomi delle variabili o i commenti, ovviamente.
Per le app native su Android, o su un'app iOS, sono effettivamente compilate in codice nativo.
Per iOS, se si tratta di un'app JavaScript che vive in una UIView, quindi è più o meno in esecuzione in una finestra del browser, è possibile estrarre il JavaScript.
A parte questo, un certo numero di trasformazioni nella compilazione sono tali che non è possibile recuperare il codice sorgente dal codice compilato.
In effetti, è un problema N-P difficile persino generare il codice sorgente, che, se eseguito attraverso un compilatore, risulterebbe nello stesso codice oggetto, perché non c'è una corrispondenza uno-a-uno, c'è l'inlining delle funzioni, alcune funzioni vengono trasformate nell'ottimizzatore peephole, ci può essere l'ottimizzazione della chiamata di coda che sembra un'istruzione di salto, ma che è effettivamente una chiamata senza un push del registro alla fine di una funzione, e così via.
In passato, i compilatori erano piuttosto cattivi nell'ottimizzare e si poteva lavorare per tornare indietro; in questi giorni: non è possibile.
Se volete smontare un programma esistente, dovrete investire in uno strumento come IDA Pro, e dovrete smontarlo in codice assembly.
Sul lato positivo, il codice ARM ha una lunghezza fissa delle istruzioni, e quindi è possibile distinguere il codice dai dati. Questo non è così facile sulle macchine con architettura x86, con istruzioni di lunghezza variabile, e non saprete necessariamente cosa state guardando.
Anche un PPC ha istruzioni di lunghezza fissa, e quindi è deterministico anche in questo modo.
Ma il meglio che otterrete sono contratti API dalle librerie, e potreste incorrere in problemi saltando attraverso tabelle di salto o vtables, dove quelli che sembrano dati sono in realtà puntatori a funzioni.