反汇编逆向实战——扫雷辅助制作

这篇具有很好参考价值的文章主要介绍了反汇编逆向实战——扫雷辅助制作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、编程前准备

刚开始是预备知识,如果熟悉的话,可以直接跳到第二部分阅读

在 Windows API 中,SetTimer 函数用于创建一个定时器,并在指定的时间间隔后触发一个定时器消息。以下是关于 SetTimer 函数的介绍:

功能:创建一个定时器,并在指定的时间间隔后触发定时器消息。

参数:

  • hWnd:指定接收定时器消息的窗口的句柄。
  • nIDEvent:指定定时器的标识符。在定时器消息中使用该标识符来区分不同的定时器。
  • uElapse:指定定时器触发的时间间隔,以毫秒为单位。
  • lpTimerFunc:指向定时器回调函数的指针。当定时器触发时,系统将调用该回调函数。
 case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            
            // 获取当前时间
            SYSTEMTIME sysTime;
            GetLocalTime(&sysTime);
            
            // 将时间转换为字符串
            char timeString[64];
            sprintf(timeString, "%02d:%02d:%02d", sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
            
            // 绘制时间文本
            TextOut(hdc, 10, 10, timeString, strlen(timeString));
            
            EndPaint(hwnd, &ps);
            break;
        }

要在窗口中使用计时器(Timer)来定期绘制时间,可以按照以下步骤进行操作:

1、在窗口类中添加一个计时器标识符:在窗口类的定义中,添加一个计时器标识符作为类的成员变量,用于标识计时器的ID。

class WindowClass
{
private:
    static const UINT_PTR TIMER_ID = 1; // 计时器标识符
    // 其他成员变量和方法
};

2、在窗口的创建过程中启动计时器:在窗口的创建过程中,通过调用 SetTimer 函数来启动计时器。这个函数将设置一个定时器,每隔一定时间触发一个 WM_TIMER 消息。 

HWND hwnd = CreateWindow(/* 窗口参数 */);
SetTimer(hwnd, TIMER_ID, 1000, NULL); // 在这里启动计时器,每隔1秒触发一次 WM_TIMER 消息

3、处理 WM_TIMER 消息:在窗口的消息处理函数中,处理 WM_TIMER 消息,并在该消息中绘制时间。

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        // 其他消息处理代码
        
        case WM_TIMER:
        {
            if (wParam == TIMER_ID) // 根据计时器标识符判断是哪个计时器触发的消息
            {
                // 获取当前时间
                SYSTEMTIME sysTime;
                GetLocalTime(&sysTime);
                
                // 将时间转换为字符串
                char timeString[64];
                sprintf(timeString, "%02d:%02d:%02d", sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
                
                // 绘制时间文本
                HDC hdc = GetDC(hwnd);
                TextOut(hdc, 10, 10, timeString, strlen(timeString));
                ReleaseDC(hwnd, hdc);
            }
            
            break;
        }
        
        // 其他消息处理代码
        
        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    
    return 0;
}

另外,不要忘记在窗口销毁时停止计时器,可以在 WM_DESTROY 消息中调用 KillTimer 函数来停止计时器的触发。

case WM_DESTROY:
    KillTimer(hwnd, TIMER_ID); // 停止计时器
    PostQuitMessage(0);
    break;

二、扫雷找数据

1、获取雷区的数据

首先准备本次实验需要用到的工具:

如果大家需要扫雷的资源,可以私信我获取噢~😐😐😐

反汇编逆向实战——扫雷辅助制作

附加到扫雷的进程:

反汇编逆向实战——扫雷辅助制作

首次扫描未知的初始值,类型选择字节

反汇编逆向实战——扫雷辅助制作

点击首次扫描,发现有10W+的搜索结果,,,然后毫无疑问我们需要过滤掉一部分数据:

点击第一个格子,再次扫描变动的数据

反汇编逆向实战——扫雷辅助制作

点击旁边的格子,扫描不变的数据,再次扫描

反汇编逆向实战——扫雷辅助制作

重新开始,如果数字如果发生变化就选择变动的数值,再次扫描

反汇编逆向实战——扫雷辅助制作 

然后继续点击几个格子,不是地雷的话就可以选择未变动的值,再次扫描

反汇编逆向实战——扫雷辅助制作 

