メモリ内のマインスイーパのマインレイアウトを表すデータ構造を見つけるにはどうすればよいですか?


94

マインスイーパをサンプルアプリケーションとして使用して、リバースエンジニアリングについて学習しようとしています。すべての鉱山を明らかにする単純なWinDbgコマンドに関するこのMSDNの記事を見つけましたが、それは古く、詳細には説明されておらず、本当に探しているものではありません。

私が持っているIDA Proの逆アセンブラWinDbgデバッガーをし、私はそれらの両方にwinmine.exeをロードしました。誰かが地雷原を表すデータ構造の場所を見つけるという観点から、これらのプログラムのいずれかに実用的なヒントを提供できますか?

WinDbgではブレークポイントを設定できますが、ブレークポイントを設定するポイントとメモリの場所を想像するのは困難です。同様に、IDA Proで静的コードを表示すると、地雷原のフィールドを表す関数またはデータ構造をどこから探し始めればよいかわかりません。

私を正しい方向に向けることができるStackoverflowのリバースエンジニアはいますか?


27
学生のための宿題としては素晴らしいアイデアです。マインスイーパを猫とする解剖学のようなものです。
ojblass 2009年

3
混乱するかもしれない海外の読者にとって、マインスイーパは、Windows Vistaに同梱されているハッピーフラワーファインディングゲームのアメリカ版です。microsoft.blognewschannel.com/index.php/archives/2006/09/28/...
キップ

16
幸せな花探しゲーム?O_o政治的正しさが行き過ぎている。
ユージーン

10
まあ、マインスイーパバージョンは、少なくともスウェーデン語バージョンのVistaではデフォルトです。私は、地雷が実際に子供たちを粉々に吹き飛ばそうとする場所で、ハッピーフラワーバージョンにデフォルトすると思います。
JesperE 2009

1
ですから、ランダムな正方形をクリックして、それらが地雷かどうかを確認するだけでは、役に立ちませんね。
スマンドリ2009

回答:


125

3のパート1


あなたがリバースエンジニアリングに真剣であるならば-トレーナーとチートエンジンを忘れてください。

優れたリバースエンジニアは、最初にOS、コアAPI関数、プログラムの一般的な構造(実行ループとは何か、Windows構造、イベント処理ルーチン)、ファイル形式(PE)を知る必要があります。Petzoldのクラシックな「Programming Windows」は、オンラインMSDNだけでなく(www.amazon.com/exec/obidos/ISBN=157231995X)にも役立ちます。

最初に、地雷原初期化ルーチンを呼び出すことができる場所について考える必要があります。私は次のことを考えました:

  • ゲームを起動すると
  • 幸せそうな顔をクリックすると
  • 「ゲーム」->「新規」をクリックするか、F2キーを押したとき
  • レベル難易度を変更したとき

F2加速器コマンドをチェックすることにしました。

アクセラレータ処理コードを見つけるには、ウィンドウメッセージ処理手順(WndProc)を見つけます。CreateWindowExとRegisterClassの呼び出しによって追跡できます。

読むには:

IDAの[インポート]ウィンドウを開き、「CreateWindow *」を見つけてそこにジャンプし、「Jump xref to operand(X)」コマンドを使用して、それが呼び出される場所を確認します。呼び出しは1つだけです。

ここで、RegisterClass関数とそのパラメーターWndClass.lpfnWndProcを探します。私の場合、関数にはすでにmainWndProcという名前を付けています。

.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

関数名でEnterキーを押します( 'N'を使用して名前をより適切な名前に変更します)

今見てください

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

これはメッセージIDであり、F2ボタンを押した場合はWM_COMMAND値が含まれます。あなたはそれが111hと比較される場所を見つけることです。これは、IDAでedxをトレースダウンするか、WinDbgで条件付きブレークポイント設定して、ゲームでF2を押すことで実行できます。

どちらの方法でも

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

111hを右クリックして、「記号定数」->「標準記号定数を使用」を使用し、WM_と入力してEnterキーを押します。あなたは今持っているべきです

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

これは、メッセージID値を見つける簡単な方法です。

アクセラレータの処理を理解するには、以下を確認してください。

