找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 454|回复: 1

昭姐每天一练- 新手入门假设游戏仅检测关键内存点

[复制链接]

30

主题

1

回帖

0

积分

版主

积分
0
发表于 2013-6-8 10:43:21 | 显示全部楼层 |阅读模式


解决方法:

1. 改变游戏作弊的内存地址:
如:

6F361F79    33C9            xor     ecx, ecx

6F361F7B    B8 01000000     mov     eax, 1   ;此处改为 mov eax,0 实现小地图显示单位   

6F361F80    D3E8            shr     eax, cl

6F361F82    3BC3            cmp     eax, ebx
-------------------------------------------------------
游戏会检测6F361F7C处的内存是不是01 如果不是说明game.dll被修改 即作弊

我们可以改别处也可以实现效果的地方如下:

6F361F79    33C9            xor     ecx, ecx

6F361F7B    B8 01000000     mov     eax, 1

6F361F80    33C0            xor     eax, eax                ;此处修改

6F361F82    3BC3            cmp     eax, ebx

游戏检测 6F361F7C处的内存的话还是01,检测点的内存还是没变!游戏也就查不到了!
国外的MH制作者们也都是经常改变作弊内存地址来逃过检测的。
--------------------------------------------------------------------------------
2.JMP跳转法:

   改变作弊内存地址无效可采用万能方法:检测点前面跳走。然后补上被跳过的代码,然后在跳回来继续执行。
--------------------------------------------------------------------------------------------------------------------------------------

魔兽版本1.24E

我们需要的是修改魔兽内部的一些数据,达到作弊的效果。但是又不能被平台发现。
第一个方法,就是找到暂时还没有被平台发现的地址作弊。(比较麻烦)
比如我自己找了一个地址 6F362393 这里的一句JE 6F3627C9如果nop,也就是让他不跳转的话,如果第一次可见以后,那么该单位以后就都可见了。比如英雄单位。总不可能打了一把DOTA,还没看到这个英雄出现过吧。只要出现在视野里一次,以后就都可见了。

原来的是
6F36238F    CALL EDX                                 ; Game.6F285C30
6F362391    TEST EAX,EAX
6F362393    JE Game.6F3627C9
6F362399    MOV EAX,DWORD PTR DS:[EBX]
6F36239B    MOV EDX,DWORD PTR DS:[EAX+EC]

如果把6F362393 这里修改为NOP那么以后就可以看到敌方英雄了。

修改以后变为
6F36238F    CALL EDX                                 ; Game.6F285C30
6F362391    TEST EAX,EAX
6F362393    NOP
6F362394    NOP
6F362395    NOP
6F362396    NOP
6F362397    NOP
6F362398    NOP
6F362399    MOV EAX,DWORD PTR DS:[EBX]
6F36239B    8B90 EC000000   MOV EDX,DWORD PTR DS:[EAX+EC]


但是这里是肯定被平台检查了,怎么办?

上面 我们看到了一个CALL EDX 本来我们可以修改EDX的值来更改程序流程的,但是不幸的是这个方法1早被封了。额。到此为止就没办法了?

别急。跟进这个 EDX CALL 来到6f285c30还是没有有价值的东西。继续跟进每一个CALL 最后发现了一个好地方

6F285C6A     CALL Game.6F4C3FD0
跟进 看到
6F4C3FD9    CALL Game.6F6DA080
再跟进 6F6DA080

