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?


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


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.


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.


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)


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.


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


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.


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.


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.


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.