単一の回答にはかなりの量のテキストです。興味があれば、別の投稿をいくつか書けます。長い地雷の地雷原はバイトの配列[24x36]として保存され、0x0Fはバイトが使用されていないことを示します(小さいフィールドを再生)、0x10-空のフィールド、0x80-地雷。

3のパート2


では、F2ボタンを押しましょう。

F2ボタンが押されたときのキーボードアクセラレータの使用によると、wndProc関数

... WM_COMMANDまたはWM_SYSCOMMANDメッセージを受け取ります。wParamパラメータの下位ワードには、アクセラレータの識別子が含まれています。

OK、すでにWM_COMMANDが処理される場所を見つけましたが、対応するwParamパラメータ値を決定する方法は?ここでリソースハッカーが活躍します。バイナリをフィードすると、すべてが表示されます。アクセラレータテーブルのように。

代替テキストhttp://files.getdropbox.com/u/1478671/2009-07-29_161532.jpg

F2ボタンがwParamの510に対応していることがわかります。

次に、WM_COMMANDを処理するコードに戻りましょう。wParamをさまざまな定数と比較します。

.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

コンテキストメニューまたは 'H'キーボードショートカットを使用して10進値を表示すると、ジャンプを確認できます

.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

これは、いくつかのprocを呼び出し、wndProcを終了するコードチャンクにつながります。

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

それは新しいゲームを開始する機能ですか?最後の部分でそれを見つけてください!乞うご期待。

3のパート3

その関数の最初の部分を見てみましょう

.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

レジスタeaxとecxに読み込まれ、別の2つの値(dword_1005164、dword_1005338)と比較される2つの値(dword_10056AC、uValue)があります。

WinDBGを使用して実際の値を見てみましょう( 'bp 01003696';休憩 'p eax; p ecx')-私にとって地雷原の寸法のように見えました。カスタム地雷原のサイズで遊んでみると、最初のペアは新しい次元であり、2番目-現在の次元であることがわかりました。新しい名前を設定しましょう。

.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

少し後で新しい値が現在の値を上書きし、サブルーチンが呼び出されます

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

そしてそれを見たとき

.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

私は地雷原の配列を見つけたと完全に確信していました。360xバイト長の配列(dword_1005340)を0xFで初期化するサイクルの原因。

360h = 864なのはなぜですか?その行の下にはいくつかの手がかりがあり、行は32バイトを取り、864は32で割ることができるため、配列は27 * 32のセルを保持できます(UIは最大24 * 30のフィールドを許可しますが、境界の配列の周りに1バイトのパディングがあります)。

次のコードは地雷原の上部と下部の境界線(0x10バイト)を生成します。私はあなたがその混乱の中でループ反復を見ることができることを望みます;)私は紙とペンを使わなければなりませんでした

.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

そして、残りのサブルーチンは左と右の境界を描画します

.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

WinDBGコマンドをスマートに使用すると、地雷原のクールなダンプ(カスタムサイズ9x9)を提供できます。国境をチェック!

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

うーん、トピックを閉じるには別の投稿が必要なようです


1
@スタニスラフ、良い答えはスタニスラフ。もう少し詳しく説明できる場合は、そうしてください。これらの長く有益な回答が最適です。おそらく、地雷原のデータ構造をどのように調整したかについてもう少し詳しく教えてください。
KingNestor 2009

@スタニスラフ、250名のバウンティが終了していたので、私はあなたの答えを受け入れました。おめでとう!
KingNestor 2009

1
@スタニスラフ、私はあなたのマルチパートの回答を単一の回答に編集しました。単一の回答のサイズ制限に近づいていないため、通常は複数の投稿よりも1つの回答の方が好ましいと思います。元の回答(これ)を自由に編集し、必要に応じて追加してください。
mmcdole 2009

2
また、壮大な答えはスタニスラフ。お疲れ様でした!
mmcdole 2009

15

ソースを逆アセンブルしようとしているようですが、実行する必要があるのは、実行中のプログラムのメモリ空間を調べることです。16進エディタHxDには、それを可能にする機能があります。

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

メモリ空間に入ったら、ボードをいじくり回しながらメモリのスナップショットを撮るだけです。変化するものと変化しないものを切り分けます。データ構造が16進数のメモリ内のどこにあるかを把握している場合は、メモリ内にある間に編集してみて、ボードが変化するかどうかを確認してください。

