Question

Pourquoi est-il si facile à décompiler IL code .NET dans le code source, par rapport à des binaires natifs décompilation x86? (Réflecteur produit assez bon code source la plupart du temps, alors que décompiler la sortie d'un compilateur C ++ est presque impossible.)

Est-ce parce IL contient beaucoup de méta-données? Ou est-ce parce que l'IL est une abstraction plus élevé que les instructions x86? Je l'ai fait des recherches et a trouvé les deux articles suivants usefull, mais aucun d'eux répond à ma question.

Était-ce utile?

La solution

Je pense que vous avez les bits les plus importants déjà.

  • Comme vous le dites, il y a plus de métadonnées disponibles. Je ne connais pas les détails de ce qui est émis par un C ou C ++ compilateur, mais je soupçonne que bien d'autres noms et des informations similaires sont inclus dans IL. Il suffit de regarder ce que le décompilateur sait ce qui est dans un cadre de pile particulier, par exemple - dans la mesure où le x86 est concerné, vous ne savez comment la pile est utilisé ; en IL vous savez ce que le contenu de la pile représentent (ou du moins, le type - pas le sens sémantique)
  • Encore une fois, comme vous l'avez mentionné, IL est une abstraction de niveau plus élevé que x86. x86 n'a aucune idée de ce qu'est un appel de méthode ou la fonction est, ou un événement, ou une propriété, etc. IL a toutes ces informations encore à l'intérieur.
  • En règle générale C et compilateurs C d'optimiser beaucoup plus lourd que (par exemple) le compilateur C #. En effet, le compilateur C # suppose que la plupart de l'optimisation peut être effectuée plus tard encore - par le JIT. D'une certaine façon il est logique pour le compilateur C # pas pour essayer de faire beaucoup d'optimisation, car il y a différents éléments d'information qui sont à la disposition du JIT mais pas le compilateur C #. code optimisé est plus difficile à décompiler, car il est plus loin d'être une représentation naturelle du code source d'origine.
  • IL a été conçu pour être compilé JIT; X 86 a été conçu pour être exécuté en mode natif (certes par micro-code). Les informations du compilateur JIT a besoin est similaire à celle qu'un décompilateur voudrait, donc un décompilateur a un temps plus facile avec IL. À certains égards, cela est vraiment juste une reformulation du deuxième point.

Autres conseils

Il y a un certain nombre de choses qui font l'ingénierie inverse il assez facile.

  • Les informations de type. Ceci est massif. En assembleur x86, vous devez déduire les types de variables en fonction de la façon dont ils sont utilisés.

  • Structure

    . Informations sur la structure de l'application est plus disponible en démontages de IL. Ceci, combiné avec des informations de type, vous donne une quantité incroyable de données. Vous travaillez à un niveau assez élevé à ce point (par rapport à l'assembleur x86). En assembleur natif, vous devez déduire les dispositions de la structure (et même le fait que ce sont des structures) basées sur la façon dont les données sont utilisées. Pas impossible, mais beaucoup plus de temps.

  • noms

    . Connaître les noms des choses peut être utile.

Ces choses, combinées, signifie que vous avez tout à fait un grand nombre de données sur l'exécutable. Il travaille essentiellement à un niveau beaucoup plus proche de la source d'un compilateur de code natif serait. Le niveau supérieur bytecode fonctionne à, plus l'ingénierie inverse est, en général.

C # et IL carte près d'un à un. (Ceci est moins avec quelques nouveaux C # 3.0 caractéristiques.) La proximité de la cartographie (et l'absence d'un optimiseur dans le compilateur C #) rend les choses si « réversible ».

L'extension de réponse de Brian

Si vous pensez que tout IL est facilement decompilable, je vous suggère d'écrire un programme F # non trivial et tenter de décompiler ce code. F # fait beaucoup de transformations de code et a donc une cartographie très pauvre de l'IL et la base de code d'origine émis réelle. À mon humble avis, il est beaucoup plus difficile de regarder le code décompilé F # et récupérer le programme original que pour C # ou VB.Net.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top