Come posso trovare la struttura dati che rappresenta il mio layout di Campo Minato in memoria?


94

Sto cercando di imparare il reverse engineering, utilizzando Campo Minato come applicazione di esempio. Ho trovato questo articolo di MSDN su un semplice comando WinDbg che rivela tutte le mine ma è vecchio, non è spiegato in dettaglio e in realtà non è quello che sto cercando.

Ho il disassemblatore IDA Pro e il debugger WinDbg e ho caricato winmine.exe in entrambi. Qualcuno può fornire alcuni suggerimenti pratici per uno di questi programmi in termini di individuazione della posizione della struttura dati che rappresenta il campo minato?

In WinDbg posso impostare i punti di interruzione, ma è difficile per me immaginare in quale punto impostare un punto di interruzione e in quale posizione di memoria. Allo stesso modo, quando visualizzo il codice statico in IDA Pro, non so nemmeno da dove cominciare a trovare la funzione o la struttura dati che rappresenta il campo minato.

Ci sono Reverse Engineers su Stackoverflow che possono indicarmi la giusta direzione?


27
Che bella idea per un compito per gli studenti. È una specie di laboratorio di anatomia con dragamine come il gatto.
ojblass

3
per i nostri lettori internazionali che potrebbero essere confusi, dragamine è la versione americana del gioco felice alla ricerca di fiori fornito con Windows Vista. microsoft.blognewschannel.com/index.php/archives/2006/09/28/…
Kip

16
Buon gioco di ricerca di fiori? O_o La correttezza politica è andata troppo oltre.
Eugene

10
Ebbene, la versione dragamine è quella predefinita almeno nella versione svedese di Vista. Suppongo che siano predefiniti alla versione dei fiori felici nei luoghi in cui le mine tendono effettivamente a far esplodere i bambini.
JesperE

1
Quindi ... fare clic su alcuni quadrati casuali per vedere se sono mine non è utile per questo, eh?
Smandoli

Risposte:


125

Parte 1 di 3


Se sei seriamente interessato al reverse engineering, dimentica i trainer e i cheat engine.

Un buon reverse engineer dovrebbe prima conoscere il sistema operativo, le funzioni API di base, la struttura generale del programma (cos'è il ciclo di esecuzione, le strutture di Windows, le routine di gestione degli eventi), il formato dei file (PE). I classici "Programming Windows" di Petzold possono aiutare (www.amazon.com/exec/obidos/ISBN=157231995X) così come MSDN online.

Per prima cosa dovresti pensare a dove può essere chiamata la routine di inizializzazione del campo minato. Ho pensato di seguire:

  • Quando avvii il gioco
  • Quando fai clic su faccina felice
  • Quando fai clic su Gioco-> Nuovo o premi F2
  • Quando cambi livello di difficoltà

Ho deciso di controllare il comando dell'acceleratore F2.

Per trovare il codice di gestione dell'acceleratore devi trovare la procedura di gestione dei messaggi della finestra (WndProc). Può essere rintracciato dalle chiamate CreateWindowEx e RegisterClass.

Leggere:

Apri IDA, finestra Imports, trova "CreateWindow *", salta ad esso e usa il comando "Jump xref to operand (X)" per vedere dove viene chiamato. Dovrebbe esserci solo una chiamata.

Ora guarda sopra per la funzione RegisterClass e il suo parametro WndClass.lpfnWndProc. Ho già chiamato la funzione mainWndProc nel mio 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

Premi Invio sul nome della funzione (usa 'N' per rinominarlo in qualcosa di meglio)

Ora dai un'occhiata

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

Questo è l'ID del messaggio, che in caso di pressione del pulsante F2 dovrebbe contenere il valore WM_COMMAND. Devi trovare dove si trova rispetto a 111h. Può essere fatto tracciando edx in IDA o impostando il punto di interruzione condizionale in WinDbg e premendo F2 nel gioco.

In ogni caso porta a qualcosa di simile

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

Fare clic con il tasto destro su 111h e utilizzare "Costante simbolica" -> "Usa costante simbolica standard", digitare WM_ e Invio. Ora dovresti avere

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

È un modo semplice per scoprire i valori degli ID dei messaggi.

Per comprendere la gestione dell'acceleratore, controlla:

È un bel po 'di testo per una singola risposta. Se ti interessa posso scrivere un altro paio di post. Campo minato lungo e breve memorizzato come array di byte [24x36], 0x0F mostra che il byte non è utilizzato (campo più piccolo), 0x10 - campo vuoto, 0x80 - mio.

Parte 2 di 3


Ok, andiamo avanti con il tasto F2.

Secondo Utilizzo degli acceleratori da tastiera quando si preme il pulsante F2 funzione wndProc

... riceve un messaggio WM_COMMAND o WM_SYSCOMMAND. La parola di ordine inferiore del parametro wParam contiene l'identificatore dell'acceleratore.

Ok, abbiamo già trovato dove viene elaborato WM_COMMAND, ma come determinare il valore del parametro wParam corrispondente? È qui che entra in gioco l' hacker di risorse . Alimentalo con binario e ti mostra tutto. Come la tabella degli acceleratori per me.

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

Puoi vedere qui, che il pulsante F2 corrisponde a 510 in wParam.

Ora torniamo al codice, che gestisce WM_COMMAND. Confronta wParam con diverse costanti.

.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

Usa il menu contestuale o la scorciatoia da tastiera "H" per visualizzare i valori decimali e puoi vedere il nostro 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

Porta a un blocco di codice che chiama alcuni proc ed esce da wndProc.

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

È questa la funzione che avvia il nuovo gioco? Scoprilo nell'ultima parte! Rimanete sintonizzati.

Parte 3 di 3

Diamo un'occhiata alla prima parte di quella funzione

.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

Ci sono due valori (dword_10056AC, uValue) letti nei registri eax ed ecx e confrontati con altri due valori (dword_1005164, dword_1005338).

Dai un'occhiata ai valori effettivi usando WinDBG ('bp 01003696'; in pausa 'p eax; p ecx') - mi sembravano dimensioni di campo minato. Giocare con le dimensioni personalizzate del campo minato ha mostrato che la prima coppia sono nuove dimensioni e la seconda - dimensioni attuali. Impostiamo nuovi nomi.

.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 po 'più tardi i nuovi valori sovrascrivono la corrente e viene chiamata la subroutine

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

E quando l'ho visto

.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

Ero completamente sicuro di aver trovato la matrice del campo minato. Causa del ciclo che inits array di 360h byte di lunghezza (dword_1005340) con 0xF.

Perché 360h = 864? Ci sono alcuni segnali sotto quella riga che richiede 32 byte e 864 può essere diviso per 32, quindi l'array può contenere 27 * 32 celle (sebbene l'interfaccia utente consenta un massimo di 24 * 30 campi, c'è un byte che riempie l'array per i bordi).

