黄金岛棋牌游戏是否存在操纵玩家输赢?

黄金岛棋牌游戏是否存在操纵玩家输赢?

这种东西肯定会存在操纵玩家输赢的,不仅仅是这个,所有的游戏都存在这个问题的

游戏是人写出来的,用计算机做出来的东西本来就不存在随机性

这里给出一些代码,来给你看下这个东西是如果作弊的

在游戏中寻找数据来进行标识什么时候显示什么游戏界面比如下面是我找到的标识

**************************************************************

s1:string='493278|dc|1b0';///是否开始;

s2:string='493278|dc|368';/////是否下注;

s3:string='493278|dc|2b8';/////是否摊牌;

s4:string='493278|dc|208'; /////是否当庄家;

s5:string='493278|dc|4c8'; /////是否全部开始了

s6:string='493278|dc|164|4|a4'; /////是否有牌了

****************************************************************

我写了一个函数来读取上面的数据的

function readint(h:hwnd;s:string):integer; //h:目标句柄。。

var

wnd:hwnd;

pid:hwnd;

pHandle:hwnd;

hp:integer;

i:array [1..10]of integer;

nSize:DWORD;

j:integer ;

lpNumberOfBytesRead:DWORD;

list : TStringlist;

begin

try

// nSize:=10;

//hp:=AllocMem(nSize);

// Wnd := FindWindow(nil,'Element Client');

list := TStringlist.Create;

list.Delimiter := '|';

list.DelimitedText := s;

for j:=1 to list.Count do

begin

i[j]:=strtoint('$'+list.Strings[j-1]);

end;

GetWindowThreadProcessId(h,@pid);

pHandle:=OpenProcess(PROCESS_ALL_ACCESS,false,pid);

ReadProcessMemory(pHandle,Pointer(i[1]),@hp,sizeof(hp),lpNumberOfBytesRead);

IF list.Count>1 then

begin

for j:=2 to list.Count do

begin

hp:=hp+i[j];

ReadProcessMemory(pHandle,Pointer(hp),@hp,sizeof(hp),lpNumberOfBytesRead);

end;

end;

result:=hp;

except

end;

end;

简单说一下上面的参数s:string 是代表什么吧

想必你们找到基址和便宜吧

比如 s1:string='493278|dc|1b0';///是否开始;

如果用od查看的时候就是 dd [[493278]+0dc]+1b0

由于我需要再游戏中进行批量读取。。所以就写了上面的那个函数来的读取指定程序的数据

***********************************************************

上面基本就是我需要的游戏的全部数据了,由于还要进行识别牌的点数。所以只能说基本上上面的数据就行了

我遇到的人他们有的人要求全部替换牌,不用识别牌。。。。。所以说如果那样的话那么上面的数据就足够了。。。所以说想做的话可以不用多少逆向的东西,不用你找太多东西就能达到换牌的目的,其实最大的问题是在怎么处理好你和游戏之间进行同步了。。。详细细节也不好说清楚。。。所以只是稍微提一下,就是说什么时候你的牌覆盖游戏的牌。。什么时候你软件隐藏。什么时候你软件出现在什么位置。考虑细节比如当其他窗口打开。比如浏览器打开。由于只是你的软件进行覆盖到游戏上面,那么你这个时候就需要进行相应的处理了

其实说起来挺简单的,但是具体操作起来就麻烦了。。因为你必须保证到人家看不出任何破绽,不然的话你的软件就没有任何价值了

++++++++++++++++++++++++++++++++++++++++++++++++++

下面我就说一下如何读取游戏中牌的点数了

关于识别游戏牌的点数曾经我发过一篇贴子,但是游戏当时图片丢失了,所以我这次再简单说一下我的思路吧

由于当时时间挺急的。我想直接从游戏中读取游戏牌的点数。但是当时一直没思路该从哪里下手

后来在游戏中调试看到了user32.loadbitmap

0040E5B6 CC int3

0040E5B7 8BEC mov ebp, esp

0040E5B9 8A45 08 mov al, byte ptr [ebp+8]

0040E5BC 50 push eax

0040E5BD EB 08 jmp short 0040E5C7

0040E5BF CC int3

0040E5C0 55 push ebp

0040E5C1 - E9 88BB1C00 jmp 005DA14E 跳到我的区段中去执行

