La plupart des applications Android ne sont pas compilées en code natif, elles sont compilées en Java, ce qui les fait exécuter en bytecode sur une machine virtuelle.
En conséquence, il est possible de prendre le bytecode, et de générer du code source Java qui se recompilera sur le même bytecode. Toute optimisation a lieu pendant la recompilation dynamique en code natif, qui se produit pour tout code qui est frappé pendant l'exécution, et ne reste dans la VM que jusqu'à ce que le programme se termine.
On ne peut pas récupérer des choses comme les noms de variables ou les commentaires, bien sûr.
Pour les Apps natives sur Android, ou sur une App iOS, elles sont effectivement compilées en code natif.
Pour iOS, si c'est une App JavaScript vivant dans une UIView, de sorte qu'elle s'exécute plus ou moins dans une fenêtre de navigateur, vous pouvez extraire le JavaScript.
A part cela, un certain nombre de transformations dans la compilation sont telles que vous ne pouvez pas récupérer le code source à partir du code compilé.
En fait, c'est un problème N-P Hard que de générer même le code source qui, s'il était exécuté par un compilateur, donnerait le même code objet, parce qu'il n'y a pas de correspondance biunivoque, il y a de l'inlining de fonctions, certaines fonctions sont transformées dans l'optimiseur peephole, il peut y avoir une optimisation du tail call qui ressemble à une instruction de saut, mais qui est en réalité un appel sans push de registre à la fin d'une fonction, et ainsi de suite.
Auparavant, les compilateurs étaient plutôt mauvais en matière d'optimisation et vous pouviez remonter la pente ; de nos jours : pas possible.
Si vous voulez démonter un programme existant, vous devrez investir dans un outil comme IDA Pro, et vous devrez le démonter jusqu'au code d'assemblage.
Du côté positif, le code ARM a une taille d'instruction de longueur fixe, et il est donc possible de distinguer le code des données. Ce n'est pas si facile sur les machines d'architecture x86, avec une longueur d'instruction variable, et vous ne saurez pas nécessairement ce que vous regardez.
Un PPC a également des instructions de longueur fixe, et est donc également déterministe de cette manière.
Mais le mieux que vous obtiendrez, ce sont des contrats d'API hors des bibliothèques, et vous pouvez rencontrer des problèmes en sautant à travers des tables de saut ou des vtables, où ce qui ressemble à des données est en réalité un pointeur de fonction.