扫雷山寨外挂

说句实话,本人一直非常喜欢玩扫雷,尤其是在寝室断网的情况下,目前在10×10的难度下最好成绩是9秒(没有截图 - - 无图无真相 - -||),之后就再也没能超越自己,始终进不了11秒 - -||
  一怒之下决定写个外挂,说干就干!打开DEV之后冷静了,我不会OD - - 汇编也差的一塌糊涂怎么办 = =||  
  没关系,那咱就站在前辈的肩膀上向前看!
  上网一搜搜到了扫雷的原理,如下:
原理其实很简单,设法获得“雷区”的数据,然后通过模拟鼠标动作,点击雷区上非地雷的的格子,就搞定了:)  所以技术难点只有三个:获得雷区数据、找到扫雷程序和模拟鼠标动作。

这里我们省略第三个难点,退而求其次之打印出雷的分布图就好了,那么雷区的数据该怎么获得呢?
比较有难度的是如何获得雷区数据。这里有两个事情要做,首先要找出雷区在程序内部是如何表示的,如何区分格子是有雷还是无雷,如何知道雷区格子大小,以及这些数据保存在程序什么位置,是固定位置还是变化的。弄到这些情报后,第二件事情就简单了,我们可以通过几个 api函数很轻松地就获取雷区的动态数据。
    要完成第一件事情,我们需要一个叫ollydbg的反汇编调试工具、一些些汇编知识以及很大的耐心,呵呵,具体过程这里就不说了,主要是不知道怎样说清楚,感觉靠经验多一些。通过跟踪汇编代码,我们可以发现无雷的格子数据是0x0F,有雷的是 0x8F,而雷区数据总是从0x1005340 这个逻辑地址开始。

看到了吧,里面虽然要用到OD,但是前辈已经基本告诉我们所有我们需要的信息了,我之所以说基本,因为他说还不是很好理解,我们需要一张图来直观的感受下
   
     0  1    2   3   4   5   6   7   8    9    10  11   31

0  10 10 10 10 10 10 10 10 10  10  10 0F  0F

1  10 0F 0F 0F 0F 0F 0F 0F 0F 0F 10 0F  0F

2  10 0F 0F 0F 0F 0F 0F 0F 0F 0F 10 0F  0F

3  10 0F 0F 0F 0F 0F 0F 0F 0F 0F 10 0F  0F

4  10 0F 0F 0F 0F 0F 8F 0F 0F 8F 10 0F  0F

5  10 0F 8F 0F 0F 0F 0F 0F 0F 0F 10 0F  0F

6  10 0F 8F 0F 0F 0F 8F 0F 8F 0F 10 0F  0F

7  10 8F 0F 0F 0F 8F 0F 0F 0F 0F 10 0F  0F

8  10 0F 0F 8F 0F 0F 0F 0F 0F 0F 10 0F  0F

9  10 0F 0F 0F 0F 0F 8F 0F 0F 0F 10 0F  0F

10  10 10 10 10 10 10 10 10 10 10 10 0F  0F

11  0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F  0F
   
   
23  0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F  0F

我来解释一下,这是一个32×24的矩阵,也就表示这扫雷的最高难度级别,这张图表示的是10*10难度 怎么看出来的呢因为有10×10的部分被10包围了,这个10是十六进制的数,大家可以想象下中级和高级的图的表示。
知道这些就好办多了,于是我们轻松的写下如下的代码 :
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
HANDLE GetProcessPID();
void ReadDataFromProcess(HANDLE hProcess,int address);
void PrintBombPic();
char addr;
main(){
       #define SAFE 0x0F        //无雷数据为0x0F 
       #define BOMB 0x8F        //雷区数据为0x8F 
       #define BOARD 0x10       //边界数据为 0x10
       #define ADDR 0x1005340   //雷区数据从0x1005340这个内存地址开始 
       HANDLE hProcess;         //扫雷进程句柄变量 
       int address=ADDR;        
       int row=0;
       int line=0;
       hProcess=GetProcessPID();
       for(line=0;line<=10;line++){  //这里的上限根据情况而定,我这里是10×10的难度 
                                   for(row=0;row<=10;row++){
                                                            ReadDataFromProcess(hProcess,address);
                                                            PrintBombPic();
                                                            address=address+0x1;
                                                            }
                                   address=address+0x15; // 只打印10×10的范围,这里扫雷的级别为初级10*10 
                                   printf("\n");
                                   }
       CloseHandle(hProcess);
       system("pause");
       }
       
HANDLE GetProcessPID(){                //获取扫雷进程句柄函数 
     DWORD pid;
     HWND hwnd=FindWindow(NULL,"扫雷");     //获取扫雷窗口句柄
     GetWindowThreadProcessId(hwnd,&pid);                       //获取扫雷进程ID
     HANDLE handleid=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);        //获取扫雷进程句柄
     return handleid;
     }
     
void ReadDataFromProcess(HANDLE hProcess,int address){   //读取内存地址内容 
     if(!(ReadProcessMemory(hProcess,(LPCVOID)address,&addr,1,NULL))) printf("err ");
     }
     
void PrintBombPic(){     //打印出雷的分布图 
     switch(addr){
                  case SAFE:
                       printf("+ ");    //无雷用“+”表示 
                       break;
                  case BOMB:            //雷用“×”表示 
                       printf("* ");
                       break;
                  case BOARD:           //边界用“=”表示 
                       printf("= ");
                       break;
                  default:printf("- ");  //其他情况用“-”表示 
                  }
     }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值