Como posso encontrar a estrutura de dados que representa o layout da mina do Campo Minado na memória?

94

Estou tentando aprender sobre engenharia reversa, usando o Campo Minado como um aplicativo de amostra. Eu encontrei este artigo do MSDN sobre um comando WinDbg simples que revela todas as minas, mas é antigo, não é explicado em detalhes e realmente não é o que estou procurando.

Tenho o desmontador IDA Pro e o depurador WinDbg e carreguei o winmine.exe em ambos. Alguém pode fornecer algumas dicas práticas para qualquer um desses programas em termos de encontrar a localização da estrutura de dados que representa o campo minado?

No WinDbg posso definir pontos de interrupção, mas é difícil para mim imaginar em que ponto definir um ponto de interrupção e em que local de memória. Da mesma forma, quando vejo o código estático no IDA Pro, não tenho certeza de onde começar a encontrar a função ou estrutura de dados que representa o campo minado.

Existe algum engenheiro reverso no Stackoverflow que pode me apontar na direção certa?

KingNestor
fonte
27
Que ótima ideia para uma tarefa para os alunos. É uma espécie de laboratório de anatomia com o caça-minas como o gato.
ojblass
3
para os nossos leitores internacionais que podem ficar confusos, o caça-minas é a versão americana do jogo feliz de encontrar flores que vem com o Windows Vista. microsoft.blognewschannel.com/index.php/archives/2006/09/28/…
Kip
16
Feliz jogo de encontrar flores? O_o O politicamente correto foi longe demais.
Eugene
10
Bem, a versão do caça-minas é o padrão, pelo menos na versão sueca do Vista. Suponho que eles adotem a versão de flores felizes em lugares onde as minas tendem a explodir crianças em pedaços.
JesperE
1
Então ... apenas clicar em alguns quadrados aleatórios para ver se eles são minas não ajuda nisso, hein?
Smandoli

Respostas:

125

Parte 1 de 3


Se você é sério em engenharia reversa - esqueça os treinadores e os mecanismos de trapaça.

Uma boa engenharia reversa deve primeiro conhecer o sistema operacional, as funções básicas da API, a estrutura geral do programa (o que é loop de execução, estruturas do Windows, rotinas de tratamento de eventos), formato de arquivo (PE). Os clássicos "Janelas de programação" da Petzold podem ajudar (www.amazon.com/exec/obidos/ISBN=157231995X), bem como MSDN online.

Primeiro você deve pensar sobre onde a rotina de inicialização do campo minado pode ser chamada. Pensei em seguir:

  • Quando você inicia o jogo
  • Quando você clica em cara feliz
  • Quando você clica em Jogo-> Novo ou pressiona F2
  • Quando você muda o nível de dificuldade

Decidi verificar o comando do acelerador F2.

Para localizar o código de manipulação do acelerador, você deve encontrar o procedimento de manipulação de mensagens da janela (WndProc). Ele pode ser rastreado por chamadas CreateWindowEx e RegisterClass.

Ler:

Abra a janela IDA, Importações, encontre "CreateWindow *", vá até ela e use o comando "Jump xref to operand (X)" para ver onde ela é chamada. Deve haver apenas uma chamada.

Agora procure a função RegisterClass e seu parâmetro WndClass.lpfnWndProc acima. Já chamei a função mainWndProc no meu 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

Pressione Enter no nome da função (use 'N' para renomeá-la para algo melhor)

Agora dê uma olhada em

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

Este é o id da mensagem, que no caso de pressionar o botão F2 deve conter o valor WM_COMMAND. Você deve descobrir onde está em comparação com 111h. Isso pode ser feito rastreando edx no IDA ou definindo um ponto de interrupção condicional no WinDbg e pressionando F2 no jogo.

Qualquer uma das formas leva a algo como

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

Clique com o botão direito em 111h e use "Constante simbólica" -> "Usar constante simbólica padrão", digite WM_ e pressione Enter. Agora você deve ter

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

É uma maneira fácil de descobrir os valores de id da mensagem.

Para entender o manuseio do acelerador, verifique:

É muito texto para uma única resposta. Se você estiver interessado, posso escrever mais alguns posts. Longa história curta campo minado armazenado como uma matriz de bytes [24x36], 0x0F mostra que o byte não é usado (jogando campo menor), 0x10 - campo vazio, 0x80 - meu.

