¿Cómo puedo encontrar la estructura de datos que representa el diseño mío de Buscaminas en la memoria?

94

Estoy tratando de aprender sobre ingeniería inversa, usando Minesweeper como una aplicación de muestra. Encontré este artículo de MSDN sobre un comando simple de WinDbg que revela todas las minas, pero es antiguo, no se explica en detalle y realmente no es lo que estoy buscando.

Tengo el desensamblador IDA Pro y el depurador WinDbg y he cargado winmine.exe en ambos. ¿Alguien puede brindar algunos consejos prácticos para cualquiera de estos programas en términos de encontrar la ubicación de la estructura de datos que representa el campo minado?

En WinDbg puedo establecer puntos de interrupción, pero me resulta difícil imaginar en qué punto establecer un punto de interrupción y en qué ubicación de memoria. De manera similar, cuando veo el código estático en IDA Pro, no estoy seguro de dónde comenzar a encontrar la función o estructura de datos que representa el campo minado.

¿Hay ingenieros inversos en Stackoverflow que me puedan orientar en la dirección correcta?

ReyNestor
fuente
27
Qué gran idea para una tarea para estudiantes. Es como un laboratorio de anatomía con un buscaminas como el gato.
ojblass
3
Para nuestros lectores internacionales que podrían estar confundidos, Minesweeper es la versión estadounidense del feliz juego de búsqueda de flores que se envía con Windows Vista. microsoft.blognewschannel.com/index.php/archives/2006/09/28/…
Kip
16
¿Feliz juego de encontrar flores? O_o La corrección política ha ido demasiado lejos.
Eugene
10
Bueno, la versión del buscaminas es la predeterminada al menos en la versión sueca de Vista. Supongo que por defecto utilizan la versión de flores felices en lugares donde las minas tienden a hacer volar a los niños en pedazos.
JesperE
1
Entonces ... simplemente hacer clic en algunos cuadrados al azar para ver si son minas no es útil para esto, ¿eh?
Smandoli

Respuestas:

125

Parte 1 de 3


Si te tomas en serio la ingeniería inversa, olvídate de los entrenadores y los motores de trampa.

Un buen ingeniero inverso primero debe conocer el sistema operativo, las funciones básicas de la API, la estructura general del programa (qué es el ciclo de ejecución, las estructuras de Windows, las rutinas de manejo de eventos), el formato de archivo (PE). Los clásicos de Petzold "Programming Windows" pueden ayudar (www.amazon.com/exec/obidos/ISBN=157231995X) así como MSDN en línea.

Primero debe pensar en dónde se puede llamar a la rutina de inicialización del campo minado. Pensé en seguir:

  • Cuando inicias el juego
  • Cuando haces clic en la cara feliz
  • Cuando haces clic en Juego-> Nuevo o presionas F2
  • Cuando cambia el nivel de dificultad

Decidí verificar el comando del acelerador F2.

Para encontrar el código de manejo del acelerador, debe buscar el procedimiento de manejo de mensajes de ventana (WndProc). Se puede rastrear mediante llamadas CreateWindowEx y RegisterClass.

Leer:

Abra la ventana IDA, Imports, busque "CreateWindow *", salte a ella y use el comando "Jump xref to operand (X)" para ver dónde se llama. Debería haber una sola llamada.

Ahora mire arriba para la función RegisterClass y su parámetro WndClass.lpfnWndProc. Ya nombré la función mainWndProc en mi caso.

.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

Presione Enter en el nombre de la función (use 'N' para cambiarle el nombre a algo mejor)

Ahora echa un vistazo a

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

Este es el ID del mensaje, que en caso de presionar el botón F2 debe contener el valor WM_COMMAND. Debe encontrar dónde se compara con 111h. Se puede hacer rastreando edx en IDA o estableciendo un punto de interrupción condicional en WinDbg y presionando F2 en el juego.

De cualquier manera conduce a algo como

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

Haga clic derecho en 111h y use "Constante simbólica" -> "Usar constante simbólica estándar", escriba WM_ y Enter. Ahora deberías tener

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

Es una forma sencilla de averiguar los valores de identificación de mensajes.

Para comprender el manejo del acelerador, consulte:

Es bastante texto para una sola respuesta. Si estás interesado puedo escribir otro par de publicaciones. Campo minado corto de la historia larga almacenado como una matriz de bytes [24x36], 0x0F muestra que el byte no se usa (jugando un campo más pequeño), 0x10 - campo vacío, 0x80 - mío.

Parte 2 de 3


