Comment puis-je trouver la structure de données qui représente la disposition de la mine de Démineur en mémoire?

94

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?

KingNestor
la source
27
Quelle belle idée de devoir pour les étudiants. C'est un peu comme un laboratoire d'anatomie avec un dragueur de mines comme le chat.
ojblass
3
pour nos lecteurs internationaux qui pourraient être confus, le dragueur de mines est la version américaine du jeu de recherche de fleurs heureux qui est livré avec windows vista. microsoft.blognewschannel.com/index.php/archives/2006/09/28/…
Kip
16
Joyeux jeu de recherche de fleurs? O_o Le politiquement correct est allé trop loin.
Eugene
10
Eh bien, la version démineur est la version par défaut au moins dans la version suédoise de Vista. Je suppose qu'ils utilisent par défaut la version happy-flowers dans des endroits où les mines ont tendance à faire exploser les enfants en morceaux.
JesperE
1
Alors ... le simple fait de cliquer sur des cases aléatoires pour voir si ce sont des mines n'est pas utile pour ça, hein?
Smandoli

Réponses:

125

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:

  • Lorsque vous lancez le jeu
  • Quand tu cliques sur un visage heureux
  • Lorsque vous cliquez sur Jeu-> Nouveau ou appuyez sur F2
  • Lorsque vous changez de niveau de difficulté

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.

.text:0100225D                 mov     [ebp+WndClass.lpfnWndProc], offset mainWndProc
.text:01002264                 mov     [ebp+WndClass.cbClsExtra], edi
.text:01002267                 mov     [ebp+WndClass.cbWndExtra], edi
.text:0100226A                 mov     [ebp+WndClass.hInstance], ecx
.text:0100226D                 mov     [ebp+WndClass.hIcon], eax

.text:01002292                 call    ds:RegisterClassW

Appuyez sur Entrée sur le nom de la fonction (utilisez 'N' pour le renommer en quelque chose de mieux)

Jetez maintenant un œil à

.text:01001BCF                 mov     edx, [ebp+Msg]

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

.text:01001D5B                 sub     eax, 111h
.text:01001D60                 jz      short loc_1001DBC

Faites un clic droit sur 111h et utilisez "Constante symbolique" -> "Utiliser la constante symbolique standard", tapez WM_ et Entrée. Tu devrais maintenant avoir

.text:01001D5B                 sub     eax, WM_COMMAND
.text:01001D60                 jz      short loc_1001DBC

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

... reçoit un message WM_COMMAND ou WM_SYSCOMMAND. Le mot de poids faible du paramètre wParam contient l'identifiant de l'accélérateur.

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.

.text:01001DBC HandleWM_COMMAND:                       ; CODE XREF: mainWndProc+197j
.text:01001DBC                 movzx   eax, word ptr [ebp+wParam]
.text:01001DC0                 mov     ecx, 210h
.text:01001DC5                 cmp     eax, ecx
.text:01001DC7                 jg      loc_1001EDC
.text:01001DC7
.text:01001DCD                 jz      loc_1001ED2
.text:01001DCD
.text:01001DD3                 cmp     eax, 1FEh
.text:01001DD8                 jz      loc_1001EC8

Utilisez le menu contextuel ou le raccourci clavier 'H' pour afficher les valeurs décimales et vous pouvez voir notre saut

.text:01001DBC HandleWM_COMMAND:                       ; CODE XREF: mainWndProc+197j
.text:01001DBC                 movzx   eax, word ptr [ebp+wParam]
.text:01001DC0                 mov     ecx, 528
.text:01001DC5                 cmp     eax, ecx
.text:01001DC7                 jg      loc_1001EDC
.text:01001DC7
.text:01001DCD                 jz      loc_1001ED2
.text:01001DCD
.text:01001DD3                 cmp     eax, 510
.text:01001DD8                 jz      loc_1001EC8 ; here is our jump

Cela conduit à un morceau de code qui appelle certains proc et quitte wndProc.

.text:01001EC8 loc_1001EC8:                            ; CODE XREF: mainWndProc+20Fj
.text:01001EC8                 call    sub_100367A     ; startNewGame ?
.text:01001EC8
.text:01001ECD                 jmp     callDefAndExit  ; default

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