あなたが望むプロセスは、ビデオゲームの「トレーナー」を構築することと同じです。それらは通常、健康や弾薬のような値がメモリのどこにあるかを見つけ、その場でそれらを変更することに基づいています。ゲームトレーナーを構築する方法についての良いチュートリアルを見つけることができるかもしれません。


2
さて、あなたは静的な逆アセンブリを介してメモリの場所を見つけることができます。アセンブリ命令をたどって、rand()関数のようなものを探して地雷原を生成し、そこからトレースして、フィールドがメモリに格納されている場所(および方法)を確認できます。
mmcdole 2009

どちらのアプローチも困難です。私は過去にアプリケーションを逆アセンブルしようとしましたが、非常に苦痛であることがわかりました。どのくらい正確にrand()関数を見つけますか?
James McMahon、

回答ネモありがとうございます。
KingNestor 2009

11

このコードプロジェクトの記事を確認してください。これは、あなたが言及したブログ投稿よりも少し詳細です。

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

編集する

この記事では、マインスイーパについては直接触れていませんが、WinDbgを使用してメモリを探索するためのステップバイステップガイドを示しています。

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

編集2

繰り返しになりますが、これはマインスイーパに関するものではありませんが、私のメモリデバッグについて考えるための食料を確実に与えてくれました。ここには豊富なチュートリアルがあります。

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

また、CheatEngine(Nick Dが言及)をダウンロードして、付属のチュートリアルを実行してください。


9

「WinDbgではブレークポイントを設定できますが、ブレークポイントを設定するポイントとメモリ位置を想像するのは困難です。同様に、IDA Proで静的コードを表示するとき、どこから始めればよいかわかりません。地雷原を表す関数またはデータ構造を見つける。」

丁度!

さて、あなたは、rans()のようなルーチンを探すことができます。これは、マインズテーブルの構築中に呼び出されます。このは、リバースエンジニアリングを試すときに非常に役立ちました。:)

一般に、ブレークポイントを設定するための適切な場所は、メッセージボックスの呼び出し、サウンドを再生する呼び出し、タイマー、およびその他のwin32 APIルーチンです。

ところで、私は現在、OlylyDbgで掃海艇をスキャンしています

更新: nemoは私に素晴らしいツール、Eric "Dark Byte" HeijnenによるCheat Engineを思い出させました。

Cheat Engine(CE)は、他のプロセスのメモリ空間を監視および変更するための優れたツールです。その基本的な機能に加えて、CEには、プロセスの逆アセンブルされたメモリの表示や他のプロセスへのコードの挿入など、より特別な機能があります。

(そのプロジェクトの真の価値は、ソースコード-Delphi-をダウンロードして、それらのメカニズムがどのように実装されたかを確認できることです-私は何年も前にそれを行いました:o)


5

このトピックに関するかなり良い記事はUninformedにあります。マインスイーパのリバースエンジニアリング(Win32アプリのリバースエンジニアリングの概要として)を非常に詳細に説明しており、すべてが非常に優れたリソースです。


4

このウェブサイトはもっと役立つかもしれません:

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

これを行う一般的な方法は次のとおりです。

  1. どういうわけかソースコードを入手してください。
  2. 分解し、残ったシンボルが役立つことを願っています。
  3. データ型を推測して操作し、メモリスキャナーを使用して可能性を制限してください。

バウンティに応えて

さて、2回目の読みでは、リバースエンジニアリングの方法に関する通常の質問ではなく、WinDBGのようなデバッガーの使用方法に関するガイドが必要であるように見えます。検索する必要がある値を説明するWebサイトを既に示したので、問題は、どのように検索するかです。

マインスイーパがインストールされていないため、この例ではメモ帳を使用しています。しかし、考え方は同じです。

代替テキスト

あなたがタイプする

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

ヘルプを表示するには、「?」、次に「s」を押します。

必要なメモリパターンが見つかったら、Alt + 5を押してメモリビューアを表示し、見栄えをよくします。

代替テキスト

WinDBGは慣れるまでに時間がかかりますが、他のデバッガと同じくらい優れています。