很快就找到了我们所需要的雷区的数据 

反汇编逆向实战——扫雷辅助制作 

浏览这块区域所在的内存位置,观察一下里面都是什么数据 

反汇编逆向实战——扫雷辅助制作

可以手动测试一下:

反汇编逆向实战——扫雷辅助制作

 反汇编逆向实战——扫雷辅助制作

 经过几轮尝试之后,不难发现:

"0x0f"表示不是地雷

"0x8f"表示是地雷

"0x0e"表示小旗子

"0x10"表示边界

"40"表示空格

"41-49"表示数字

2、获取雷区的高度和宽度

注意:这里说的高度和宽度是不计算无关数据的,就是真实的高、宽占多少个格子

比如对于初级模式就是9*9:

反汇编逆向实战——扫雷辅助制作 

切换为中级、高级,分别搜索,很快就可以找到高度所在内存:

反汇编逆向实战——扫雷辅助制作 

反汇编逆向实战——扫雷辅助制作 

同理,还可以找到宽度和地雷数量 :

反汇编逆向实战——扫雷辅助制作 

3、寻找存储时间的数据 

我们找存储时间内存的目的,就是观察谁修改了它,具体来说就是哪条指令把这块内存的数据inc了,这样我们通过把这句指令nop掉,就可以实现时间停止的功能,从而实现0秒扫雷😂😂😂

反汇编逆向实战——扫雷辅助制作 、

其实搜索起来十分简单,只要一直追那个变化的数据就好了

反汇编逆向实战——扫雷辅助制作 

反汇编逆向实战——扫雷辅助制作 

这样我们就找到了inc时间的指令,位于0x1002ff5的位置,把他nop掉,时间就静止了~

反汇编逆向实战——扫雷辅助制作 

但是我们一开始点击格子的时候,它还是会自动设置时间为1,所有我们还需要把这一条指令也nop掉,实现真正的0秒扫雷!!! 

我采用的思路是在左键弹起的地方设置一个硬件断点,然后一路f8下去,观察到时间发生变化,就在最近的那个call打个断点继续跟----->

反汇编逆向实战——扫雷辅助制作 

反汇编逆向实战——扫雷辅助制作 

它断下来的地方是整个消息处理的头部 !!!

反汇编逆向实战——扫雷辅助制作 

反汇编逆向实战——扫雷辅助制作

看到修改全局的内存,高度怀疑是这里修改时间,经过测试果然如此:

反汇编逆向实战——扫雷辅助制作 

跟进去发现果真调用了绘制函数!!!

反汇编逆向实战——扫雷辅助制作

所以我们最终确定,设置时间的地址位于0x1003830位置处!

三、编程思路梳理:

1、获取扫雷窗口句柄,然后获得pid

2、nop掉时间inc的函数,实现时间静止

3、读取雷区有效数据

4、模拟鼠标给窗口发消息

5、释放掉申请的内存和句柄

四、扫雷辅助源码

#include<iostream>
using namespace std;
#include<Windows.h>

#define increaseTimeAddr 0x01002FF5
#define setTimeAddr      0x01003830
#define mineStartAddr    0x01005340

