日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

扫雷插件分析与编写

發布時間:2025/3/21 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 扫雷插件分析与编写 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

至個人年久失修的git博客搬運https://yusakul.github.io/


掃雷游戲插件的目標

  • 當鼠標放在掃雷的方格中時,會顯示是否有雷。
  • 一鍵掃雷,快捷鍵是F5
  • 掃雷游戲的分析

  • 需要的技能
  • ① 會編寫DLL

    ②會寫注入讀取或者寫內存的代碼

    ③能夠分析出掃雷程序中的信息

  • 需要分析的數據
  • ① 掃雷數組的大小

    ② 掃雷數組的寬度 、高度

    ③ 掃雷數組中的數量

  • 需要分析的代碼
  • ① 找到遍歷掃雷數組的代碼,或者分析出如何遍歷數組

    ② 找到屏幕坐標轉換數組下的代碼,或者分析出這個過程

    ③ 找到數組下標轉換屏幕坐的代碼,或者分析出這個過程

  • 代碼框架
  • 接管掃雷窗口的回調函數,處理F5的按鍵消息

    修改窗口屬性SetWindowLong

    掃雷游戲-分析數據

    ① 掃雷數組的大小

    ② 掃雷數組的寬度 、高度

    ③ 掃雷數組中的數量

    根據寬度或者高的值變化,使用 CE 在內存中搜索數值,從而能找到寬度的地址

    CE使用
  • 修改程序數據的值,在CE中搜索

  • 每次修改之后,再使用CE搜索,最后確定可能的值

  • 注意:綠色的地址就是可以映射到文件偏移的地址,綠色地址稱為基址

  • 在可能的值上查找此地址數據的代碼
  • 再次修改數據,會有代碼被記錄

    代碼處:10036AC

    高度:1005338

    寬度:1005334

    雷數:1005330

    掃雷游戲-分析代碼

  • 從數值變化的代碼處開始分析
  • 從代碼處: 10036 AC 開始跟蹤分析

  • 敏感 API 下斷點,再進一步分析 下斷點,再進一步分析
  • 定時器創建和銷毀: SetTimer,KillTimer

    隨機函數: rand

  • 從窗口回調函數開始分析 窗口回調函數開始分析 ,分析鼠標按下消息

    使用 spy++ 查找程序的窗口回調

  • 地址:1001BC9

  • 從數值變化的代碼處開始分析
  • 從代碼處:10036AC開始跟蹤分析

    修改完數據之后,應該初始化掃雷數組、隨機生成雷。

    隨機生成雷的代碼中,是一個循環隨機生成雷的x,y 坐標,然后寫入到對應緩沖區

    基地址:0x1005340

    X坐標計算:隨機數+1

    Y坐標計算:(隨機數+1)*32

    根據內存情況可以分析出一些標記:

    0F :初始化的值

    8F :雷的標記

    4X :周圍有幾顆雷就是4X, 41,42,43,44……

    10 :邊界

    有了隨機雷的生成,那么在雷生成前面的CALL,應該就是初始化雷區數組的代碼,經過調試查看內存,發現真的是。

    分析初始化雷區數組代碼,發現為三步

  • 初始化全部緩沖區為 0x0 F

  • 初始化行標記 為 0x10

  • 初始化列標記 位 0x 10

  • 搭建代碼框架

    第一步 ,定義一些值和函數

    WNDPROC g_OldProc = NULL; HWND g_hWnd = NULL; LRESULT WINAPI WindowProc ( _In_ HWND hWnd, _In_ UINT Msg, _In_ WPARAM wParam, _In_ LPARAM lParam) {if (Msg == WM_KEYDOWN && wParam == VK_F5){CString strString;strString.Format(L"wParam = %p", wParam);OutputDebugString(strString.GetBuffer());return DefWindowProc(hWnd, Msg, wParam, lParam);}return CallWindowProc(g_OldProc, hWnd, Msg, wParam, lParam); }

    第二步,修改回調函數

    // 修改掃雷窗口的回調函數 // 1. 找到掃雷窗口 g_hWnd = FindWindow(NULL, L"掃雷"); // 2. 修改窗口回調 g_OldProc = (WNDPROC)SetWindowLong(g_hWnd, GWL_WNDPROC, (LONG)WindowProc); // 恢復窗口回調 SetWindowLong(g_hWnd, GWL_WNDPROC, (LONG)g_OldProc);

    注意:寫代碼要記得釋放和恢復,寫代碼要做好debug的準備

    經過調整編寫之后,遍歷掃雷的數組

    // 基地址:0x1005340 // 高度:1005338 // 寬度:1005334 // 雷數:1005330 byte** g_MineArray = (byte**)0x1005340; int* g_nHeight = (int*)0x1005338; int* g_nWidth = (int*)0x1005334; int* g_nMineCount = (int*)0x1005330;LRESULT WINAPI WindowProc ( _In_ HWND hWnd, _In_ UINT Msg, _In_ WPARAM wParam, _In_ LPARAM lParam) {if (Msg == WM_KEYDOWN && wParam == VK_F5){CString strString;strString.Format(L"saolei wParam = %p", wParam);OutputDebugString(strString.GetBuffer());// 遍歷掃雷數組int nHeight = *g_nHeight; // 高度yint nWidth = *g_nWidth; // 寬度xint nCount = *g_nMineCount;int nCurrentCount = 0;for (int j = 1; j < nHeight+1; j++){CString strString1;strString1.Format(L"saolei 行:%d ", j);// 行遍歷時,需要注意去掉邊界for (int i = 1; i < nWidth + 2 - 1; i++){byte byCode = *(byte*)((int)g_MineArray+i+j*32);if (byCode == (byte)0x8F){nCurrentCount += 1;}CString strCode;strCode.Format(L" %02x ", byCode);strString1 += strCode;}strString1 += L"\r\n";OutputDebugString(strString1.GetBuffer());}CString strString2;strString2.Format(L"saolei 雷數 = %d", nCurrentCount);OutputDebugString(strString2.GetBuffer());return DefWindowProc(hWnd, Msg, wParam, lParam);}return CallWindowProc(g_OldProc, hWnd, Msg, wParam, lParam); }

    分析 -屏幕坐標轉數組下標

    分析思路:

    ① 窗口回調下消息斷點,分析鼠標按下彈起消息的流程

    ② 靜態分析窗口回調,使用IDA找到對應的消息處理流程

    窗口回調地址:1001BC9

    在地址處下消息斷點WM_LBUTTONDOWN

    在這個消息的lParam參數里是x,y坐標

    將匯編代碼翻譯為C代碼

    WORD y = HIWORD(lParam); y = (y - 0x27) >> 4;WORD x = LOWORD(lParam); x = (x + 4) >> 4;byte byCode = *(byte*)((int)g_MineArray + x + y * 32);if (byCode == (byte)0x8F) {SetWindowText(hWnd,L"掃雷 - 友情提示:你踩到雷了!"); } else {SetWindowText(hWnd, L"掃雷"); }

    分析-數組下標轉屏幕坐標

    將上面的代碼反轉

    // 發送一個鼠標按下彈起的消息 WORD y = j; y = (y << 4) + 0x27; //y 高16位WORD x = i; x = (x << 4) - 4; // x 低16位SendMessage(hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(x,y)); SendMessage(hWnd, WM_LBUTTONUP, 0, MAKELPARAM(x, y));

    DLL調試

  • 如果有源碼,可以使用VS進行調試,只需要設置啟動exe即可

  • 如果沒有源碼,使用OD調試,一般選擇在調試的代碼處加入特征匯編指令

  • 比如:

    Mov eax, eax

    Mov eax, eax

    在注入 DLL 之后,可以搜索指令 之后,可以搜索指令

    選擇 DLL 模塊 (在模塊列表中找到對應,右鍵跟隨入口)

    選擇 DLL 模塊的代碼基址 (進入模塊代碼之后,拖到最前面)

    使用 Ctrl +S, 搜索

  • 在OD中注入DLL
  • 總結

    以上是生活随笔為你收集整理的扫雷插件分析与编写的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。