Parte 2 de 3


Ok, vamos continuar com o botão F2.

De acordo com o uso de aceleradores de teclado quando o botão F2 é pressionado função wndProc

... recebe uma mensagem WM_COMMAND ou WM_SYSCOMMAND. A palavra de ordem inferior do parâmetro wParam contém o identificador do acelerador.

Ok, já encontramos onde WM_COMMAND é processado, mas como determinar o valor do parâmetro wParam correspondente? É aqui que entra em jogo o Resource hacker . Alimente-o com binários e ele mostra tudo. Como mesa de aceleradores para mim.

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

Você pode ver aqui que o botão F2 corresponde a 510 em wParam.

Agora vamos voltar ao código, que manipula WM_COMMAND. Ele compara wParam com 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 o menu de contexto ou o atalho de teclado 'H' para exibir os valores decimais e você pode ver nosso 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

Isso leva a um pedaço de código que chama algum proc e sai de wndProc.

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

É essa função que inicia um novo jogo? Descubra isso na última parte! Fique ligado.

Parte 3 de 3

Vamos dar uma olhada na primeira parte dessa função

.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

Existem dois valores (dword_10056AC, uValue) lidos nos registros eax e ecx e comparados a outros dois valores (dword_1005164, dword_1005338).

Dê uma olhada nos valores reais usando WinDBG ('bp 01003696'; no intervalo 'p eax; p ecx') - eles pareciam dimensões de campo minado para mim. Jogar com o tamanho do campo minado personalizado mostrou que o primeiro par são novas dimensões e o segundo - dimensões atuais. Vamos definir novos nomes.

.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

Um pouco mais tarde, os novos valores sobrescrevem a corrente e a sub-rotina é chamada

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

E quando eu vi isso

.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

Eu tinha certeza de que havia encontrado um campo minado Causa do ciclo que inicia a matriz de comprimento de bytes de 360h (dword_1005340) com 0xF.

Por que 360h = 864? Existem algumas dicas abaixo de que a linha ocupa 32 bytes e 864 podem ser divididos por 32, então a matriz pode conter 27 * 32 células (embora a IU permita no máximo 24 * 30 campos, há um preenchimento de byte ao redor da matriz para as bordas).

O código a seguir gera as bordas superior e inferior do campo minado (byte 0x10). Espero que você possa ver a iteração do loop nessa bagunça;) Eu tive que usar papel e caneta

.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 o resto da sub-rotina desenha as bordas esquerda e direita

.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

O uso inteligente de comandos WinDBG pode fornecer a você um excelente despejo de campo minado (tamanho personalizado 9x9). Verifique as fronteiras!

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, parece que vou precisar de outro post para fechar o tópico

Stanislav
fonte
1
@Stanislav, boa resposta Stanislav. Se você puder elaborar sobre isso, por favor, faça-o. Essas respostas longas e informativas são as melhores. Talvez um pouco mais sobre como você se concentrou na estrutura de dados do campo minado?
KingNestor
@Stanislav, aceitei sua resposta porque a recompensa de 250 representantes estava terminando. Parabéns!
KingNestor
1
@Stanislav, editei sua resposta de várias partes em uma única resposta. Você não se aproximou do limite de tamanho de sua única resposta e acho que normalmente é preferível ter uma resposta em vez de postar várias. Sinta-se à vontade para editar sua resposta original (esta) e adicioná-la como achar adequado.
mmcdole
2
Além disso, resposta épica Stanislav. Muito obrigado pelo seu trabalho duro!
mmcdole
15

Parece que você está tentando desmontar a fonte, mas o que você precisa fazer é verificar o espaço de memória do programa em execução. O editor hexadecimal HxD tem um recurso que permite exatamente isso.

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

Uma vez no espaço da memória, é uma questão de tirar instantâneos da memória enquanto você mexe no tabuleiro. Isole o que muda e o que não muda. Quando você achar que sabe onde está a estrutura de dados na memória hexadecimal, tente editá-la enquanto ela estiver na memória e ver se a placa muda como resultado.

O processo que você deseja não é diferente de construir um 'treinador' para um videogame. Geralmente, essas informações baseiam-se em descobrir onde valores como saúde e munição vivem na memória e alterá-los em tempo real. Você pode encontrar alguns bons tutoriais sobre como construir treinadores de jogos.

