首页
社区
课程
招聘
扫雷PE
发表于: 2005-1-18 16:52 6828

扫雷PE

2005-1-18 16:52
6828
闲来无事,顺手pe了扫雷,以前很喜欢这游戏,不过老是在最后关头一招不慎。满盘皆输。

所以增加了一次作弊的机会。
小鸟随便pe的,也不写什么东西了。

还有向各位请教的,我想给扫雷加个快存快取功能,不知道各位大大有没有什么意见。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (20)
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
忘记了附件,顺手补上
附件:winmine.rar
2005-1-18 16:53
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
pe的代码再文件的最后,od看看就明白的。
2005-1-18 16:54
0
雪    币: 547
活跃值: (2200)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
怎么用啊, 快存快取?
2005-1-18 17:52
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
快存快取正在研究中,^^:

偶小鸟什么都要学。目前只PE了一个功能,就是当你扫雷数目小于10的时候,不幸踩到雷,不会满盘皆输,而会避免一次失败。不过设定的时候是只能使用一次,第二次就没有了。^^:
2005-1-18 18:02
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
快存快取就是保存当前扫雷的状态,等到下次取的时候可以继续上次的进度,不过对于这个功能,我是找到了一些关键点,但是实现起来还是有点问题,所以召唤各位PE的大大。
2005-1-18 18:04
0
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
7
看能不能找到游戏存取状态的表或者链表,搞明白就可以设置它。
2005-1-18 19:16
0
雪    币: 176
活跃值: (117)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
8
我有个提议

  //$010052c0 玩的模式
  //$010052C4  2K下是雷数起始地址
  //$010052C8  2K下是雷区高度起始地址
  //$010052CC  2K下是雷区宽度起始地址
  //$01005721  2K下是雷区内容起始地址,依次是$01005721+高*32+宽
  //$01005a60  2K下是雷剩余个数

  //$010056a0  玩的模式
  //$01005330/56a4  XP下是雷数起始地址
  //$01005338/56a8  XP下是雷区高度起始地址
  //$01005334/56ac  XP下是雷区宽度起始地址
  //$01005361  XP下是雷区内容起始地址,依次是$01005361+高*32+宽
  //$01005194  XP下是雷剩余个数

从内存中抓出来

扫雷里面已经挂了CreateFileA和WriteFileA的相关函数
把内存中的这些地址存入文件应该没有问题
关键是读取。。。。
2005-1-18 19:39
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
想到一个方法,可以利用程序本身来做游戏模式的切换,在其切换好了,生成了新的扫雷分布之后,再用原来的扫雷分布覆盖,这样。。。好像也不成诶。。。郁闷

不过好像CreateFileA和WriteFile还有ReadFile都没有挂在扫雷上吧,好像还要自己弄一下Import表,用LordPE好像会把自己以前的code的东东覆盖掉的!。。可能是我没有设好边界吧。
2005-1-19 13:25
0
雪    币: 176
活跃值: (117)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
10
最初由 tempm 发布

不过好像CreateFileA和WriteFile还有ReadFile都没有挂在扫雷上吧,好像还要自己弄一下Import表,用LordPE好像会把自己以前的code的东东覆盖掉的!。。可能是我没有设好边界吧。


98下的扫雷有这个函数吧?因为成绩是记在ini文件里的
不过2000和XP的有注册表的相关函数
可以把他写在注册表里啊,数据不多效果和写在文本里一样的
2005-1-19 13:35
0
雪    币: 150
活跃值: (116)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
我改过一个作弊版的

雷的位置在内存中是固定的,可以做一个外挂比较容易。
而且初中高级都很容易找到在那里的。
做一个内存补丁很容易。
在原来的基础上比较困难。
2005-1-19 21:15
0
雪    币: 200
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
12
找到地雷数组就好办了。可以直接判断是否地雷。我在98、2000下都做过,每次扫雷都是1秒。
2005-1-19 22:56
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
最初由 乱乱 发布
我改过一个作弊版的

雷的位置在内存中是固定的,可以做一个外挂比较容易。
而且初中高级都很容易找到在那里的。
做一个内存补丁很容易。
........


这个以前就做过了,以前直接点鼠标左键,遇雷扫雷^^:

把其中的函数修改了一下就可以了!其实如果把我现在修改的那个把雷数比较修改成99,把Flag永远置0的话也差不多是一个样子。

但时光作弊太没有意思了。

现在主要是想做快存快取啦,我又想到一个方法了,可以向重放的方式,Reload雷区分布之后,把挖过的用扫雷内的那个挖雷函数重新Execute。这样或许可行。我目前正在做快存那部分,用RegSetValueW,辛苦工作ing^^:
2005-1-20 16:56
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
最初由 baddog911 发布
找到地雷数组就好办了。可以直接判断是否地雷。我在98、2000下都做过,每次扫雷都是1秒。