1
マインスイーパはソースなしで送信されるため、「どういうわけかソースコードを取得する」はばかげた発言です。また、ソースを使用したリバースエンジニアリングは、リバースエンジニアリングではありません...ソースコード分析です。
mrduclaw 2009

@mrduclawには、アセンブリをソース言語に逆コンパイルできるアプリケーションがあります。「ソースコード分析」という用語はありません。
不明

1
@Unknown特定のコンパイル済みバイナリからソース言語でプログラムを再構築しようとするアプリケーションがあります。しかし、コンパイルされたバイナリから作者のコメントや引用を含む「ソースコード」を取得することはできません。確かに、これらの「逆コンパイラー」のいくつかは他のものよりも優れていますが、著者が書いたコードを提供していません(コンパイラー最適化コードは、プログラマーのコードとは非常に異なることがよくあります)。また、品質保証テストを行ったことはありませんか?PREfastやSparseなどのツールは何をしますか?静的ソースコード分析。
mrduclaw 2009

PREfastおよびSparseでの静的ソースコード分析は、ハッキングするために逆コンパイルされたコードを手動で読み取ることとはまったく異なります。私は、この2つの異なるアイデアを互いに混同することはないと思います。
不明

@Unknownもう1つ理解し、リバースエンジニアリングの逆アセンブリとソースコード(逆コンパイルされているか、ソースコード分析を実行しているソースがある場合は別の方法で調べる)を混同しないでください。それが私の要点でした。したがって、2つを混同しないでください。:)
mrduclaw 2009

0

デバッガーでトレースを開始するには、マウスを上に置くとよいでしょう。メインウィンドウプロシージャを見つけます(spyxxのようなツールはウィンドウのプロパティを検査でき、イベントハンドラーアドレスもその1つだと思います)。それに侵入して、マウスイベントを処理する場所を見つけます。アセンブラーでそれを認識できる場合は、スイッチがあります(windows.hでマウスアップのWM_XXXの値を確認してください)。

そこにブレークポイントを置き、ステップインを開始します。マウスボタンを離してから画面が更新されるまでの間のどこかで、victumは探しているデータ構造にアクセスします。

辛抱強く、いつでも何が行われているのかを特定するように心がけてください。ただし、現在の目的に興味がないと思われるコードを深く調べすぎないでください。デバッガーでそれを特定するには、いくつかの実行が必要になる場合があります。

通常のwin32アプリケーションワークフローの知識も役立ちます。


0

地雷はおそらく何らかの2次元配列に格納されます。これは、ポインタの配列またはブール値の単一のCスタイル配列のいずれかであることを意味します。

フォームがマウスアップイベントを受信するたびに、このデータ構造が参照されます。インデックスは、おそらく整数除算を使用して、マウス座標を使用して計算されます。つまりcmp、オペランドの1つがオフセットとを使用して計算される、または同様の命令を探す必要がありますx。ここで、xは整数除算を含む計算の結果です。オフセットは、データ構造の先頭へのポインタになります。


0

地雷に関する情報は、少なくとも行についてはメモリ内で連続してレイアウトされていると想定するのはかなり合理的です(つまり、2D配列または配列の配列です)。したがって、私は同じ行の隣接するいくつかのセルを開いて、プロセスのメモリダンプを作成し、それらを比較して、同じメモリ領域で繰り返される変更を探します(つまり、最初のステップで1バイトが変更され、次のステップバイトは次のステップなどで正確に同じ値に変更されました。

また、それがパックされたビット配列である可能性もあります(1鉱山あたり3ビットで、可能なすべての状態(閉鎖/開放、鉱山/非鉱山、フラグ付き/非フラグ付き)を記録するのに十分であるはずです)。パターンは再現可能ですが、見つけるのは困難です)。しかし、これは扱いに便利な構造ではなく、メモリ使用量がマインスイーパのボトルネックであったとは思わないため、この種のものが使用される可能性は低いと考えられます。


0

厳密には「リバースエンジニアのツール」ではありませんが、私のようなバカでさえもおもちゃの多くは、チートエンジンをチェックしてください。これにより、メモリのどの部分がいつ変更されたかを簡単に追跡できるようになり、ポインタを介して変更されたメモリ部分を追跡するための準備ができます(ただし、おそらくそれは必要ありません)。素敵なインタラクティブなチュートリアルが含まれています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.