Ok, continuemos con el botón F2.

De acuerdo con el uso de aceleradores de teclado cuando se presiona el botón F2 función wndProc

... recibe un mensaje WM_COMMAND o WM_SYSCOMMAND. La palabra de orden inferior del parámetro wParam contiene el identificador del acelerador.

Bien, ya encontramos dónde se procesa WM_COMMAND, pero ¿cómo determinar el valor del parámetro wParam correspondiente? Aquí es donde entra en juego el hacker de recursos . Aliméntelo con binario y le mostrará todo. Como mesa de aceleradores para mí.

texto alternativo http://files.getdropbox.com/u/1478671/2009-07-29_161532.jpg

Puede ver aquí que el botón F2 corresponde a 510 en wParam.

Ahora volvamos al código, que maneja WM_COMMAND. Compara wParam con diferentes 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

Use el menú contextual o el atajo de teclado 'H' para mostrar valores decimales y podrá ver nuestro salto

.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

Conduce a un fragmento de código que llama a algún proceso y sale de wndProc.

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

¿Es esa la función que inicia un nuevo juego? ¡Descúbrelo en la última parte! Manténganse al tanto.

Parte 3 de 3

Echemos un vistazo a la primera parte de esa función.

.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

Hay dos valores (dword_10056AC, uValue) leídos en los registros eax y ecx y comparados con otros dos valores (dword_1005164, dword_1005338).

Eche un vistazo a los valores reales usando WinDBG ('bp 01003696'; en el descanso 'p eax; p ecx'); me parecieron dimensiones de campo minado. Jugar con el tamaño personalizado del campo minado mostró que el primer par son nuevas dimensiones y las segundas dimensiones actuales. Establezcamos nuevos nombres.

.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 poco más tarde, los nuevos valores sobrescriben la corriente y se llama a la subrutina

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

Y cuando lo vi

.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

Estaba completamente seguro de que encontré una matriz de campo minado. Causa del ciclo que inicia su matriz de longitud de bytes de 360 ​​h (dword_1005340) con 0xF.

¿Por qué 360h = 864? Hay algunas señales debajo de que la fila toma 32 bytes y 864 se puede dividir por 32, por lo que la matriz puede contener 27 * 32 celdas (aunque la interfaz de usuario permite un campo máximo de 24 * 30, hay un relleno de un byte alrededor de la matriz para los bordes).

El siguiente código genera los bordes superior e inferior del campo minado (0x10 bytes). Espero que puedas ver la iteración del bucle en ese lío;) Tuve que usar papel y bolígrafo

.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

Y el resto de la subrutina dibuja los bordes izquierdo y derecho

.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

El uso inteligente de los comandos WinDBG puede proporcionarle un volcado de campo minado genial (tamaño personalizado 9x9). ¡Mira las fronteras!

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

Mmm, parece que necesitaré otra publicación para cerrar el tema.

Stanislav
fuente
1
@Stanislav, buena respuesta Stanislav. Si puede ampliarlo, hágalo. Estas respuestas largas e informativas son las mejores. ¿Quizás un poco más sobre cómo se centró en la estructura de datos del campo minado?
KingNestor
@Stanislav, acepté tu respuesta porque la recompensa de 250 representantes estaba terminando. ¡Felicidades!
KingNestor
1
@Stanislav, he editado su respuesta de varias partes en una sola respuesta. No se ha acercado al límite de tamaño de su única respuesta y creo que normalmente se prefiere tener una respuesta en lugar de publicar varias. Siéntase libre de editar su respuesta original (esta) y agregarla como mejor le parezca.
mmcdole
2
Además, épica respuesta Stanislav. ¡Muchas gracias por tu arduo trabajo!
mmcdole
15

Parece que está intentando desmontar la fuente, pero lo que debe hacer es mirar el espacio de memoria del programa en ejecución. El editor hexadecimal HxD tiene una función que le permite precisamente eso.

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

Una vez que estás en el espacio de la memoria, es cuestión de tomar instantáneas de la memoria mientras juegas con el tablero. Aísle lo que cambia frente a lo que no. Cuando crea que sabe dónde se encuentra la estructura de datos en la memoria hexadecimal, intente editarla mientras está en la memoria y vea si la placa cambia como resultado.

El proceso que desea no es diferente a la construcción de un 'entrenador' para un videojuego. Por lo general, se basan en encontrar dónde viven en la memoria valores como la salud y la munición y cambiarlos sobre la marcha. Es posible que pueda encontrar algunos buenos tutoriales sobre cómo crear entrenadores de juegos.