6F6DA080    PUSH ESI
6F6DA081    PUSH ECX
6F6DA082    CALL DWORD PTR DS:[<&KERNEL32.TlsGetValu>; kernel32.TlsGetValue
6F6DA088    MOV ESI,EAX
6F6DA08A    CALL DWORD PTR DS:[<&KERNEL32.GetLastErr>; kernel32.GetLastError
6F6DA090   TEST EAX,EAX
6F6DA092   JE SHORT Game.6F6DA09F
6F6DA094   PUSH 57
6F6DA096   CALL <JMP.&Storm.#465>
6F6DA09B    XOR EAX,EAX
6F6DA09D   POP ESI
6F6DA09E   RETN

哥伦布发现新大陆了~~
6F6DA082 CALL DWORD PTR DS:[<&KERNEL32.TlsGetValu>]; kernel32.TlsGetValue
6F6DA08A CALL DWORD PTR DS:[<&KERNEL32.GetLastErr>]; kernel32.GetLastError

这两句调用了系统的API。估计平台没有在这里检查。那么可以修改这个[KERNEL32.TlsGetValu],[KERNEL32.GetLastErr]里面的东西,来执行我们的代码咩?
很不幸,这个方法2就是之前写的iat hook,估计也被发现了。总之这里也不安全了。。
当然,你可以去系统领空修改GetLastError或者TlsGetValue函数的代码JMP 执行自己的代码,不过我估计危险也比较大,因为game.dll调用这两个函数自iathook以后也许早被平台监控了并且这两个函数很简单,汇编也只有几句,因此很容易检查。

完了,已经没戏了?

由于系统的特殊。我是WIN7的,因此以下的也是针对WIN7 。XP不同,因此会无效

既然跟进了几个CALL,也不差这一个。那么继续跟进,我跟GetLastError。到达了kernel32.dll的领空。
发现是两个连续的 JMP

JMP XXXX


XXXX地址的代码是 jmp [xxxxxxccc]
但是这个xxxxccc里面的地址是kernelbase.dll的GetLastError函数的地址

其实WIN7是这样的,kernel32.dll里面的函数,大多是空壳函数,也就是一个简单的跳转。实际的函数在kernelbase.dll里面。
这样就爽YY了。我们可以在这个JMP里面做文章( jmp [xxxxxxccc])把XXXXCC里面的地址,修改为我们自己的函数,这样就可以修改程序的流程,到我们的函数内执行了。

这里我采用硬编码。修改 JMP [XXXXXXXCCC]

原来是 76EEF10B  FF 25 941DEA76   JMP DWORD PTR DS:[76EA1D94]

这里的 JMP XXXX和JMP [XXXXX]不同
JMP XXXXX指令是E9 相对偏移
JMP [XXXX]指令是FF 25 XXXX 表示跳到 XXXX保存的地址那里去。比如这里
就是跳到76EA1D94保存的地址那里去。OD中看到
DS:[76EA1D94]=7551686B (KERNELBA.GetLastError)
76EA1D94保存的数据是7551686B,这个地址就是 kernelbase.dll里面的GetLastError的地址。
我们只要把我们的HOOK函数的地址数据保存到A里面 然后把FF 25 后面的四个字节修改为A的地址就行了,

A=我的函数的地址

76EEF10B  JMP DS:[A] ;
这样就行了。
当然,我这样说了以后,说不定平台会检查这儿了、先不管,这是以后再说的了。

到此为止,我们已经找到了一个优良的地址,修改程序的执行流程。

但是这和我们要NOP 6F362393 这里的代码有什么联系?修改了流程还是不能把6F362393 的代码NOP啊。

其实,不一定要NOP6F362393 这里的这个跳转。
为什么?因为我们现在在 EDX的CALL里面。当call EDX的时候。CALL EDX的下一行地址已经入栈,这是为了CALL执行完毕以后能正确回到接下来的流程。
当遇到 CALL XXXX程序先PUSH 下一行的地址 再JMP到CALL内

如下
6F36238F     CALL EDX  Game.6F285C30  断点在这里 这一句还没有被执行
6F362391 TEST EAX,EAX 下一句代码


堆栈如下
0012F698   00000000
0012F69C   00000004
0012F6A0   1CFB0020
0012F6A4   171C0088
按F7进入CALL 以后
堆栈如下
0012F694   6F362391  返回到 Game.6F362391
0012F698   00000000
0012F69C   00000004
0012F6A0   1CFB0020
0012F6A4   171C0088
OD已经解释的很清楚了

6F362391 就是TEST EAX,EAX  当call完毕返回以后,程序接下来要运行的地方是6F362391,这样才能保证程序不乱来。

那么我们可以在这个CALL内修改0012F694 里面的6F362391,把他变为6F362399 也就是告诉程序,你执行完这个CALL以后。接下来要运行的地方是6F362399
修改以后
6F36238F CALL EDX ; Game.6F285C30执行的时候把栈内的6F362391修改为6F362399
6F362391 TEST EAX,EAX
6F362393 JE Game.6F3627C9
6F362399 MOV EAX,DWORD PTR DS:[EBX]  程序在执行完CALL EDX 后立即到这里执行。
6F36239B MOV EDX,DWORD PTR DS:[EAX+EC]

很自然的我们就跳过了这个JE Game.6F3627C9 并且没有修改魔兽的内存。
这样相当于NOP的效果。我们必须判断调用GetLastError是不是最先来自6F36238F,如果其他地方调用了我们也修改了那就会崩溃。
接下来就是写代码了。这里贴一段主要代码

MyError=(DWORD)MyGetLastError; 把我的函数存到A里面

LPVOID Kernel32Addr=GetModuleHandle(L"kernel32.dll");
LPVOID GameAddr=GetModuleHandle(L"game.dll");
if(Kernel32Addr==NULL||GameAddr==NULL)
{
  return; 如过没有基址,返回
}

CmpNum+=(DWORD)GameAddr; 判断是不是最先来自6F36238F的调用的一个地址


if(*(DWORD*)((DWORD)Kernel32Addr+HOOKADDR-4)!=0x25ff9090)校验特征码。看看是不是WIN7

{
  return;  }
DWORD Old=0;
VirtualProtect((LPVOID)((DWORD)Kernel32Addr+\
  HOOKADDR),4,PAGE_EXECUTE_READWRITE,&Old);
*(DWORD**)((DWORD)Kernel32Addr+HOOKADDR)=&MyError;修改数据为A的地址
VirtualProtect((LPVOID)((DWORD)Kernel32Addr+\
  HOOKADDR),4,Old,&Old);

HOOK 函数如下

void _declspec(naked)MyGetLastError()裸函数
{
_asm
{
    push ebp
   mov ebp,esp
   pushad 保护现场
   mov eax,[ebp+0x28]//OD边调试边写代码。这里是把
堆栈中特定位置一个值取出来,如果是来自EDX 那么这里的数据就应该是6F362391 ,取出来如果是 CALL EDX的下一行地址那么表示是要修改。
   cmp eax,CmpNum 如果这里是6F362391 表示是我们要改的,如果不是就跳到GetLastError执行
   jne label1
   mov eax,[ebp+0x28] 取出6F362391 放到eax  
   add eax,8   把6F362391 +8以后eax=6F362399;
   mov [ebp+0x28],eax 把6F362399放回去,当EDXcall执行完毕返回的地址就是6F362399了。达到NOP的效果
label1:
   popad恢复现场
   mov esp,ebp
   pop ebp
   mov eax,fs:[0x18]
   mov eax,[eax+0x34]
   ret
}
};





以上只是一个思路。参考,有不对的地方麻烦指出,谢谢 (XP是没法用的)


附件


XP肯定不能使用。由于版本问题 不保证WIN7也能全部使用

0

主题

38

回帖

0

积分

版主

积分
0
发表于 2013-6-8 15:42:55 | 显示全部楼层
昭姐求百事啊
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

果子博客
扫码关注微信公众号

Archiver|手机版|小黑屋|风叶林

GMT+8, 2026-2-1 03:26 , Processed in 0.148860 second(s), 20 queries .

Powered by 风叶林

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表