.text:0100367A sub_100367A     proc near               ; CODE XREF: sub_100140C+CAp
.text:0100367A                                         ; sub_1001B49+33j ...
.text:0100367A                 mov     eax, dword_10056AC
.text:0100367F                 mov     ecx, uValue
.text:01003685                 push    ebx
.text:01003686                 push    esi
.text:01003687                 push    edi
.text:01003688                 xor     edi, edi
.text:0100368A                 cmp     eax, dword_1005334
.text:01003690                 mov     dword_1005164, edi
.text:01003696                 jnz     short loc_10036A4
.text:01003696
.text:01003698                 cmp     ecx, dword_1005338
.text:0100369E                 jnz     short loc_10036A4

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.

.text:0100367A startNewGame    proc near               ; CODE XREF: handleButtonPress+CAp
.text:0100367A                                         ; sub_1001B49+33j ...
.text:0100367A                 mov     eax, newMineFieldWidth
.text:0100367F                 mov     ecx, newMineFieldHeight
.text:01003685                 push    ebx
.text:01003686                 push    esi
.text:01003687                 push    edi
.text:01003688                 xor     edi, edi
.text:0100368A                 cmp     eax, currentMineFieldWidth
.text:01003690                 mov     dword_1005164, edi
.text:01003696                 jnz     short loc_10036A4
.text:01003696
.text:01003698                 cmp     ecx, currentMineFieldHeight
.text:0100369E                 jnz     short loc_10036A4

Un peu plus tard, de nouvelles valeurs écrasent le courant et le sous-programme est appelé

.text:010036A7                 mov     currentMineFieldWidth, eax
.text:010036AC                 mov     currentMineFieldHeight, ecx
.text:010036B2                 call    sub_1002ED5

Et quand je l'ai vu

.text:01002ED5 sub_1002ED5     proc near               ; CODE XREF: sub_1002B14:loc_1002B1Ep
.text:01002ED5                                         ; sub_100367A+38p
.text:01002ED5                 mov     eax, 360h
.text:01002ED5
.text:01002EDA
.text:01002EDA loc_1002EDA:                            ; CODE XREF: sub_1002ED5+Dj
.text:01002EDA                 dec     eax
.text:01002EDB                 mov     byte ptr dword_1005340[eax], 0Fh
.text:01002EE2                 jnz     short loc_1002EDA

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

.text:01002EE4                 mov     ecx, currentMineFieldWidth
.text:01002EEA                 mov     edx, currentMineFieldHeight
.text:01002EF0                 lea     eax, [ecx+2]
.text:01002EF3                 test    eax, eax
.text:01002EF5                 push    esi
.text:01002EF6                 jz      short loc_1002F11    ; 
.text:01002EF6
.text:01002EF8                 mov     esi, edx
.text:01002EFA                 shl     esi, 5
.text:01002EFD                 lea     esi, dword_1005360[esi]
.text:01002EFD
.text:01002F03 draws top and bottom borders
.text:01002F03 
.text:01002F03 loc_1002F03:                            ; CODE XREF: sub_1002ED5+3Aj
.text:01002F03                 dec     eax
.text:01002F04                 mov     byte ptr MineField?[eax], 10h ; top border
.text:01002F0B                 mov     byte ptr [esi+eax], 10h       ; bottom border
.text:01002F0F                 jnz     short loc_1002F03
.text:01002F0F
.text:01002F11
.text:01002F11 loc_1002F11:                            ; CODE XREF: sub_1002ED5+21j
.text:01002F11                 lea     esi, [edx+2]
.text:01002F14                 test    esi, esi
.text:01002F16                 jz      short loc_1002F39

Et le reste du sous-programme dessine des bordures gauche et droite

.text:01002F18                 mov     eax, esi
.text:01002F1A                 shl     eax, 5
.text:01002F1D                 lea     edx, MineField?[eax]
.text:01002F23                 lea     eax, (MineField?+1)[eax+ecx]
.text:01002F23
.text:01002F2A
.text:01002F2A loc_1002F2A:                            ; CODE XREF: sub_1002ED5+62j
.text:01002F2A                 sub     edx, 20h
.text:01002F2D                 sub     eax, 20h
.text:01002F30                 dec     esi
.text:01002F31                 mov     byte ptr [edx], 10h
.text:01002F34                 mov     byte ptr [eax], 10h
.text:01002F37                 jnz     short loc_1002F2A
.text:01002F37
.text:01002F39
.text:01002F39 loc_1002F39:                            ; CODE XREF: sub_1002ED5+41j
.text:01002F39                 pop     esi
.text:01002F3A                 retn

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!

