Question:
Décompresser les binaires de manière générique
Remko
2013-03-20 20:25:47 UTC
view on stackexchange narkive permalink

Je trouve que de plus en plus souvent les binaires sont emballés avec des protecteurs exe tels que upx, aspack etc. J'ai essayé de suivre quelques tutoriels sur la façon de les décompresser mais les exemples sont souvent assez faciles alors que mes cibles ne le sont pas.

Je recherche de bonnes ressources et des conseils / astuces sur la façon de décompresser les cibles.

Les [didacticiels lena] (http://tuts4you.com/download.php?list.17) fonctionneront à travers de nombreuses techniques que vous verrez dans de nombreux packers. Il existe des didacticiels qui se concentrent davantage sur le craquage, mais ceux-ci contiennent généralement de bonnes informations.
Connaissez-vous: [Ether: analyse des logiciels malveillants via les extensions de virtualisation matérielle] (http://ether.gtisc.gatech.edu/)
Trois réponses:
Igor Skochinsky
2013-03-20 23:57:25 UTC
view on stackexchange narkive permalink

Le déballage d'un packer d'emballage générique ou d'un crypteur implique généralement les étapes suivantes:

1. Tracez le code, en évitant ou en contournant peut-être les vérifications anti-débogage.

Ce n'est pas difficile avec de simples packers mais cela peut être compliqué avec les plus avancés. Ils peuvent utiliser des contrôles de synchronisation ( rdtsc ), un transfert de contrôle basé sur des exceptions, l'utilisation de registres de débogage pour les calculs, etc. L'utilisation d'une VM ou d'un émulateur ici aide généralement à lutter contre la plupart d'entre eux.

2. Trouvez le point d'entrée d'origine (OEP)

Il y a plusieurs façons de le faire. Parfois, le saut vers OEP est évident quand il suit un morceau de code en boucle et qu'il n'y a rien de raisonnable. Ou vous pouvez reconnaître le code chez OEP si vous connaissez les points d'entrée produits par différents compilateurs. Quelques autres astuces:

  1. si le packer enregistre les registres d'origine avant de déballer, définissez un point d'arrêt matériel sur leur emplacement dans la pile - de cette façon, vous vous casserez dès qu'ils sont restauré avant de passer à OEP.

  2. si, pendant le traçage, vous pouvez identifier la mémoire où le code décompressé est écrit, définissez un point d'arrêt d'exécution de page sur cette plage de mémoire - il se déclenchera après le sauter. IDA vous permet de définir un tel point d'arrêt, et je pense qu'OllyDbg aussi.

  3. définir des points d'arrêt sur les API courantes utilisées par le code de démarrage, par exemple GetCommandLine ou GetVersionEx . Cela ne vous donnera pas l'OEP exact, mais vous pouvez généralement revenir en arrière dans la pile d'appels et le trouver plus ou moins facilement.

3. Vider le code décompressé

Si vous utilisez IDA, vous n'avez pas besoin de vider le fichier dans un fichier séparé - il suffit de prendre un instantané de la mémoire qui copierait les octets de la mémoire vers la base de données afin que vous puissiez les analyser ultérieurement. Une chose à garder à l'esprit ici est que si le packer a utilisé de la mémoire allouée dynamiquement, vous devez la marquer comme "chargeur" ​​pour qu'elle soit incluse dans l'instantané. Plus ici.

4. Restaurer les importations

Je ne sais pas très bien comment cela se fait dans Olly ou dans un autre débogueur, mais AFAIK vous devez utiliser un outil comme ImpREC sur votre vidage et une copie du processus en mémoire.

C'est un peu plus simple (OMI) dans l'IDA. Il vous suffit de trouver la table d'importation et de renommer les pointeurs en fonction des fonctions sur lesquelles ils pointent actuellement (cela devrait être fait pendant que le débogueur est actif). Vous pouvez utiliser le script renimp.idc ou la "fonction de reconstruction manuelle" UUNP (voir ici).

Pour trouver la table d'importation, il y a deux astuces: utilisez parfois:

  • suivez certains appels dans le code de démarrage d'OEP pour trouver des API externes et cela devrait vous conduire à la table d'importation. Habituellement, le début et la fin de la table sont évidents.

  • pendant le déballage, définissez un point d'arrêt sur GetProcAddress et voyez où les résultats sont écrits. Cependant, cela ne fonctionnera pas avec les packers qui utilisent le résultat de l'importation manuelle à l'aide du répertoire d'exportation. Mettre un BP en lecture sur la table d'exportation de kernel32 pourrait aider ici.

5. Nettoyer

Ceci est facultatif mais il peut être utile de supprimer les restes du code du packer qui ne feraient que vous distraire. Dans IDA, vous devez également appliquer une signature FLIRT du compilateur si vous reconnaissez le compilateur utilisé.

6. Créer un exécutable décompressé

Je ne fais pas cette étape car j'ai rarement besoin d'exécuter le fichier décompressé, mais en général, vous devez généralement corriger l'en-tête PE afin que les décalages du code de la section dans le fichier correspondent à ceux dans la décharge.


Maintenant, il existe de nombreuses variantes et astuces qui ne sont pas couvertes par les étapes ci-dessus. Par exemple, certains packers ne résolvent pas entièrement les importations au départ, mais placent des sauts dans les stubs qui résolvent l'importation au premier appel, puis le corrigent pour qu'il passe directement à la cible la prochaine fois. Ensuite, il y a l'approche du «code volé» qui rend plus difficile la recherche et la récupération d'OEP. Parfois, le packer exécute une copie de lui-même et le débogue, de sorte que vous ne pouvez pas y attacher votre propre débogueur (cela peut être résolu en utilisant un émulateur ou un débogueur qui n'utilise pas d'API de débogage comme Intel PIN). Néanmoins, les étapes décrites peuvent couvrir une grande partie de ce qui existe.

Je terminerai par la vidéo réalisée par Elias montrant le processus de déballage du Lighty Compressor: https: //www.hex -rays.com/video/bochs_video_2.html

bonne réponse (+1) et sans aucun doute l'IDA joue un grand rôle en général dans RCE, mais je pense que vous ne devriez pas limiter votre réponse à seulement IDA (ouais, j'ai vu la mention d'ImpRec et OllyDbg).
@0xC0000022L: Je ne suis malheureusement pas familier avec le déballage dans OllyDbg, je ne le connais qu'en théorie. Mais je pense que la plupart de ma réponse peut être utilisée avec n'importe quel débogueur (en fait, je ne dirais pas du tout que c'est "limité" à IDA). Vous pouvez cependant ajouter votre propre réponse sur le déballage dans OllyDbg!
belle réponse, voici un outil: http://ether.gtisc.gatech.edu/
@IgorSkochinsky Je suis en fait très heureux que vous ayez couvert IDA ici car franchement, il y a une tonne d'informations sur la façon de faire cela dans Olly / x64 sur Tuts4You et ailleurs, mais pas beaucoup sur la façon de le faire dans IDA Pro. J'en suis très reconnaissant car j'ai appris une toute nouvelle façon de gérer complètement ce problème dans IDA Pro. Avez-vous d'autres suggestions IDA Pro pour résoudre ce problème plus récent que ce post (plugins / blogs / etc)? Merci Igor.
94c3
2013-03-22 05:28:10 UTC
view on stackexchange narkive permalink

La réponse d'Igor est très bonne. Cependant, les techniques décrites reposent sur l'hypothèse qu'à un moment donné, l'exécutable est décompressé en mémoire. Ce n'est pas toujours vrai. Les obfusactors de virtualisation compilent le binaire d'origine dans un jeu d'instructions personnalisé lorsqu'il est exécuté par un simulateur au moment de l'exécution. Si vous rencontrez un binaire obscurci de cette manière, vous n'avez pas d'autre choix que d'écrire un désassembleur à partir du jeu d'instructions personnalisé dans un jeu d'instructions que vous comprenez.

Oui, j'ai mentionné que je parlais d'emballage d'emballage.
Eh bien, techniquement, même les protecteurs de VM laissent le fichier décompressé en mémoire, c'est-à-dire qu'ils fonctionnent toujours comme des «emballeurs d'emballage». La seule différence est qu'il est beaucoup plus difficile de comprendre le code qui est protégé par une VM, même s'il est "à la vue".
@newgre:, cependant, tous ne déballeront pas tout en même temps. Vous risquez donc de vous retrouver avec des morceaux seulement.
Quels VM Packers font cela?
newgre pouvez-vous expliquer comment l'étape 3 du processus d'Igor est possible lorsque la seule chose en mémoire est le bytecode pour un jeu d'instructions aléatoires? La seule façon de vider un exécutable protégé de cette manière est d'écrire un désassembleur pour le bytecode.
Il y a quelques options une fois que vous rencontrez un tel binaire, en voici une - https://github.com/jnraber/VirtualDeobfuscator
rj_
2014-05-10 15:00:42 UTC
view on stackexchange narkive permalink

Le portail Blackstorm contient une énorme collection de didacticiels de déballage Didacticiels du portail Blackstorm

Tuts4You a une autre grande collection de didacticiels de déballage Tuts4You

Cela m'a pris beaucoup de temps au début, mais avec le temps, le déballage est devenu beaucoup plus facile, beaucoup de patience et de pratique ont cependant été nécessaires.



Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 3.0 sous laquelle il est distribué.
Loading...