Il codice seguente genera i bordi superiore e inferiore del campo minato (0x10 byte). Spero che tu possa vedere l'iterazione del loop in quel casino;) Ho dovuto usare carta e penna

.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

E il resto della subroutine disegna i bordi sinistro e destro

.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

L'utilizzo intelligente dei comandi WinDBG può fornire un fantastico dump del campo minato (dimensioni personalizzate 9x9). Controlla i confini!

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, sembra che avrò bisogno di un altro post per chiudere l'argomento


1
@Stanislav, buona risposta Stanislav. Se puoi approfondirlo, fallo. Queste risposte lunghe e informative sono le migliori. Forse un po 'di più su come ti sei concentrato sulla struttura dei dati del campo minato?
KingNestor

@ Stanislav, ho accettato la tua risposta perché la taglia di 250 ripetizioni stava finendo. Congratulazioni!
KingNestor

1
@Stanislav, ho modificato la tua risposta in più parti in un'unica risposta. Non ti sei avvicinato al limite di dimensione della tua singola risposta e penso che in genere sia preferibile avere una risposta piuttosto che postarne diverse. Sentiti libero di modificare la tua risposta originale (questa) e aggiungerla come meglio credi.
mmcdole

2
Inoltre, risposta epica Stanislav. Grazie mille per il tuo duro lavoro!
mmcdole

15

Sembra che tu stia cercando di disassemblare il sorgente, ma quello che devi fare è guardare lo spazio di memoria del programma in esecuzione. L'editor esadecimale HxD ha una funzione che ti consente proprio questo.

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

Una volta che sei nello spazio della memoria, si tratta di scattare istantanee della memoria mentre giochi con la lavagna. Isolare ciò che cambia rispetto a ciò che non lo fa. Quando pensi di avere un controllo su dove si trova la struttura dei dati nella memoria esadecimale, prova a modificarla mentre è in memoria e vedi se la scheda cambia di conseguenza.

Il processo che desideri non è diverso dalla creazione di un "trainer" per un videogioco. Di solito si basano sulla ricerca di dove i valori come la salute e le munizioni vivono nella memoria e sulla loro modifica al volo. Potresti essere in grado di trovare alcuni buoni tutorial su come creare trainer di gioco.