James McMahon
fuente
2
Bueno, ~ puedes ~ localizar la ubicación de la memoria mediante un desmontaje estático. Puede seguir las instrucciones de ensamblaje buscando cosas como las funciones rand () que se llaman para generar el campo minado y luego rastrear desde allí para ver en qué ubicación se almacena el campo en la memoria (y cómo).
mmcdole
Ambos enfoques son desafiantes. Intenté desmontar aplicaciones en el pasado y me resultó muy doloroso. ¿Cómo detecta exactamente una función rand ()?
James McMahon
Gracias por tu respuesta nemo.
KingNestor
11

Consulte este artículo del proyecto de código, es un poco más profundo que la publicación del blog que mencionó.

http://www.codeproject.com/KB/trace/minememoryreader.aspx

Editar

Y este artículo, aunque no trata directamente sobre el buscaminas, le brinda una buena guía paso a paso sobre cómo buscar en la memoria usando WinDbg:

http://www.codingthewheel.com/archives/extracting-hidden-text-with-windbg

Editar 2

Nuevamente, no se trata de buscaminas, pero definitivamente me ha dado algo en que pensar para la depuración de mi memoria, hay una gran cantidad de tutoriales aquí:

http://memoryhacking.com/forums/index.php

Además, descargue CheatEngine (mencionado por Nick D.) y siga el tutorial que viene con él.

Kirschstein
fuente
9

"En WinDbg puedo establecer puntos de interrupción, pero me resulta difícil imaginar en qué punto establecer un punto de interrupción y en qué ubicación de memoria. De manera similar, cuando veo el código estático en IDA Pro, no estoy seguro de por dónde empezar para encontrar la función o estructura de datos que representa el campo minado ".

¡Exactamente!

Bueno, puede buscar rutinas como random () que se llamarán durante la construcción de la tabla de minas. Este libro me ayudó mucho cuando estaba experimentando con la ingeniería inversa. :)

En general, los buenos lugares para establecer puntos de interrupción son las llamadas a los buzones de mensajes, las llamadas para reproducir un sonido, los temporizadores y otras rutinas de la API win32.

Por cierto, estoy escaneando el buscaminas en este momento con OllyDbg .

Actualización: nemo me recordó una gran herramienta, Cheat Engine de Eric "Dark Byte" Heijnen.

Cheat Engine (CE) es una gran herramienta para observar y modificar el espacio de memoria de otros procesos. Más allá de esa facilidad básica , CE tiene características más especiales como ver la memoria desmontada de un proceso e inyectar código en otros procesos.

(el valor real de ese proyecto es que puedes descargar el código fuente -Delphi- y ver cómo se implementaron esos mecanismos; lo hice hace muchos años: o)

Nick Dandoulakis
fuente
5

Se puede encontrar un artículo bastante bueno sobre este mismo tema en Uninformed . Cubre la inversión del Buscaminas (como una introducción a las aplicaciones de ingeniería inversa de Win32) con bastante detalle y es un recurso bastante bueno.

mrduclaw
fuente
4

Este sitio web puede ser más útil:

http://www.subversity.net/reversing/hacking-minesweeper

La forma general de hacerlo es:

  1. De alguna manera obtén el código fuente.
  2. Desmonte y espere que los símbolos sobrantes puedan ayudarlo.
  3. Adivina el tipo de datos e intenta manipularlos y usa un escáner de memoria para limitar las posibilidades.

En respuesta a Bounty

Bueno, en una segunda lectura, parece que desea una guía sobre cómo usar un depurador como WinDBG en lugar de la pregunta habitual de cómo realizar ingeniería inversa. Ya le mostré el sitio web que le dice los valores que necesita buscar, así que la pregunta es, ¿cómo lo busca?

Estoy usando el Bloc de notas en este ejemplo porque no tengo el Buscaminas instalado. Pero la idea es la misma.

texto alternativo

Usted escribe

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

Presione "?" Y luego "s" para ver la ayuda.

Una vez que haya encontrado el patrón de memoria que desea, puede presionar alt + 5 para abrir el visor de memoria para una visualización agradable.

texto alternativo

Toma un tiempo acostumbrarse a WinDBG, pero es tan bueno como cualquier otro depurador.

