winmine学習ノート


ゲームのコール

  • MessageBoxA call関数
  • OD winmineを開くexeプログラム後crl+gでMessageBoxAを検索すると、MessageBoxA callアドレスに着きます.コード注入ツールでテストします(「注入ツール学習ノート」を参照).間違いありません.
    // ( ), ( ), ( ), (error/warning/ok)
    int MessageBox{
        __in HWND hWnd,
        __in LPSTSTR lpText,
        __in LPCTSTR lpCaption,
        __in UNIT uType
    }
    
  • windowsウィンドウクラス関数
  • // ( ), , , 
    LRESULT CALLBACK WindowProc{
        __in HWND hwnd,
        __in UINT uMsg,
        __in WPARAM wParam,
        __in LPARAM lParam
    }
    // ,WindowProc ,uMsg=WM_COMMAND,wParam ID( )
    
  • 起動:OD winmineを開く.exeプログラム、実行、上のwボタンを押して、リフレッシュして、ルートウィンドウを右クリックして、ClassProcに従って、WindowProcアドレスを見つけることができて、本ルーチンのテストで得たアドレスは01001 BD 2
  • です
  • 希望:WindowProc関数で条件ブレークポイント:uMsg=WM_COMMANDは、不要なメッセージをフィルタリングするために
  • 観察:exeプログラムはuMsgを認識していないため、mov edx、dword ptr ss:[ebp+0 xC]が逆アセンブリされていることを観察し、ついで右上レジスタ領域edxの値が00000111
  • であることに注意する.
  • 点:次の行mov ecx,dword ptr ss:[ebp+0 x 14]右クリック、ブレークポイント、条件ブレークポイント、edx=WM_COMMAND
  • テスト:雷枠によってブレークポイントをトリガーせず、メニューによって初期/中/高級を切り替えるとブレークポイントをトリガーし、条件中断
  • を実現する.
  • mov edx,[arg,2],mov edx,dword ptr ss:[ebp+0 xC]
  • をダブルクリック
  • 右下のスタックアドレスを右クリックし、EBPに対してEBP+Cの値が00000111
  • であることを確認します.
  • EBP+8,+C,+10,+14はそれぞれlocalである.1,2,3,4,ここでlocalは順次呼び出しであることに注意してください.関数呼び出し前のスタックが逆順序で押し込まれていることを知っています.このルーチンのテストで得られた情報は、EBP+8>|00230 A 22 EBP+C>|00000111 EBP+10>|00000209 EBP+14>|00000
  • です.
  • EBP+10の値を読み出し、現在のメニュー項目のIDであり、複数回のテストで得ることができる:開局:0 x 1 FE初級:0 x 209中級:0 x 20 A高級:0 x 20 B

  • ゲームのベースアドレス


    ベースアドレスコンセプト:グローバル変数、文字定数などのアドレス、毎回開く
  • 掃雷インターフェース左上の残りの雷数の値のメモリアドレスを探しに来ました.OEはwinmineを開きます.Exce運転、CE再接続winmine.exe
  • CEは10を検索し、その後、雷区で雷位を右クリックし、CEは9を検索し、値のメモリアドレス0 x 0100594
  • を得た.
  • OD左下db 0 x 01005194でデータ位置を見つけ、右クリック、ブレークポイント、メモリ書き込み
  • さらに右に雷位を打つと、0100346 Eで中断され、命令はadd dword ptr ds:[0 x 1005194]、eax、OD右上EAXの値を表示し、FFFFFFFFFFFFであり、addを結合すると1減少し、間違いなく
  • 命令の0 x 1005194の即時数アドレスが絶対アドレスであり、ebp±やlocalのようなものではないことを見て、ベースアドレスであると判断することができる.

  • MFCコントロールメニュー

    /* VS ctrl+f1 VS , SendMessage FindWindow API 
     SendMessage :
    LRESULT WINAPI SendMessage(
    	_In_ HWND hWnd,
        _In_ UINT Msg,
        _In_ WPARAM wParam,
        _In_ LPARAM lParam
    );
    */
    
    // MFC 4 , 
    void CwinmineDlg::OnBnClickedButton1(){
    	HWND hWnd = ::FindWindow(NULL, _T(" "));
    	if (NULL == hWnd) {
    		::MessageBox(NULL, _T(" "),_T(" "),MB_OK);
    		return ;
    	}
    	::SendMessage(hWnd, WM_COMMAND, 0x209, 0);
    }
    void CwinmineDlg::OnBnClickedButton2(){
    	HWND hWnd = ::FindWindow(NULL, _T(" "));
    	if (NULL == hWnd) {
    		::MessageBox(NULL, _T(" "),_T(" "), MB_OK);
    		return;
    	}
    	::SendMessage(hWnd, WM_COMMAND, 0x20A, 0);
    }
    void CwinmineDlg::OnBnClickedButton3(){
    	HWND hWnd = ::FindWindow(NULL, _T(" "));
    	if (NULL == hWnd) {
    		::MessageBox(NULL, _T(" "), _T(" "), MB_OK);
    		return;
    	}
    	::SendMessage(hWnd, WM_COMMAND, 0x20B, 0);
    }
    void CwinmineDlg::OnBnClickedButton4(){
    	for (int i = 0; i < 3; i++) {
    		OnBnClickedButton1();
    		Sleep(1000);
    		OnBnClickedButton2();
    		Sleep(1000);
    		OnBnClickedButton3();
    		Sleep(1000);
    	}
    }
    // 
    

    MFCベースアドレス読み出し

    // , , , int, m_num_mine
    // , , VS 
    void CwinmineDlg::OnBnClickedButton5(){
    	DWORD pid;
    	HWND hWnd = ::FindWindow(NULL, _T(" "));
    	if (NULL == hWnd) {
    		::MessageBox(NULL, _T(" "), _T(" "), MB_OK);
    		return;
    	}
    	GetWindowThreadProcessId(hWnd, &pid);
    	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    	if (NULL == hProcess) {
    		::MessageBox(NULL, _T(" "), _T(" "), MB_OK);
    		return;
    	}
    	ReadProcessMemory(hProcess, (LPCVOID)0x1005194, &m_num_mine, sizeof(m_num_mine), &pid);
    	UpdateData(FALSE);
    }
    

    CE雷域情報の検索

  • 掃雷ゲームを開き、CEを開き掃雷ゲームを導入し、現在の目標は左上のチェックのメモリアドレス
  • を見つけることです.
  • 最初のグリッドを押すと、最初の検索は不明な初期値
  • です.
  • それから笑顔を押して、更に第1の格を押して、もし2回の第1の格の数字が同じならば再び変動していない数値を探して、同じでないならば再び変動する数値
  • を探します
  • は、候補アドレスが1つしか残っていないまで、前のステップを繰り返し、このノートのテストアドレスは01005361
  • である.
  • CEに候補アドレス01005361を追加し、以下に説明を雷域ベースアドレスに変更し、CTテーブルを保存して次回
  • を読み取る.
  • 下の候補アドレスを右クリックし、関連メモリ領域を参照し、雷領域の格子との関係を観察します.
  • 0 F非雷+未操作
  • 0 E非雷+挿旗
  • 0 D非雷+疑問符
  • 8 Fは雷+未操作
  • である.
  • 8 Eは雷+挿旗
  • 8 Dは雷+疑問符
  • CCは踏中雷
  • 440は0
  • です
  • 41は1
  • です
  • 42は2
  • です
  • 43は3
  • です
  • 44は4
  • です
  • 45は5
  • です
  • 46は6
  • です
  • 47は7
  • です
  • 48は8(カスタム行列雷は999でテストできますが、最大24,3667しかできません)
  • 10は無効領域表示
  • である.
  • 補足:最初に雷を押すと雷の位置が再配置され、最初に雷を押さなければ
  • は再配置されません.
  • 補足:01005361から32バイトを第1グループとし、第1行の雷を表し、最大30バイトまで有効である.すなわち、掃雷ウィンドウには最大30列の雷が
  • ある.
  • 補足:30列の雷領域の場合、最後の2バイトは10であり、1行が30列未満の場合、2つの10の間で0 F
  • を補足する.
  • 補足:01005381から32バイトは第2グループで、第2行の雷を代表して、このように類推して、最大24グループ、つまり掃雷ウィンドウは最大24行の雷
    char a[24][32];// 
    
  • があります
  • カスタムを利用して、異なる行数と列数を絶えず設定し、CEで行列値を得たアドレスをフィルタリングする.本ゲーム補助は異なるレベルに適用されるからである.
  • winmine.exe+5338とwinmine.exe+56 A 8は雷区高
  • winmine.exe+5334とwinmine.exe+56 ACは雷域幅
  • winmine.exeのベースアドレスは01000000です.注意:複数の掃雷を同時に開いても、各掃雷はこのベースアドレスであり、各掃雷間のアドレスは互いに独立しています.つまり4 GBのメモリ
  • があります
  • (しかもFFFFFFFFFFは4 Gアドレスでバイト単位で説明可能)

  • Spy++検索メッセージ

  • microsoftspy++を開き、メッセージボタンを押し、準心アイコンをスキャンウィンドウにドラッグして識別し、メッセージを押してWM_を監視するLUTTONDOWNとWM_LBUTTONUP
  • マウスは順番に雷区の4つの角をクリックして、クリックした座標を得て、それから行列の雷格数を除いて各格の幅を得て、ここでは16を計算して、最も左上の雷格の中心座標は(20,60)
  • です
  • VSヘルプドキュメントでWM_を表示LUTTONDOWNとWM_LUTTONUPのヘルプ説明
  • MFCゲームアシスト


    編集ボックスを作成し、プロパティのマルチ動作Trueを設定します.読み取り専用はTrueです.バインド変数を生成します.変数名m_strshowdata,カテゴリvalue
    ボタンを作成して、文字を説明します:自動的に雷を掃いて、写実的な現代コードをダブルクリックします
    BOOL PostMessage(
    	__in HWND hWnd,
        __in UINT Msg,
        __in WPARAM wParam,
        __in LPARAM lParam,
    )// ,SendMessage 
    
    void CwinmineDlg::OnBnClickedButton6(){
    	DWORD pid;
    	HWND hWnd = ::FindWindow(NULL, _T(" "));
    	if (NULL == hWnd) {
    		::MessageBox(NULL, _T(" "), _T(" "), MB_OK);
    		return;
    	}
    	GetWindowThreadProcessId(hWnd, &pid);
    	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    	if (NULL == hProcess) {
    		::MessageBox(NULL, _T(" "), _T(" "), MB_OK);
    		return;
    	}
    	/*
    		0x01005361 ,0x8F 
    		0x01005338 , 16
    		0x01005334 , 16
    	*/
    	unsigned char gamedata[24][32] = { 0 };
    	if (!ReadProcessMemory(hProcess, (LPCVOID)0x01005361, &gamedata, 24 * 32, &pid)) {
    		::MessageBox(NULL, _T(" "), _T(" "), MB_OK);
    		return;
    	}
    	DWORD rows;
    	if (!ReadProcessMemory(hProcess, (LPCVOID)0x01005338, &rows, sizeof(rows), &pid)) {
    		::MessageBox(NULL, _T(" "), _T(" "), MB_OK);
    		return;
    	}
    	DWORD columns;
    	if (!ReadProcessMemory(hProcess, (LPCVOID)0x01005334, &columns, sizeof(columns), &pid)) {
    		::MessageBox(NULL, _T(" "), _T(" "), MB_OK);
    		return;
    	}
    	m_strshowdata.Empty();
    	CString strTemp = _T("");
    	short gamex = 20;
    	short gamey = 60;
    	unsigned short xypos[2] = { 0 };
    	for (int i = 0; i < rows; i++) {
    		for (int j = 0; j < 32; j++) {
    			if (0x10 == gamedata[i][j]) {
    				break;
    			}
    			xypos[0] = gamex + j * 16;
    			xypos[1] = gamey + i * 16;
    			if (0x8F != gamedata[i][j]) {
    				::PostMessage(hWnd, WM_LBUTTONDOWN, MK_LBUTTON, *(int*)xypos);
    				::PostMessage(hWnd, WM_LBUTTONUP, 0, *(int*)xypos);
    			}
    			strTemp.Format(_T("%02x "), gamedata[i][j]);
    			m_strshowdata += strTemp;
    		}
    		m_strshowdata += _T("\r
    "); } UpdateData(FALSE); }

    広がる

  • 自動掃雷は上の方法のほかに、画像を識別し、人間の思考をシミュレートして解読する方法があります.この方法はCEで雷区のデータを求める必要はありません.雷区の高さと幅は
  • です.