James McMahon
fonte
2
Bem, você ~ pode ~ localizar o local da memória por meio de desmontagem estática. Você pode seguir as instruções de montagem procurando coisas como funções rand () sendo chamadas para gerar o campo de mina e, em seguida, rastrear a partir daí para ver em que local o campo está armazenado na memória (e como).
mmcdole
Ambas as abordagens são desafiadoras. Já tentei desmontar aplicativos no passado e achei muito doloroso. Como exatamente você localiza uma função rand ()?
James McMahon
Obrigado pela sua resposta nemo.
KingNestor
11

Confira este artigo de projeto de código, é um pouco mais detalhado do que a postagem do blog que você mencionou.

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

Editar

E este artigo, embora não seja diretamente sobre o campo minado, fornece um bom guia passo a passo sobre como caçar na memória usando o WinDbg:

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

Editar 2

Novamente, não se trata de caça-minas, mas definitivamente me deu um pouco de reflexão para depurar minha memória. Há uma abundância de tutoriais aqui:

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

Além disso, baixe o CheatEngine (mencionado por Nick D.) e trabalhe no tutorial que vem com ele.

Kirschstein
fonte
9

"No WinDbg posso definir pontos de interrupção, mas é difícil imaginar em que ponto definir um ponto de interrupção e em que local de memória. Da mesma forma, quando vejo o código estático no IDA Pro, não tenho certeza de por onde começar para encontrar a função ou estrutura de dados que representa o campo minado. "

Exatamente!

Bem, você pode procurar rotinas como random () que serão chamadas durante a construção da tabela de minas. Este livro me ajudou muito quando eu estava fazendo experiências com engenharia reversa. :)

Em geral, bons lugares para definir pontos de interrupção são chamadas para caixas de mensagem, chamadas para reproduzir um som, temporizadores e outras rotinas de API win32.

BTW, estou digitalizando o caça-minas agora com OllyDbg .

Atualização: nemo me lembrou uma ótima ferramenta, Cheat Engine de Eric "Dark Byte" Heijnen.

Cheat Engine (CE) é uma ótima ferramenta para observar e modificar o espaço de memória de outros processos. Além dessa facilidade básica , o CE tem mais recursos especiais, como visualizar a memória desmontada de um processo e injetar código em outros processos.

(o valor real desse projeto é que você pode baixar o código-fonte -Delphi- e ver como esses mecanismos foram implementados - eu fiz isso há muitos anos: o)

Nick Dandoulakis
fonte
5

Um bom artigo sobre este mesmo tópico pode ser encontrado em Uninformed . Ele cobre a reversão do Campo Minado (como uma introdução aos aplicativos Win32 de engenharia reversa) em grande detalhe e é um recurso muito bom.

Mrduclaw
fonte
4

Este site pode ser mais útil:

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

A maneira geral de fazer isso é:

  1. Obtenha o código-fonte de alguma forma.
  2. Desmonte e espere que os símbolos restantes possam ajudá-lo.
  3. Adivinhe o tipo de dado e tente manipulá-lo e usar um scanner de memória para limitar as possibilidades.

Em resposta ao Bounty

Bem, em uma segunda leitura, parece que você queria um guia sobre como usar um depurador como o WinDBG, em vez da questão usual de como fazer engenharia reversa. Já mostrei o site que informa os valores que você precisa pesquisar, então a pergunta é: como você pesquisa por isso?

Estou usando o Bloco de notas neste exemplo porque não tenho o Minesweeper instalado. Mas a ideia é a mesma.

texto alternativo

Você digita

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

Pressione "?" E depois "s" para ver a ajuda.

Depois de encontrar o padrão de memória desejado, você pode pressionar alt + 5 para abrir o visualizador de memória para uma boa exibição.

texto alternativo

Leva algum tempo para se acostumar com o WinDBG, mas é tão bom quanto qualquer outro depurador por aí.