Desconocido
fuente
1
"Obtener el código fuente de alguna manera" es una afirmación tonta ya que Minesweeper se envía sin fuente. Y la ingeniería inversa con fuente no es ingeniería inversa ... es análisis de código fuente.
mrduclaw
@mrduclaw hay aplicaciones que pueden descompilar el ensamblado en el lenguaje fuente. No existe un término llamado "análisis de código fuente".
Desconocido
1
@Desconocido Hay aplicaciones que intentan reconstruir un programa en un idioma fuente a partir de un binario compilado dado. Pero no se puede obtener "código fuente" con los comentarios y citas del autor de un binario compilado. Seguro, algunos de esos "descompiladores" hacen un mejor trabajo que otros, pero no le dan el código que escribió el autor (el código optimizado para el compilador es a menudo muy diferente del código del programador). ¿Y nunca ha realizado pruebas de control de calidad? ¿Qué hacen herramientas como PREfast y Sparse? Análisis de código fuente estático.
mrduclaw
El análisis de código fuente estático en PREfast y Sparse es completamente diferente a leer manualmente el código descompilado para piratearlo. No creo que nadie confunda esas dos ideas diferentes entre sí.
Desconocido
@Desconocido Lo llevo más allá y estoy de acuerdo en que no debe confundir el desensamblaje de ingeniería inversa con mirar el código fuente (descompilado o de otro modo, si tiene la fuente, está realizando un análisis de código fuente). Ese era mi punto de vista. Así que, por favor, deje de confundir a los dos. :)
mrduclaw
0

Un buen punto para comenzar a rastrear en el depurador sería con el mouse hacia arriba. Entonces, busque el procedimiento de la ventana principal (creo que herramientas como spyxx pueden inspeccionar las propiedades de Windows y la dirección del controlador de eventos es una de ellas). Entra en él y encuentra dónde maneja los eventos del mouse; habrá un interruptor, si puedes reconocerlo en ensamblador (mira el valor de WM_XXX para mouse hacia arriba en windows.h).

Coloque un punto de interrupción allí y comience a intervenir. En algún momento entre el momento en que soltó el botón del mouse y la pantalla se actualiza, el victum accederá a la estructura de datos que está buscando.

Sea paciente, intente identificar lo que se está haciendo en un momento dado, pero no se moleste en buscar demasiado en el código que sospecha no es interesante para su objetivo actual. Puede que sean necesarias varias ejecuciones en el depurador para concretarlo.

El conocimiento del flujo de trabajo normal de las aplicaciones win32 también ayuda.

Eugenio
fuente
0

Las minas probablemente se almacenarán en algún tipo de matriz bidimensional. Esto significa que es una matriz de punteros o una única matriz de booleanos estilo C.

Siempre que el formulario recibe un evento de mouse-up, se hace referencia a esta estructura de datos. El índice se calculará utilizando las coordenadas del ratón, probablemente utilizando la división de enteros. Eso significa que probablemente debería buscar una cmpinstrucción o una similar, donde uno de los operandos se calcula usando un desplazamiento y x, donde xes el resultado de un cálculo que involucra una división de enteros. El desplazamiento será el puntero al comienzo de la estructura de datos.

Jørgen Fogh
fuente
0

Es bastante razonable suponer que la información sobre las minas se presenta contiguamente en la memoria al menos para las filas (es decir, es una matriz 2D o una matriz de matrices). Por lo tanto, intentaría abrir varias celdas adyacentes en la misma fila, haciendo volcados de memoria del proceso a medida que avanzo, y luego diferenciarlos y buscar cambios repetidos en la misma región de memoria (es decir, 1 byte cambiado en el primer paso, el siguiente byte cambiado exactamente al mismo valor en el siguiente paso, etc.).

También existe la posibilidad de que sea una matriz de bits empaquetada (3 bits por mina deberían ser suficientes para registrar todos los estados posibles: cerrado / abierto, mío / no mío, marcado / no marcado), por lo que también buscaría eso ( los patrones también serían repetibles, aunque más difíciles de detectar). Pero no es una estructura conveniente con la que lidiar, y no creo que el uso de la memoria fuera un cuello de botella para Minesweeper, por lo que es poco probable que se use este tipo de cosas.

Pavel Minaev
fuente
0

Si bien no es estrictamente una "herramienta de ingeniería inversa", y es más un juguete que incluso un idiota como yo podría usar, echa un vistazo a Cheat Engine . Hace que sea algo fácil rastrear qué partes de la memoria han cambiado, cuándo, e incluso tiene disposiciones para rastrear las partes de la memoria cambiadas a través de punteros (aunque probablemente no lo necesite). Se incluye un bonito tutorial interactivo.

Ivan Vučica
fuente