/ / Décompiler le code C avec les informations de débogage? - java, c ++, c, ingénierie inverse, décompilation

Décompiler le code C avec les informations de débogage? - java, c ++, c, ingénierie inverse, décompilation

Le code des octets Java et Python est relativement facile à décompiler que le code machine compilé généré par le compilateur C / C ++.

Je suis incapable de trouver une réponse convaincante pour expliquer pourquoiles informations de l'option -g sont insuffisantes pour la décompilation, mais suffisantes pour le débogage? Quel est le contenu supplémentaire contenu dans le code d'octet Python / Java, qui facilite la décompilation?

Réponses:

1 pour la réponse № 1

Je ne parviens pas à trouver de réponse convaincante quant aux raisons pour lesquelles les informations de l'option -g sont insuffisantes pour la décompilation, mais suffisantes pour le débogage?

Les informations de débogage ne contiennent en principe quemappage entre les adresses du code généré et les numéros de ligne des fichiers source. Le débogueur n'a pas besoin de décompiler le code - il vous montre simplement les sources d'origine. Si les fichiers source manquent, le débogueur ne les affichera pas comme par magie.

Cela dit, la présence d’informations de débogage faitdécompilation plus facile. Si les informations de débogage incluent la mise en page des types et prototypes de fonctions utilisés, le décompilateur peut l'utiliser et fournir une décompilation beaucoup plus précise. Dans de nombreux cas, cependant, il sera probablement encore différent de la source originale.

Par exemple, voici une fonction décompilée avec le décompilateur Hex-Rays sans utiliser les informations de débogage:

int __stdcall sub_4050A0(int a1)
{
int result; // eax@1

result = a1;
if ( *(_BYTE *)(a1 + 12) )
{
result = sub_404600(*(_DWORD *)a1);
*(_BYTE *)(a1 + 12) = 0;
}
return result;
}

Comme il ne connaît pas le type de a1, les accès à ses champs sont représentés par des ajouts et des distributions.

Et voici la même fonction après le chargement du fichier de symboles:

void __thiscall mytree::write_page(mytree *this, PAGE *src)
{
if ( src->isChanged )
{
cache::set_changed(this->cache, src->baseAddr);
src->isChanged = 0;
}
}

Vous pouvez voir que cela s’est beaucoup amélioré.

En ce qui concerne les raisons pour lesquelles la décompilation du bytecode est généralement plus facile, outre la vérification de réponse de NPE, ce.


8 pour la réponse № 2

Voici certaines des raisons pour cela:

  1. Les bytecodes Java et Python sont relativement simples et de haut niveau, alors que le jeu d'instructions de certains processeurs (think x86) est terriblement compliqué.
  2. Les bytecodes imitent étroitement la structure de la langue pour laquelle ils ont été conçus.
  3. Lors de la génération de bytecodes, Java et Pythoneffectuer faire très peu par voie d'optimisation. Cela se traduit par des bytecodes qui correspondent étroitement à la structure du code source d'origine. Un bon compilateur C ou C ++ optimisant est capable de produire un assemblage très éloigné du code source original.
  4. Il existe peu de compilateurs Java et Python, et beaucoup deCompilateurs C et C ++. Il est plus facile de produire un décompilateur de haute qualité si vous ciblez un seul compilateur connu (ou un petit ensemble de compilateurs connus).
  5. Python et Java sont des langages relativement simples comparés au C ++ (ce point ne s’applique pas au C).
  6. Les modèles C ++ présentent de nombreux défis pour la décompilation de qualité (ce point ne s’applique pas non plus à C).
  7. Le préprocesseur C / C ++.
  8. En Python, il existe une relation un à unentre les fichiers source et les fichiers bytecode. En Java, la relation est une source pour un ou plusieurs fichiers de code secondaire. En C et C ++, la relation est multiple, avec beaucoup de chevauchement sur le front de la source (pensez aux en-têtes).

0 pour la réponse № 3

Certains processeurs, comme ceux x86, ont des instructionsde longueur variable. Si le contrôle est passé au milieu (= n'importe où après le premier octet) d'une instruction, il peut s'agir également d'une instruction valide (ou de plusieurs instructions). Cela rend difficile le désassemblage non ambigu du code machine. Le code C / C ++ peut exploiter cette fonctionnalité.

Sur certains processeurs et systèmes d’exploitation, il est possible deexécuter les données comme s'il s'agissait de code et utiliser le code comme s'il s'agissait de données. Cela rend difficile de séparer sans ambiguïté les deux. Et, encore une fois, c’est ce que les programmes C / C ++ peuvent souvent faire facilement.

Sur certains processeurs et systèmes d’exploitation, il est facile de générerCode à la volée et exécutez-le et il est possible de modifier le code existant au moment de l'exécution. Cela contribue également aux ambiguïtés de la décompilation du code. Et les programmes C / C ++ peuvent souvent le faire également.

MODIFIER: De plus, certains processeurs ont plusieurs encodages différents pour la même instruction. Par exemple, les processeurs x86 ont 2 instructions mov reg, reg/mem et mov reg/mem, reg. Ceux-ci vous permettent de déplacer des données entre un registre etun emplacement de mémoire (dans les deux sens) et entre deux registres. Ces deux instructions peuvent être utilisées pour transférer des données entre deux registres, mais elles ont des codages différents. Si le programme s'appuie en quelque sorte sur un codage particulier (par exemple, dans le but de valider son intégrité via des sommes de contrôle), alors, à partir du désassemblage, comme suit: mov eax, ebx vous ne pourriez pas dire lequel des deux mov Si c’était à l’origine, si vous essayez de réassembler le démontage, vous risquez de casser le programme.

Vous pouvez utiliser le débogueur pour déboguer un programme avecou sans informations de débogage / symbole. Ces informations facilitent la navigation dans le code et les données, car de nombreuses routines et variables (mais pas nécessairement toutes) peuvent être identifiées et affichées à l’aide de leurs noms et types, et pas uniquement des adresses brutes et des données brutes non typées.

Je suppose que les différents bytecodes sont moins ambigus et plus limités dans ce qu’ils peuvent faire et que c’est ce qui facilite leur décompilation.