J'essaie d'en apprendre davantage sur l'ingénierie inverse, en utilisant le démineur comme exemple d'application. J'ai trouvé cet article MSDN sur une simple commande WinDbg qui révèle toutes les mines mais elle est ancienne, n'est pas expliquée en détail et n'est vraiment pas ce que je recherche.
J'ai le désassembleur IDA Pro et le débogueur WinDbg et j'ai chargé winmine.exe dans les deux. Quelqu'un peut-il fournir des conseils pratiques pour l'un ou l'autre de ces programmes afin de trouver l'emplacement de la structure de données qui représente le champ de mines?
Dans WinDbg, je peux définir des points d'arrêt, mais il m'est difficile d'imaginer à quel point définir un point d'arrêt et à quel emplacement mémoire. De même, lorsque je visualise le code statique dans IDA Pro, je ne sais pas par où commencer pour trouver la fonction ou la structure de données qui représente le champ de mine.
Y a-t-il des ingénieurs inverseurs sur Stackoverflow qui peuvent me diriger dans la bonne direction?
la source
Réponses:
Partie 1 de 3
Si vous êtes sérieux dans l'ingénierie inverse, oubliez les entraîneurs et les moteurs de triche.
Un bon reverse engineering doit d'abord apprendre à connaître le système d'exploitation, les fonctions principales de l'API, la structure générale du programme (qu'est-ce que la boucle d'exécution, les structures Windows, les routines de gestion des événements), le format de fichier (PE). Les classiques de Petzold "Programming Windows" peuvent aider (www.amazon.com/exec/obidos/ISBN=157231995X) ainsi que MSDN en ligne.
Vous devez d'abord réfléchir à l'endroit où la routine d'initialisation du champ de mines peut être appelée. J'ai pensé à suivre:
J'ai décidé de vérifier la commande d'accélérateur F2.
Pour trouver le code de gestion des accélérateurs, vous devez trouver la procédure de gestion des messages de fenêtre (WndProc). Il peut être retracé par les appels CreateWindowEx et RegisterClass.
Lire:
Ouvrez IDA, la fenêtre Importations, recherchez "CreateWindow *", accédez-y et utilisez la commande "Jump xref to operand (X)" pour voir où elle est appelée. Il ne devrait y avoir qu'un seul appel.
Regardez maintenant ci-dessus pour la fonction RegisterClass et son paramètre WndClass.lpfnWndProc. J'ai déjà nommé la fonction mainWndProc dans mon cas.
Appuyez sur Entrée sur le nom de la fonction (utilisez 'N' pour le renommer en quelque chose de mieux)
Jetez maintenant un œil à
Il s'agit de l'ID de message, qui en cas de pression sur le bouton F2, doit contenir la valeur WM_COMMAND. Vous devez trouver où c'est par rapport à 111h. Cela peut être fait soit en traçant edx dans IDA, soit en définissant un point d'arrêt conditionnel dans WinDbg et en appuyant sur F2 dans le jeu.
De toute façon mène à quelque chose comme
Faites un clic droit sur 111h et utilisez "Constante symbolique" -> "Utiliser la constante symbolique standard", tapez WM_ et Entrée. Tu devrais maintenant avoir
C'est un moyen simple de connaître les valeurs d'identifiant de message.
Pour comprendre la gestion des accélérateurs, consultez:
C'est beaucoup de texte pour une seule réponse. Si vous êtes intéressé, je peux écrire quelques autres articles. Le champ de mines court d'une longue histoire stocké sous forme de tableau d'octets [24x36], 0x0F montre que l'octet n'est pas utilisé (jouant un champ plus petit), 0x10 - champ vide, 0x80 - le mien.
Partie 2 sur 3
Ok, continuons avec le bouton F2.
Selon l' utilisation des accélérateurs de clavier lorsque le bouton F2 est enfoncé, fonction wndProc
Ok, nous avons déjà trouvé où WM_COMMAND est traité, mais comment déterminer la valeur du paramètre wParam correspondante? C'est là que Resource hacker entre en jeu. Nourrissez-le avec du binaire et il vous montre tout. Comme une table d'accélérateurs pour moi.
texte alternatif http://files.getdropbox.com/u/1478671/2009-07-29_161532.jpg
Vous pouvez voir ici, que le bouton F2 correspond à 510 dans wParam.
Revenons maintenant au code, qui gère WM_COMMAND. Il compare wParam avec différentes constantes.
Utilisez le menu contextuel ou le raccourci clavier 'H' pour afficher les valeurs décimales et vous pouvez voir notre saut
Cela conduit à un morceau de code qui appelle certains proc et quitte wndProc.
Est-ce la fonction qui lance un nouveau jeu? Découvrez-le dans la dernière partie! Restez à l'écoute.
Partie 3 sur 3
Jetons un coup d'œil à la première partie de cette fonction
Il y a deux valeurs (dword_10056AC, uValue) lues dans les registres eax et ecx et comparées à deux autres valeurs (dword_1005164, dword_1005338).
Jetez un œil aux valeurs réelles en utilisant WinDBG ('bp 01003696'; on break 'p eax; p ecx') - elles me semblaient être des dimensions de champ de mines. Jouer avec la taille de champ de mines personnalisée a montré que la première paire correspond à de nouvelles dimensions et la seconde à des dimensions actuelles. Définissons de nouveaux noms.
Un peu plus tard, de nouvelles valeurs écrasent le courant et le sous-programme est appelé
Et quand je l'ai vu
J'étais absolument sûr d'avoir trouvé un tableau de champ de mines. Cause du cycle qui comprend un tableau de longueur de 360h octets (dword_1005340) avec 0xF.
Pourquoi 360h = 864? Il y a quelques indices ci-dessous, cette ligne prend 32 octets et 864 peut être divisée par 32, donc le tableau peut contenir 27 * 32 cellules (bien que l'interface utilisateur autorise un champ maximum de 24 * 30, il y a un remplissage d'un octet autour du tableau pour les bordures).
Le code suivant génère des bordures supérieure et inférieure de champ de mines (0x10 octet). J'espère que vous pouvez voir une itération de boucle dans ce désordre;) J'ai dû utiliser du papier et un stylo
Et le reste du sous-programme dessine des bordures gauche et droite
Une utilisation intelligente des commandes WinDBG peut vous fournir un vidage de champ de mines cool (taille personnalisée 9x9). Découvrez les frontières!
Hmm, on dirait que j'aurai besoin d'un autre post pour fermer le sujet
la source
Il semble que vous essayez de démonter la source, mais ce que vous devez faire est de regarder l'espace mémoire du programme en cours d'exécution. L'éditeur hexadécimal HxD a une fonctionnalité qui vous permet justement cela.
Une fois que vous êtes dans l'espace mémoire, il s'agit de prendre des instantanés de la mémoire pendant que vous dérangez avec le tableau. Isolez ce qui change et ce qui ne change pas. Lorsque vous pensez avoir une idée de l'emplacement de la structure de données dans la mémoire hexadécimale, essayez de la modifier pendant qu'elle est en mémoire et voyez si la carte change en conséquence.
Le processus que vous souhaitez n'est pas sans rappeler la construction d'un «formateur» pour un jeu vidéo. Celles-ci sont généralement basées sur la recherche de valeurs telles que la santé et les munitions et leur modification à la volée. Vous pourrez peut-être trouver de bons tutoriels sur la façon de créer des entraîneurs de jeu.
la source
Consultez cet article de projet de code, il est un peu plus détaillé que le billet de blog que vous avez mentionné.
http://www.codeproject.com/KB/trace/minememoryreader.aspx
Éditer
Et cet article, bien qu'il ne concerne pas directement le dragueur de mines, vous donne un bon guide étape par étape sur la recherche dans la mémoire en utilisant WinDbg:
http://www.codingthewheel.com/archives/extracting-hidden-text-with-windbg
Modifier 2
Encore une fois, il ne s'agit pas de dragueur de mines, mais cela m'a certainement donné matière à réflexion pour le débogage de ma mémoire, il y a une multitude de tutoriels ici:
http://memoryhacking.com/forums/index.php
Téléchargez également CheatEngine (mentionné par Nick D.) et suivez le tutoriel qui l'accompagne.
la source
Exactement!
Eh bien, vous pouvez rechercher des routines comme random () qui seront appelées lors de la construction de la table des mines. Ce livre m'a beaucoup aidé lorsque j'expérimentais la rétro-ingénierie. :)
En général, les bons endroits pour définir des points d'arrêt sont les appels aux boîtes de message, les appels pour jouer un son, les minuteries et autres routines API win32.
BTW, je scanne le dragueur de mines en ce moment avec OllyDbg .
Mise à jour: nemo m'a rappelé un excellent outil, Cheat Engine par Eric "Dark Byte" Heijnen.
Cheat Engine (CE) est un excellent outil pour regarder et modifier l'espace mémoire d'autres processus. Au-delà de cette fonctionnalité de base , CE a plus de fonctionnalités spéciales telles que la visualisation de la mémoire désassemblée d'un processus et l'injection de code dans d'autres processus.
(la vraie valeur de ce projet est que vous pouvez télécharger le code source -Delphi- et voir comment ces mécanismes ont été implémentés - je l'ai fait il y a de nombreuses années: o)
la source
Un très bon article sur ce même sujet peut être trouvé à Non informé . Il couvre le déminage inversé (en guise d'introduction à la rétro-ingénierie des applications Win32) de manière assez détaillée et constitue une ressource très intéressante.
la source
Ce site Web pourrait être plus utile:
http://www.subversity.net/reversing/hacking-minesweeper
La manière générale de procéder est la suivante:
En réponse à Bounty
Eh bien, lors d'une deuxième lecture, il semble que vous vouliez un guide sur la façon d'utiliser un débogueur comme WinDBG plutôt que la question habituelle de la rétro-ingénierie. Je vous ai déjà montré le site Web qui vous indique les valeurs que vous devez rechercher, la question est donc de savoir comment la recherchez-vous?
J'utilise Notepad dans cet exemple parce que le démineur n'est pas installé. Mais l'idée est la même.
Vous tapez
Appuyez sur "?" Puis sur "s" pour voir l'aide.
Une fois que vous avez trouvé le modèle de mémoire souhaité, vous pouvez appuyer sur alt + 5 pour faire apparaître la visionneuse de mémoire pour un affichage agréable.
WinDBG prend un certain temps pour s'y habituer, mais il est aussi bon que n'importe quel autre débogueur.
la source
Un bon point pour commencer le traçage dans le débogueur serait la souris vers le haut. Trouvez donc la procédure de la fenêtre principale (je pense que des outils comme spyxx peuvent inspecter les propriétés de Windows et l'adresse du gestionnaire d'événements en fait partie). Entrez-y et trouvez où il gère les événements de la souris - il y aura un interrupteur, si vous pouvez le reconnaître dans l'assembleur (regardez la valeur de WM_XXX pour la souris dans windows.h).
Mettez-y un point d'arrêt et commencez à entrer. Quelque part entre le moment où vous avez relâché le bouton de la souris et la mise à jour de l'écran, le victum accédera à la structure de données que vous recherchez.
Soyez patient, essayez d'identifier ce qui est fait à un moment donné, mais ne vous embêtez pas à examiner trop profondément le code que vous soupçonnez d'être inintéressant pour votre objectif actuel. Cela peut prendre plusieurs exécutions dans le débogueur pour le clouer.
La connaissance du flux de travail normal des applications win32 est également utile.
la source
Les mines seront probablement stockées dans une sorte de tableau bidimensionnel. Cela signifie qu'il s'agit soit d'un tableau de pointeurs, soit d'un seul tableau de style C de booléens.
Chaque fois que le formulaire reçoit un événement "mouse-up", cette structure de données est référencée. L'index sera calculé en utilisant les coordonnées de la souris, probablement en utilisant la division entière. Cela signifie que vous devriez probablement rechercher une
cmp
instruction ou une instruction similaire, où l'un des opérandes est calculé à l'aide d'un décalage etx
, oùx
est le résultat d'un calcul impliquant une division entière. Le décalage sera alors le pointeur vers le début de la structure de données.la source
Il est assez raisonnable de supposer que les informations sur les mines sont disposées de manière contiguë en mémoire au moins pour les lignes (c'est-à-dire qu'il s'agit d'un tableau 2D ou d'un tableau de tableaux). Ainsi, j'essaierais d'ouvrir plusieurs cellules adjacentes dans la même ligne, en effectuant des vidages de mémoire du processus au fur et à mesure, puis je les diffère et je cherche tout changement répété dans la même région de mémoire (c'est-à-dire 1 octet changé à la première étape, la suivante octet changé à exactement la même valeur à l'étape suivante, etc.).
Il est également possible que ce soit un tableau de bits compact (3 bits par mine devraient être suffisants pour enregistrer tous les états possibles - fermé / ouvert, mien / pas de mine, marqué / non marqué), donc je ferais attention à cela aussi ( les motifs seraient également reproductibles, bien que plus difficiles à repérer). Mais ce n'est pas une structure pratique à gérer, et je ne pense pas que l'utilisation de la mémoire soit un goulot d'étranglement pour le démineur, il est donc peu probable que ce genre de chose soit utilisé.
la source
Bien que n'étant pas strictement un "outil d'ingénierie inverse", et plus d'un jouet que même un idiot comme moi pourrait utiliser, consultez Cheat Engine . Il est un peu facile de suivre quelles parties de la mémoire ont changé, quand, et a même des dispositions pour suivre les parties de mémoire modifiées via des pointeurs (bien que vous n'en ayez probablement pas besoin). Un joli tutoriel interactif est inclus.
la source