2
Bene, puoi ~ ~ localizzare la posizione della memoria tramite il disassemblaggio statico. Puoi seguire le istruzioni di assemblaggio alla ricerca di cose come le funzioni rand () chiamate per generare il campo minato e quindi tracciare da lì per vedere in quale posizione è memorizzato il campo in memoria (e come).
mmcdole

Entrambi gli approcci sono impegnativi. Ho provato a smontare le applicazioni in passato e l'ho trovato molto doloroso. Come si individua esattamente una funzione rand ()?
James McMahon

Grazie per la tua risposta nemo.
KingNestor

11

Dai un'occhiata a questo articolo sul progetto di codice, è un po 'più approfondito del post del blog che hai menzionato.

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

modificare

E questo articolo, sebbene non riguardi direttamente il dragamine, ti offre una buona guida passo passo sulla caccia nella memoria usando WinDbg:

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

Modifica 2

Ancora una volta, non si tratta di dragamine, ma mi ha sicuramente dato qualche spunto di riflessione per il mio debug della memoria, c'è una vasta gamma di tutorial qui:

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

Inoltre, scarica CheatEngine (menzionato da Nick D.) e segui il tutorial con cui viene fornito.


9

"In WinDbg posso impostare punti di interruzione, ma è difficile per me immaginare in quale punto impostare un punto di interruzione e in quale posizione di memoria. Allo stesso modo, quando visualizzo il codice statico in IDA Pro, non so nemmeno da dove iniziare per trovare la funzione o la struttura dati che rappresenta il campo minato. "

Esattamente!

Bene, puoi cercare routine come random () che verranno chiamate durante la costruzione della tabella delle miniere. Questo libro mi ha aiutato molto quando stavo sperimentando il reverse engineering. :)

In generale, i buoni posti per impostare i punti di interruzione sono le chiamate alle finestre di messaggio, le chiamate per riprodurre un suono, i timer e altre routine API Win32.

A proposito, sto scansionando dragamine in questo momento con OllyDbg .

Aggiornamento: nemo mi ha ricordato un ottimo strumento, Cheat Engine di Eric "Dark Byte" Heijnen.

Cheat Engine (CE) è un ottimo strumento per guardare e modificare lo spazio di memoria di altri processi. Oltre a questa funzionalità di base , CE ha caratteristiche più speciali come la visualizzazione della memoria disassemblata di un processo e l'iniezione di codice in altri processi.

(il vero valore di quel progetto è che puoi scaricare il codice sorgente -Delphi- e vedere come sono stati implementati quei meccanismi - l'ho fatto molti anni fa: o)


5

Un buon articolo su questo argomento può essere trovato su Uninformed . Copre l'inversione di Campo minato (come introduzione alle app Win32 di reverse engineering) in modo abbastanza dettagliato ed è tutt'intorno una risorsa davvero eccezionale.


4

Questo sito potrebbe essere più utile:

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

Il modo generale per farlo è:

  1. In qualche modo ottieni il codice sorgente.
  2. Smonta e spera che i simboli avanzati possano aiutarti.
  3. Indovina il tipo di dati e prova a manipolarlo e usa uno scanner di memoria per limitare le possibilità.

In risposta a Bounty

Bene, in una seconda lettura, sembra che tu voglia una guida su come usare un debugger come WinDBG piuttosto che la solita domanda su come eseguire il reverse engineering. Ti ho già mostrato il sito web che ti dice i valori che devi cercare, quindi la domanda è: come lo cerchi?

Sto utilizzando Blocco note in questo esempio perché non ho installato Campo minato. Ma l'idea è la stessa.

testo alternativo

Tu digiti

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

Premere "?" E poi "s" per visualizzare la guida.

Una volta trovato il modello di memoria che desideri, puoi quindi premere ALT + 5 per aprire il visualizzatore di memoria per una bella visualizzazione.

testo alternativo

WinDBG richiede un po 'di tempo per abituarsi, ma è buono come qualsiasi altro debugger disponibile.


1
"In qualche modo ottieni il codice sorgente" è un'affermazione sciocca poiché Campo Minato viene inviato senza fonte. E il reverse engineering con il sorgente non è il reverse engineering ... è l'analisi del codice sorgente.
mrduclaw

@mrduclaw ci sono applicazioni che possono decompilare l'assembly nella lingua di origine. Non esiste un termine chiamato "analisi del codice sorgente".
Unknown

1
@Sconosciuto Esistono applicazioni che tentano di ricostruire un programma in una lingua di origine da un dato binario compilato. Ma non puoi ottenere il "codice sorgente" con i commenti e le citazioni dell'autore da un file binario compilato. Certo, alcuni di questi "decompilatori" fanno un lavoro migliore di altri ma non ti danno il codice scritto dall'autore (il codice ottimizzato per il compilatore è spesso molto diverso dal codice del programmatore). E non hai mai fatto test di garanzia della qualità? Cosa fanno strumenti come PREfast e Sparse? Analisi statica del codice sorgente.
mrduclaw

L'analisi statica del codice sorgente in PREfast e Sparse è completamente diversa dalla lettura manuale del codice decompilato per hackerarlo. Non credo che nessuno confonderebbe queste due idee diverse l'una con l'altra.
Unknown

@Unknown Lo prendo oltre e accetto che non si debba confondere il disassemblaggio del reverse engineering con l'osservazione del codice sorgente (decompilato o altro, se si dispone della sorgente si esegue l'analisi del codice sorgente). Questo era il mio punto. Quindi, per favore, smettila di confondere i due. :)
mrduclaw

