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?
fuente
Respuestas:
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:
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.
Presione Enter en el nombre de la función (use 'N' para cambiarle el nombre a algo mejor)
Ahora echa un vistazo a
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
Haga clic derecho en 111h y use "Constante simbólica" -> "Usar constante simbólica estándar", escriba WM_ y Enter. Ahora deberías tener
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
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.
Use el menú contextual o el atajo de teclado 'H' para mostrar valores decimales y podrá ver nuestro salto
Conduce a un fragmento de código que llama a algún proceso y sale de wndProc.
¿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.
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.
Un poco más tarde, los nuevos valores sobrescriben la corriente y se llama a la subrutina
Y cuando lo vi
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
Y el resto de la subrutina dibuja los bordes izquierdo y derecho
El uso inteligente de los comandos WinDBG puede proporcionarle un volcado de campo minado genial (tamaño personalizado 9x9). ¡Mira las fronteras!
Mmm, parece que necesitaré otra publicación para cerrar el tema.
fuente
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.
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.
fuente
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.
fuente
¡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)
fuente
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.
fuente
Este sitio web puede ser más útil:
http://www.subversity.net/reversing/hacking-minesweeper
La forma general de hacerlo es:
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.
Usted escribe
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.
Toma un tiempo acostumbrarse a WinDBG, pero es tan bueno como cualquier otro depurador.
fuente
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.
fuente
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
cmp
instrucción o una similar, donde uno de los operandos se calcula usando un desplazamiento yx
, dondex
es 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.fuente
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.
fuente
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.
fuente