Desconhecido
fonte
1
"Obter código-fonte de alguma forma" é uma declaração boba, já que o Campo Minado é enviado sem o código-fonte. E a engenharia reversa com o código-fonte não é engenharia reversa ... é a análise do código-fonte.
mrduclaw
@mrduclaw existem aplicativos que podem descompilar assembly para o idioma de origem. Não existe um termo denominado "análise do código-fonte".
Desconhecido em
1
@Desconhecido Existem aplicativos que tentam reconstruir um programa em uma linguagem fonte a partir de um determinado binário compilado. Mas você não pode obter o "código-fonte" com os comentários e citações do autor de um binário compilado. Claro, alguns desses "descompiladores" fazem um trabalho melhor do que outros, mas não estão fornecendo o código que o autor escreveu (o código otimizado do compilador costuma ser muito diferente do código do programador). E você nunca fez testes de garantia de qualidade? O que ferramentas como PREfast e Sparse fazem? Análise estática de código-fonte.
mrduclaw
A análise estática do código-fonte no PREfast e no Sparse é completamente diferente da leitura manual do código descompilado para hackea-lo. Não acho que alguém iria confundir essas duas ideias diferentes.
Desconhecido em
@Desconhecido, vou além e concordo que você não deve confundir a desmontagem da engenharia reversa com a análise do código-fonte (descompilado ou não, se você tiver a fonte que está executando a análise do código-fonte). Esse foi todo o meu ponto. Então, por favor, pare de confundir os dois. :)
mrduclaw
0

Um bom ponto para iniciar o rastreamento no depurador seria com o mouse para cima. Portanto, encontre o procedimento da janela principal (acho que ferramentas como spyxx podem inspecionar as propriedades do Windows e o endereço do manipulador de eventos é uma delas). Entre nele e descubra onde ele trata os eventos do mouse - haverá uma mudança, se você puder reconhecê-lo no assembler (veja o valor de WM_XXX para mouse up em windows.h).

Coloque um ponto de interrupção lá e comece a intervir. Em algum momento entre o momento em que você soltou o botão do mouse e a atualização da tela, o victum acessará a estrutura de dados que você está procurando.

Seja paciente, tente identificar o que está sendo feito a qualquer momento, mas não se preocupe em examinar muito profundamente o código que você suspeita não ser interessante para seu objetivo atual. Pode levar várias execuções no depurador para acertá-lo.

O conhecimento do fluxo de trabalho de aplicativos win32 normais também ajuda.

Eugene
fonte
0

As minas provavelmente serão armazenadas em algum tipo de matriz bidimensional. Isso significa que é uma matriz de ponteiros ou uma única matriz de booleanos no estilo C.

Sempre que o formulário recebe um evento de mouse-up, essa estrutura de dados é referenciada. O índice será calculado usando as coordenadas do mouse, provavelmente usando divisão inteira. Isso significa que você provavelmente deve procurar por uma cmpinstrução ou semelhante, onde um dos operandos é calculado usando um deslocamento e x, onde xé o resultado de um cálculo envolvendo divisão inteira. O deslocamento será então o ponteiro para o início da estrutura de dados.

Jørgen Fogh
fonte
0

É bastante razoável supor que as informações sobre as minas sejam dispostas de forma contígua na memória, pelo menos para as linhas (ou seja, é uma matriz 2D ou uma matriz de matrizes). Assim, eu tentaria abrir várias células adjacentes na mesma linha, fazer despejos de memória do processo à medida que avançava e, em seguida, compará-los e procurar por quaisquer alterações repetidas na mesma região de memória (ou seja, 1 byte alterado na primeira etapa, a próxima byte alterado para exatamente o mesmo valor na próxima etapa, etc).

Também existe a possibilidade de que seja uma matriz de bits empacotada (3 bits por mina devem ser suficientes para registrar todos os estados possíveis - fechado / aberto, meu / não-mina, sinalizado / não sinalizado), então eu ficaria atento a isso também ( os padrões também seriam repetíveis, embora mais difíceis de detectar). Mas não é uma estrutura conveniente para lidar, e não acho que o uso de memória tenha sido um gargalo para o Campo Minado, então é improvável que esse tipo de coisa seja usado.

Pavel Minaev
fonte
0

Embora não seja estritamente uma "ferramenta de engenharia reversa", e mais um brinquedo que até um idiota como eu poderia usar, uma olhada no Cheat Engine . Isso torna um pouco mais fácil rastrear quais partes da memória foram alteradas, quando, e até mesmo fornece recursos para rastrear as partes alteradas da memória por meio de ponteiros (embora você provavelmente não precise disso). Um bom tutorial interativo está incluído.

Ivan Vučica
fonte