0

Un buon punto per iniziare a tracciare nel debugger sarebbe al passaggio del mouse. Quindi trova la procedura della finestra principale (penso che strumenti come Spyxx possano ispezionare le proprietà di Windows e l'indirizzo del gestore eventi è uno di questi). Entra in esso e trova dove gestisce gli eventi del mouse - ci sarà un interruttore, se puoi riconoscerlo in assembler (guarda il valore di WM_XXX per mouse up in windows.h).

Metti un punto di interruzione lì e inizia a intervenire. Da qualche parte tra il momento in cui hai rilasciato il pulsante del mouse e l'aggiornamento dello schermo, victum accederà alla struttura dati che stai cercando.

Sii paziente, cerca di identificare ciò che viene fatto in un dato momento, ma non preoccuparti di guardare troppo in profondità nel codice che sospetti di essere poco interessante per il tuo obiettivo attuale. Potrebbero essere necessarie diverse esecuzioni nel debugger per risolverlo.

Anche la conoscenza del normale flusso di lavoro delle applicazioni win32 aiuta.


0

Le mine saranno probabilmente immagazzinate in una sorta di matrice bidimensionale. Ciò significa che è un array di puntatori o un singolo array di booleani in stile C.

Ogni volta che il modulo riceve un evento mouse-up, viene fatto riferimento a questa struttura dati. L'indice verrà calcolato utilizzando le coordinate del mouse, probabilmente utilizzando la divisione intera. Ciò significa che probabilmente dovresti cercare cmpun'istruzione o un'istruzione simile, in cui uno degli operandi viene calcolato utilizzando un offset e x, dove xè il risultato di un calcolo che coinvolge la divisione di numeri interi. L'offset sarà quindi il puntatore all'inizio della struttura dati.


0

È abbastanza ragionevole presumere che le informazioni sulle mine siano disposte in modo contiguo in memoria almeno per le righe (cioè si tratta di un array 2D o di un array di array). Quindi, proverei ad aprire diverse celle adiacenti nella stessa riga, eseguendo dump di memoria del processo mentre procedo, quindi diffonderli e cercherò eventuali modifiche ripetute nella stessa regione di memoria (cioè 1 byte cambiato nel primo passaggio, il successivo byte cambiato esattamente allo stesso valore nel passaggio successivo, ecc.).

C'è anche la possibilità che sia un array di bit compresso (3 bit per miniera dovrebbero essere sufficienti per registrare tutti i possibili stati: chiuso / aperto, mio ​​/ non mio, contrassegnato / non contrassegnato), quindi cercherò anche quello ( anche i modelli sarebbero ripetibili, sebbene più difficili da individuare). Ma non è una struttura conveniente da gestire e non penso che l'utilizzo della memoria sia stato un collo di bottiglia per Campo Minato, quindi è improbabile che questo genere di cose venga utilizzato.


0

Sebbene non sia strettamente uno "strumento di reverse engineer", e più di un giocattolo che anche un idiota come me potrebbe usare, dai un'occhiata a Cheat Engine . Rende in qualche modo facile tenere traccia di quali parti della memoria sono cambiate, quando e ha anche disposizioni per tracciare le parti della memoria modificate attraverso i puntatori (anche se probabilmente non ne hai bisogno). È incluso un bel tutorial interattivo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.