0:000> db /c 20 01005340 L360
01005340  10 10 10 10 10 10 10 10-10 10 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005360  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005380  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010053a0  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010053c0  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010053e0  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005400  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005420  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005440  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005460  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005480  10 10 10 10 10 10 10 10-10 10 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010054a0  0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010054c0  0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010054e0  0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................

Hmm, on dirait que j'aurai besoin d'un autre post pour fermer le sujet

Stanislav
la source
1
@Stanislav, bonne réponse Stanislav. Si vous pouvez développer quelque chose, faites-le. Ces réponses longues et informatives sont les meilleures. Peut-être un peu plus sur la façon dont vous vous êtes concentré sur la structure des données du champ de mines?
KingNestor
@Stanislav, j'ai accepté votre réponse parce que la prime de 250 représentants se terminait. Toutes nos félicitations!
KingNestor
1
@Stanislav, j'ai modifié votre réponse en plusieurs parties en une seule réponse. Vous n'avez pas approché la taille limite de votre réponse unique et je pense qu'il est généralement préférable d'avoir une réponse plutôt que d'en publier plusieurs. N'hésitez pas à modifier votre réponse originale (celle-ci) et à y ajouter comme bon vous semble.
mmcdole
2
Aussi, réponse épique Stanislav. Merci beaucoup pour votre travail!
mmcdole
15

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.

http://www.freeimagehosting.net/uploads/fcc1991162.png

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.

James McMahon
la source
2
Eh bien, vous ~ pouvez ~ localiser l'emplacement de la mémoire via un démontage statique. Vous pouvez suivre les instructions d'assemblage en recherchant des choses comme les fonctions rand () appelées pour générer le champ de mine, puis tracer à partir de là pour voir à quel endroit le champ est stocké en mémoire (et comment).
mmcdole
Les deux approches sont difficiles. J'ai essayé de démonter des applications dans le passé et j'ai trouvé que c'était très pénible. Comment repérez-vous exactement une fonction rand ()?
James McMahon
Merci pour ta réponse nemo.
KingNestor
11

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.

Kirschstein
la source
9

"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 mines. "

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)

Nick Dandoulakis
la source
5

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.

mrduclaw
la source
4

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:

  1. Obtenez en quelque sorte le code source.
  2. Démontez et espérez que les symboles restants peuvent vous aider.
  3. Devinez le type de données et essayez de le manipuler et utilisez un scanner de mémoire pour limiter les possibilités.

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.

texte alternatif

Vous tapez

s <options> <memory start> <memory end> <pattern>

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.

texte alternatif

WinDBG prend un certain temps pour s'y habituer, mais il est aussi bon que n'importe quel autre débogueur.

Inconnue
la source
1
"Obtenir le code source d'une manière ou d'une autre" est une déclaration idiote puisque le démineur est envoyé sans source. Et l'ingénierie inverse avec la source n'est pas une ingénierie inverse ... c'est une analyse du code source.
mrduclaw
@mrduclaw il existe des applications qui peuvent décompiler l'assembly dans le langage source. Il n'y a pas de terme appelé "analyse du code source".
Inconnu
1
@ Inconnu Il existe des applications qui tentent de reconstruire un programme dans un langage source à partir d'un binaire compilé donné. Mais vous ne pouvez pas obtenir le "code source" avec les commentaires et les citations de l'auteur à partir d'un binaire compilé. Bien sûr, certains de ces "décompilateurs" font un meilleur travail que d'autres mais ils ne vous donnent pas le code écrit par l'auteur (le code optimisé pour le compilateur est souvent très différent du code du programmeur). Et n'avez-vous jamais fait de test d'assurance qualité? Que font des outils comme PREfast et Sparse? Analyse statique du code source.
mrduclaw
L'analyse statique du code source dans PREfast et Sparse est complètement différente de la lecture manuelle du code décompilé afin de le pirater. Je ne pense pas que quiconque confondrait ces deux idées différentes.
Inconnu
@ Inconnu Je vais plus loin et j'accepte que vous ne devriez pas confondre le désassemblage de l'ingénierie inverse avec la recherche du code source (décompilé ou autre, si vous avez la source que vous effectuez une analyse de code source). C'était tout mon argument. Alors s'il vous plaît, arrêtez de confondre les deux. :)
mrduclaw
0

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.

Eugène
la source
0

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 cmpinstruction ou une instruction similaire, où l'un des opérandes est calculé à l'aide d'un décalage et x, où xest 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.

Jørgen Fogh
la source
0

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é.

Pavel Minaev
la source
0

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.

Ivan Vučica
la source