int main() {

    //打开扫雷进程
    HWND hWnd = FindWindow(nullptr, L"扫雷");
    if (hWnd != nullptr)
    {
        DWORD dwProcessId;
        GetWindowThreadProcessId(hWnd, &dwProcessId);

        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
        if (hProcess == nullptr)
        {
            cout << "fail to find the winmine process" << endl;
            CloseHandle(hProcess);
            return -1;
        }
        //测试是否正确打开扫雷进程,如果关闭了,就说明句柄是对的
        //TerminateProcess(hProcess, 0);

        //把时间增加的指令nop掉,实现0秒扫雷
        DWORD oldProtect = 0;
        SIZE_T nBytesWritten1 = 0;
        SIZE_T nBytesWritten2 = 0;
        bool bRet1, bRet2;
        BYTE replaceBuf[] = { 0x90,0x90,0x90,0x90,0x90,0x90 };
        VirtualProtectEx(hProcess, (LPVOID)increaseTimeAddr, 6, MEDIA_READ_WRITE, &oldProtect);
        bRet1=WriteProcessMemory(hProcess, (LPVOID)increaseTimeAddr, replaceBuf, sizeof(replaceBuf), &nBytesWritten1);
        bRet2=WriteProcessMemory(hProcess, (LPVOID)setTimeAddr, replaceBuf, sizeof(replaceBuf), &nBytesWritten2);
        VirtualProtectEx(hProcess, (LPVOID)increaseTimeAddr, 6, oldProtect, &oldProtect);

        if (bRet1 == FALSE || bRet2 == FALSE || nBytesWritten1 <= 0 || nBytesWritten2 <= 0) {
            cout << "修改时间失败!\n";
            CloseHandle(hProcess);
            return -1;
        }

        //读取整个雷区的数据
        //设置读取雷区的最大字节数
        DWORD maxSize = 832;
        char* pByte = NULL;
        SIZE_T nBytesRead = 0;
        pByte = (char*)malloc(sizeof(BYTE) * maxSize);
        bool bReadData = ReadProcessMemory(hProcess, (LPVOID)mineStartAddr, pByte, maxSize, &nBytesRead);
        if (!bReadData) {
            CloseHandle(hProcess);
            delete pByte;
            return -1;
        }
        
        //打印一下观察是否读取正确
        /*for (int i = 0; i < maxSize;i++) {
            printf("%x  ", pByte[i]);
        }*/

        //获取当前雷区的大小
        DWORD sizeAddr = 0x01005330;
        DWORD dwHeight = 0, dwWidth = 0;
        ReadProcessMemory(hProcess, (LPVOID)(sizeAddr + 4), &dwWidth, sizeof(DWORD),0);
        ReadProcessMemory(hProcess, (LPVOID)(sizeAddr + 8), &dwHeight, sizeof(DWORD), 0);

        //读取当前雷区的有效数据
        char* pCurByte = NULL;
        pCurByte = (char*)malloc(sizeof(BYTE) * dwHeight * dwWidth);

        int h = 0;
        int index = 0;
        while (1) {
            if (pByte[index] == 0x10 && pByte[index + 1] != 0x10 && pByte[index + dwWidth + 1] == 0x10) {
                for (int j = 0; j < dwWidth; j++) {
                    pCurByte[dwWidth * h + j] = pByte[index + 1];
                    index++;
                }
                h++;
                if (h >= dwHeight)
                    break;
            }
            index++;
        }
        //模拟鼠标点击格子
        for (int i = 0; i < dwWidth*dwHeight; i++) {
            if (i % dwWidth == 0) {
                cout << endl;
            }
            printf("%x ", *(pCurByte+i));
        }
        int x1 = 0, y1 = 0;
        int x = 0, y = 0;
        for (int i = 0; i < dwHeight * dwWidth; i++) {
            if (*(pCurByte+i) != 0xffffff8f) {
                x1 = i % dwWidth;
                y1 = i / dwWidth;
                x = x1 * 16 + 16;
                y = y1 * 16 + 61;
                SendMessage(hWnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(x, y));
                SendMessage(hWnd, WM_LBUTTONUP, MK_LBUTTON, MAKELONG(x, y));
            }
           
        }
        free(pByte);
        free(pCurByte);
        pByte = NULL;
        pCurByte = NULL;
        CloseHandle(hProcess);
    }

    printf("???就这???\n");
    printf("???就这???\n");
    printf("???就这???\n");
    printf("???就这???\n");

    system("pause");

	return 0;
}

五、扫雷辅助效果

扫雷窗口最大是24*30

反汇编逆向实战——扫雷辅助制作

留下你的鼎鼎大名😂😂😂🤣

 反汇编逆向实战——扫雷辅助制作

当然还要有适当的凡尔赛:

反汇编逆向实战——扫雷辅助制作 

 好了,今天的逆向辅助实战就到这里了,如果大家喜欢的话,可以私信我,去更新你们想要的游戏噢~喜欢的话就多多点赞、收藏、关注吧!!!🧡🧡🧡🤞🤞文章来源地址https://www.toymoban.com/news/detail-481948.html