已经找到了,楼上的大哥已经放出了所有的有用地址

你做的是不是把SetTime的时间设置的很大很大?我也作了,不过不好玩!如果你方法不同的话,分享一下。
2005-1-20 17:00
0
雪    币: 427
活跃值: (412)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
扫雷这个游戏只要知道规则就可以了,我不需要什么作弊过专家级,这游戏又没有什么运气成分,很多人说还是有运气的,我都好笑,过不去就说那是运气,何必呢。:D
2005-1-20 19:22
0
雪    币: 200
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
16
最初由 tempm 发布


已经找到了,楼上的大哥已经放出了所有的有用地址

你做的是不是把SetTime的时间设置的很大很大?我也作了,不过不好玩!如果你方法不同的话,分享一下。

我的做法是单独启动一个进程,有个扫雷的按钮,点一下马上读取地图数组,对于每个没有地雷的格子发送一条鼠标左键按下的消息。一瞬间就结束了,但总是显示耗时1秒。
2005-1-20 19:41
0
雪    币: 150
活跃值: (116)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
17
我的是重写雷的位置数据所有的雷都放到左上角
2005-1-20 20:26
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
最初由 乱乱 发布
我的是重写雷的位置数据所有的雷都放到左上角


寒,这不是没有什么意义嘛!本来嘛!扫雷就是玩兴趣的,嘻嘻
2005-1-20 20:40
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
最初由 baddog911 发布

我的做法是单独启动一个进程,有个扫雷的按钮,点一下马上读取地图数组,对于每个没有地雷的格子发送一条鼠标左键按下的消息。一瞬间就结束了,但总是显示耗时1秒。


这里来了一个问题了,你怎么读取扫雷程序的内存?我对编程不懂,想问一下,说不定我的快取功能就要向你这样做。
2005-1-20 20:41
0
雪    币: 176
活跃值: (117)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
20
最初由 tempm 发布


这里来了一个问题了,你怎么读取扫雷程序的内存?我对编程不懂,想问一下,说不定我的快取功能就要向你这样做。


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    StatusBar1: TStatusBar;
    GroupBox1: TGroupBox;
    rbWin2k: TRadioButton;
    rbWinXP: TRadioButton;
    GroupBox2: TGroupBox;
    rbNotMine: TRadioButton;
    rbMine: TRadioButton;
    rbAuto: TRadioButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  hmine: Thandle; //扫雷窗体的句柄
  pmine: Thandle; //扫雷窗体的进程柄
  mineid: dword; //扫雷窗体的进程ID
  lpBuffer: pByte; //用于读取内存中的内容
  nSize: DWORD; //读取的大小
  lpNumberOfBytesRead: DWORD; //已读取的字节数
  s: string;
  row, col: integer; //行数、列数
  mwidth, mheight, mPlayType: integer; //雷的列数、行数、玩的模式
  //扫雷窗体上第一行第一列相对于这个窗体的偏移量,用于以后的鼠标自动点击
  xOffset, yOffset: integer;
  miBegin, miHeight, miWidth, miStart, miPlayType: LongWord;
