能力值:
( LV2,RANK:10 )
|
-
-
3 楼
pe的代码再文件的最后,od看看就明白的。
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
快存快取正在研究中,^^:
偶小鸟什么都要学。目前只PE了一个功能,就是当你扫雷数目小于10的时候,不幸踩到雷,不会满盘皆输,而会避免一次失败。不过设定的时候是只能使用一次,第二次就没有了。^^:
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
快存快取就是保存当前扫雷的状态,等到下次取的时候可以继续上次的进度,不过对于这个功能,我是找到了一些关键点,但是实现起来还是有点问题,所以召唤各位PE的大大。
|
能力值:
( LV13,RANK:970 )
|
-
-
7 楼
看能不能找到游戏存取状态的表或者链表,搞明白就可以设置它。
|
能力值:
( 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的相关函数
把内存中的这些地址存入文件应该没有问题
关键是读取。。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
想到一个方法,可以利用程序本身来做游戏模式的切换,在其切换好了,生成了新的扫雷分布之后,再用原来的扫雷分布覆盖,这样。。。好像也不成诶。。。郁闷
不过好像CreateFileA和WriteFile还有ReadFile都没有挂在扫雷上吧,好像还要自己弄一下Import表,用LordPE好像会把自己以前的code的东东覆盖掉的!。。可能是我没有设好边界吧。
|
能力值:
( LV6,RANK:90 )
|
-
-
10 楼
最初由 tempm 发布
不过好像CreateFileA和WriteFile还有ReadFile都没有挂在扫雷上吧,好像还要自己弄一下Import表,用LordPE好像会把自己以前的code的东东覆盖掉的!。。可能是我没有设好边界吧。
98下的扫雷有这个函数吧?因为成绩是记在ini文件里的
不过2000和XP的有注册表的相关函数
可以把他写在注册表里啊,数据不多效果和写在文本里一样的
|
能力值:
( LV4,RANK:50 )
|
-
-
11 楼
我改过一个作弊版的
雷的位置在内存中是固定的,可以做一个外挂比较容易。
而且初中高级都很容易找到在那里的。
做一个内存补丁很容易。
在原来的基础上比较困难。
|
能力值:
(RANK:10 )
|
-
-
12 楼
找到地雷数组就好办了。可以直接判断是否地雷。我在98、2000下都做过,每次扫雷都是1秒。
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
最初由 乱乱 发布 我改过一个作弊版的
雷的位置在内存中是固定的,可以做一个外挂比较容易。 而且初中高级都很容易找到在那里的。 做一个内存补丁很容易。 ........
这个以前就做过了,以前直接点鼠标左键,遇雷扫雷^^:
把其中的函数修改了一下就可以了!其实如果把我现在修改的那个把雷数比较修改成99,把Flag永远置0的话也差不多是一个样子。
但时光作弊太没有意思了。
现在主要是想做快存快取啦,我又想到一个方法了,可以向重放的方式,Reload雷区分布之后,把挖过的用扫雷内的那个挖雷函数重新Execute。这样或许可行。我目前正在做快存那部分,用RegSetValueW,辛苦工作ing^^:
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
最初由 baddog911 发布 找到地雷数组就好办了。可以直接判断是否地雷。我在98、2000下都做过,每次扫雷都是1秒。
已经找到了,楼上的大哥已经放出了所有的有用地址
你做的是不是把SetTime的时间设置的很大很大?我也作了,不过不好玩!如果你方法不同的话,分享一下。
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
扫雷这个游戏只要知道规则就可以了,我不需要什么作弊过专家级,这游戏又没有什么运气成分,很多人说还是有运气的,我都好笑,过不去就说那是运气,何必呢。:D
|
能力值:
(RANK:10 )
|
-
-
16 楼
最初由 tempm 发布
已经找到了,楼上的大哥已经放出了所有的有用地址
你做的是不是把SetTime的时间设置的很大很大?我也作了,不过不好玩!如果你方法不同的话,分享一下。
我的做法是单独启动一个进程,有个扫雷的按钮,点一下马上读取地图数组,对于每个没有地雷的格子发送一条鼠标左键按下的消息。一瞬间就结束了,但总是显示耗时1秒。
|
能力值:
( LV4,RANK:50 )
|
-
-
17 楼
我的是重写雷的位置数据所有的雷都放到左上角
|
能力值:
( LV2,RANK:10 )
|
-
-
18 楼
最初由 乱乱 发布 我的是重写雷的位置数据所有的雷都放到左上角
寒,这不是没有什么意义嘛!本来嘛!扫雷就是玩兴趣的,嘻嘻
|
能力值:
( LV2,RANK:10 )
|
-
-
19 楼
最初由 baddog911 发布
我的做法是单独启动一个进程,有个扫雷的按钮,点一下马上读取地图数组,对于每个没有地雷的格子发送一条鼠标左键按下的消息。一瞬间就结束了,但总是显示耗时1秒。
这里来了一个问题了,你怎么读取扫雷程序的内存?我对编程不懂,想问一下,说不定我的快取功能就要向你这样做。
|
能力值:
( 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.
|
能力值:
( LV2,RANK:10 )
|
-
-
21 楼
Cool, 小鸟再这里谢过了
|