到了这里,关于反汇编逆向实战——扫雷辅助制作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【软件逆向-分析工具】反汇编和反编译工具

    目录 一、IDA 1.1、简介: 1.2、使用方法: (1)IDA打开文件 (2)IDA主窗口介绍 (3)IDA的基本使用 二、调试器 2.1、简介: 2.2、Ollydbg (1)主界面 (2)断点操作 (3)代码跟踪操作 2.3、gdb (1)简介: (2)安装 (3)基本的调试操作 三、Trace类工具 3.1、简介: 3.2、Qira 反汇

    2024年02月04日
    浏览(30)
  • 童年回忆--扫雷(包括标记功能和递归展开)--万字讲解让你学会扫雷制作

    魔王的介绍:😶‍🌫️一名双非本科大一小白。 魔王的目标:🤯努力赶上周围卷王的脚步。 魔王的主页:🔥🔥🔥大魔王.🔥🔥🔥 ❤️‍🔥大魔王与你分享:人生人山人海人来人往,自己自尊自爱自由自在。 小时候我们在家里刚买电脑的时候,网络还不是很发达(两三

    2023年04月14日
    浏览(27)
  • IDA-逆向分析-工具教程-IDA简介-反汇编工具-功能窗口

    介绍了IDA反汇编原理分为, 线性扫描反汇编和递归下降反汇编 。比较了两者的优点和缺点。线性扫描反汇编算法采用一种非常简单的方法来确定需要反汇编的指令的位置:一条指令结束、另一条指令开始的地方。因此,确定起始位置最为困难。常用的解决办法是,假设程序

    2024年02月10日
    浏览(33)
  • Java制作一款扫雷游戏(含有源码)

    扫雷游戏分为初级、中级和高级三个级别,初级模式9 9个方块中有10个雷、中级模式16 16个方块中有40个雷、高级模式16*30个方块中有99个雷,单击游戏菜单可以选择“开局”、“初级”、“中级”、“高级”或“退出”。 选择级别后出现相应雷区,若不选择默认初级模式,用

    2024年02月04日
    浏览(30)
  • 带你用Python制作一个经典小游戏:扫雷

    名字:阿玥的小东东 学习:Python、C/C++ 主页链接:阿玥的小东东的博客_CSDN博客-pythonc++高级知识,过年必备,C/C++知识讲解领域博主 目录 游戏界面尺寸 方块尺寸 雷的数量

    2024年02月11日
    浏览(34)
  • 二进制代码反汇编逆向工具:IDA Pro(Win&Mac)v7.7 汉化版

    IDA Pro是一款交互式的、可编程的、可扩展的、多处理器的、交叉Windows或Linux WinCE MacOS平台主机来分析程序。它被公认为最好的花钱可以买到的逆向工程利器,已经成为事实上的分析敌意代码的标准并让其自身迅速成为攻击研究领域的重要工具。 功能丰富:IDA Pro提供了诸多功

    2024年02月20日
    浏览(35)
  • 《算法还原 - CTF》逆向exe程序 + ida Pro 反汇编分析伪C代码 + python算法复现

    二进制安全,能干什么 逆向分析: 负责成品软件的技术原理. 比如分析竞品软件,吸取技术上的优点,进行技术难点公关 病毒分析: 负责分析病毒样本.研究恶意代码的技术手段等工作.主要是在安全公司,尤其是在杀毒软件公司需求较多.如360 、腾讯电脑管家等. 漏洞挖掘分析: 负责

    2024年01月22日
    浏览(37)
  • cavity开盖制作的辅助层别

    cavity开盖工艺制作的辅助层别 数量:6个  

    2024年02月08日
    浏览(20)
  • C语言实战——扫雷游戏

    1.1扫雷游戏的功能说明 使用控制台实现经典的扫雷游戏 游戏可以通过菜单实现继续玩或者退出游戏 扫雷的棋盘是9*9的格子 默认随机布置10个雷 可以排查雷 如果位置不是雷,就显示周围有几个雷 如果位置是雷,就炸死游戏结束 把除10个雷之外的所有⾮雷都找出来,排雷成功

    2024年03月15日
    浏览(32)
  • 机器人制作开源方案 | 核酸检测辅助机器人

    作者: 周文亚、胡冲、王晓强、张娟 单位:北方民族大学 指导老师: 马行、穆春阳       新型冠状病毒肺炎全球流行已近三年,其变异毒株不断增强的传播力同时其症状不断变轻,其中无症状(怎么确认是否被感染)导致人们产生放轻松“躺平”还是严控疑虑的心理交织

    2024年02月02日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包