begin
  //$010052c0 玩的模式
  //$010052C4  2K下是雷数起始地址
  //$010052C8  2K下是雷区高度起始地址
  //$010052CC  2K下是雷区宽度起始地址
  //$01005721  2K下是雷区内容起始地址,依次是$01005721+高*32+宽
  //$01005a60  2K下是雷剩余个数

  //$010056a0  玩的模式
  //$01005330/56a4  XP下是雷数起始地址
  //$01005338/56a8  XP下是雷区高度起始地址
  //$01005334/56ac  XP下是雷区宽度起始地址
  //$01005361  XP下是雷区内容起始地址,依次是$01005361+高*32+宽
  //$01005194  XP下是雷剩余个数
  if rbWin2K.Checked then
  begin
    miBegin := $010052C4;
    miHeight := $010052C8;
    miWidth := $010052CC;
    miStart := $01005721;
    miPlayType := $010052C0;
  end
  else
  begin
    miBegin := $01005330;
    miHeight := $01005338;
    miWidth := $01005334;
    miStart := $01005361;
    miPlayType := $010056A0;
  end;
  hmine := findwindow(nil, '扫雷'); //找 扫雷 窗口
  GetWindowThreadProcessId(hmine, @mineId); //返回 扫雷 进程的ID,为mineId
  yOffset := 60;
  xOffset := 20;
  pmine := OpenProcess(PROCESS_VM_READ, true, mineId); //打开 扫雷 进程
  if pmine = 0 then
  begin
    messagebox(0, '你还没有打开扫雷吧:)', '找不到哦', mb_ok);
    exit
  end;

  nSize := 1;

  lpBuffer := AllocMem(nSize);
  if ReadProcessMemory(pmine, //进程句柄
    pointer(miBegin), //内存区基址
    lpbuffer, //数据缓冲区
    nsize, //要读的字节数
    lpNumberOfBytesRead //已读字节数
    ) then
  begin
    caption := '共有雷数 ' + inttostr(lpBuffer^) + ' 个';
  end;

  if ReadProcessMemory(pmine,
    pointer(miWidth),
    lpbuffer,
    nsize,
    lpNumberOfBytesRead
    ) then
    mwidth := lpbuffer^; //雷区宽度,即 扫雷 的列数
  if ReadProcessMemory(pmine,
    pointer(miHeight),
    lpbuffer,
    nsize,
    lpNumberOfBytesRead
    ) then
    mheight := lpbuffer^; //雷区高度,即 扫雷 的行数

  StatusBar1.Panels[0].Text := '雷区宽度 ' + inttostr(mwidth) + ' 雷区高度 ' +
    inttostr(mheight);

  if ReadProcessMemory(pmine,
    pointer(miPlayType),
    lpbuffer,
    nsize,
    lpNumberOfBytesRead
    ) then
    mPlayType := lpbuffer^; //雷区高度,即 扫雷 的行数
  case mPlayType of
    0: StatusBar1.Panels[1].Text := '模式:初级';
    1: StatusBar1.Panels[1].Text := '模式:中级';
    2: StatusBar1.Panels[1].Text := '模式:高级';
    3: StatusBar1.Panels[1].Text := '模式:自定义';
  end;

  for row := 0 to mheight do //从第一行开始,由左向右,从上而下
    for col := 0 to mwidth do //
    begin
      if ReadProcessMemory(pmine,

        pointer(miStart + row * 32 + col),
        lpbuffer,
        nsize,
        lpNumberOfBytesRead
        ) then
      begin
        if lpbuffer^ <> 143 then //即$8F为雷,
        begin
          if rbAuto.Checked then
          begin
            //模拟了鼠标左键的点击事件
            //向 扫雷 窗体的 (xOffset+16*col,yOffset+16*row)处 发送鼠标左键按下的消息
            SendMessage(hmine, WM_LBUTTONDOWN, 0, MAKELPARAM(xOffset + 16 * col,
              yOffset + 16 * row));
            //向 扫雷 窗体的 (xOffset+16*col,yOffset+16*row)处 发送鼠标左键抬起的消息
            SendMessage(hmine, WM_LBUTTONUP, 0, MAKELPARAM(xOffset + 16 * col,
              yOffset + 16 * row));
          end
          else
            if rbNotMine.Checked then
            begin
              //在非雷区标注问号
              //模拟了鼠标右键的点击事件
              //向 扫雷 窗体的 (xOffset+16*col,yOffset+16*row)处 发送鼠标右键按下的消息
              SendMessage(hmine, WM_RBUTTONDOWN, 0, MAKELPARAM(xOffset + 16 *
                col,
                yOffset + 16 * row));
              //向 扫雷 窗体的 (xOffset+16*col,yOffset+16*row)处 发送鼠标右键抬起的消息
              SendMessage(hmine, WM_RBUTTONUP, 0, MAKELPARAM(xOffset + 16 * col,
                yOffset + 16 * row));

              //模拟了鼠标右键的点击事件即标注雷
              //向 扫雷 窗体的 (xOffset+16*col,yOffset+16*row)处 发送鼠标右键按下的消息
              SendMessage(hmine, WM_RBUTTONDOWN, 0, MAKELPARAM(xOffset + 16 *
                col,
                yOffset + 16 * row));
              //向 扫雷 窗体的 (xOffset+16*col,yOffset+16*row)处 发送鼠标右键抬起的消息
              SendMessage(hmine, WM_RBUTTONUP, 0, MAKELPARAM(xOffset + 16 * col,
                yOffset + 16 * row));
            end;
        end
        else
        begin
          if rbMine.Checked then
          begin
            //模拟了鼠标右键的点击事件
            //向 扫雷 窗体的 (xOffset+16*col,yOffset+16*row)处 发送鼠标右键按下的消息
            SendMessage(hmine, WM_RBUTTONDOWN, 0, MAKELPARAM(xOffset + 16 * col,
              yOffset + 16 * row));
            //向 扫雷 窗体的 (xOffset+16*col,yOffset+16*row)处 发送鼠标右键抬起的消息
            SendMessage(hmine, WM_RBUTTONUP, 0, MAKELPARAM(xOffset + 16 * col,
              yOffset + 16 * row));
          end;
        end;

      end;
    end;
  freemem(lpbuffer, nsize);
  CloseHandle(pmine);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  close;
end;

end.
2005-1-20 21:51
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
Cool, 小鸟再这里谢过了
2005-1-20 21:56
0
游客
登录 | 注册 方可回帖
返回
//