0040E5C6 50 push eax

0040E5C7 E8 64FFFFFF call 0040E530

0040E5CC 85C0 test eax, eax

0040E5CE 75 04 jnz short 0040E5D4

0040E5D0 33C0 xor eax, eax

0040E5D2 EB 2F jmp short 0040E603

0040E5D4 837D 0C 00 cmp dword ptr [ebp+C], 0

0040E5D8 74 09 je short 0040E5E3

0040E5DA 8B4D 0C mov ecx, dword ptr [ebp+C]

0040E5DD C701 FF00FF00 mov dword ptr [ecx], 0FF00FF

0040E5E3 0FB655 08 movzx edx, byte ptr [ebp+8]

0040E5E7 85D2 test edx, edx

0040E5E9 75 04 jnz short 0040E5EF

0040E5EB C645 08 FF mov byte ptr [ebp+8], 0FF

0040E5EF 0FB645 08 movzx eax, byte ptr [ebp+8]

0040E5F3 50 push eax

0040E5F4 6A 00 push 0

0040E5F6 FF15 6CE14700 call dword ptr [<&KERNEL32.GetModuleH>; kernel32.GetModuleHandleA

0040E5FC 50 push eax

0040E5FD FF15 B8EC4700 call dword ptr [<&USER32.LoadBitmapA>>; USER32.LoadBitmapA

0040E603 5D pop ebp

0040E604 C2 0800 retn 8

于是我想到可以从这里下手,于是我就首先给游戏加了个区段,,才开始的时候这个函数本来是出现在游戏中一个dll中的,后来游戏改了,他把这段代码改到游戏中去了,你一看上面的函数就知道是怎么回事了,于是我给游戏加了个区段,,在这段代码上面的 某个地方改了他运行的流程,让他跳到我的区段中去执行,那么数据处理需要经过分析后才行,我通过分析后发现他传进来的参数就是上面用restorator中和bmp的名称存在一种想应的关系,,于是我就写了下面这段代码

005DA000 - E9 B245E3FF jmp 0040E5B7 跳回去

005DA005 90 nop

005DA006 90 nop

005DA007 90 nop

005DA008 90 nop

005DA009 90 nop

005DA00A 90 nop

005DA00B 90 nop

005DA00C 90 nop

005DA00D 90 nop

005DA00E 90 nop

005DA00F 90 nop

005DA010 83F8 00 cmp eax, 0

005DA013 75 17 jnz short 005DA02C

005DA015 C705 E84D4900 0>mov dword ptr [494DE8], 5

005DA01F 90 nop

005DA020 90 nop

005DA021 90 nop

005DA022 ^ EB DC jmp short 005DA000

005DA024 90 nop

005DA025 90 nop

005DA026 90 nop

005DA027 90 nop

005DA028 90 nop

005DA029 90 nop

005DA02A 90 nop

005DA02B 90 nop

005DA02C 81F9 00020000 cmp ecx, 200

005DA032 7D 0C jge short 005DA040

005DA034 ^ EB CA jmp short 005DA000

005DA036 90 nop

005DA037 90 nop

005DA038 90 nop

005DA039 90 nop

005DA03A 90 nop

005DA03B 90 nop

005DA03C 90 nop

005DA03D 90 nop

005DA03E 90 nop

005DA03F 90 nop

005DA040 81F9 00030000 cmp ecx, 300

005DA046 ^ 7D B8 jge short 005DA000

005DA048 833D E84D4900 0>cmp dword ptr [494DE8], 1

通过上面的操作我将棋牌的牌的点数放到游戏中指定的一个内存地址也就是基址中

于是我通过下面的函数就可以读出牌的点数(没花色。因为没必要,所以就没写出计算花色的代码)

i[1]:=readint(game_handle,'494E00');

i[2]:=readint(game_handle,'494E04');

i[3]:=readint(game_handle,'494E08');

i[4]:=readint(game_handle,'494E0c');

i[5]:=readint(game_handle,'494E10');

上面的基的基址中的数据全是我上面代码自动写进去的。。。。由于当时做的时候牌就只有五张。所以我就定义了五个变量来读取牌的点数

关于这些东西就讲到这里,其实你要是懂逆向方面的技术,这些东西背后的套路,你绝对能够看的一清二楚的