西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页游戏资讯游戏攻略 → 兽人必须死CE修改器制作方法

兽人必须死CE修改器制作方法

前往专题相关软件相关文章发表评论 来源:西西整理时间:2012/8/31 15:32:13字体大小:A-A+

作者:西西ts点击:471次评论:0次标签: 兽人必须死

兽人必须死9国语言正式版
  • 类型:RPG角色扮演大小:44KB语言:中文 评分:4.0
  • 标签:
立即下载

【前言】:

小弟我前几天才刚刚接触到《兽人必须死》这个游戏,发现主角真的很贱,不过玩起来很过瘾。一直想下载个修改器来痛快虐虐兽人,但是下载的都报毒,不知道是真毒还是误报,反正老婆大人是不同意在她电脑上用。无奈,自己动手丰衣足食吧。

【工具】
CE,这个就不说了,没他啥也甭干了。
OD,就是OllyDbg,小弟我从事软件安全工作,这个工具必不可少。
VC++,我就会C和汇编,其他不会。

【过程】
我打算就做2个功能,1个是锁定钱,一个是锁定魔法值。

先来做锁定钱的,钱因为是数字,好分析。
1 先用CE找到金钱的地址,动态地址就可以,不用找基址。如图1.这个过程巨简单吧,我就不多说了。不会的童鞋可以看诸位大大的教程或者问我。 

 

2.找到后,右键这个地址,选择“什么改写这个地址”。然后切换到游戏,花点钱,就能发现图2的窗口。选择显示汇编,就是红圈的那个。因为我们要分析汇编语言。 

3.接下来,选择显示汇编后,我们看见这个界面:

 

大家注意到,被高亮显示的那句话就是我们的钱被改写的汇编指令。我们可以看到,这句话在内存地址00794B77的位置。当然,各位童鞋要注意,你们显示的地址肯定和我不一样,我每次显示的都不一样。因为这是一个动态链接库(DLL),所以地址是动态的。不过没关系,下面我教大家怎么确定他的动态地址。

4.知道了这个地址,我们就可以改了,但是,就像我说的,他每次都会在00794B77的位置上吗?答案是否定的,退出游戏再进来,地址就变了,因此我们可以肯定的是,这部分代码应该在动态链接库中。好,我们看看他在哪一个动态链接库中。点击如下图的菜单:
 
会显示《兽人必须死》这个游戏所有加载进来的动态链接库。如图:

 

5.从此图中我们看到,动态链接库SaberPlugin的开始地址是00730000,和我们的00794B77位置最近,因此,我们可以确定,刚才位于00794B77的指令在SaberPlugin的动态库中。

6.对于windows系统,我们不知道每次动态库会被加载到内存哪里,但是,我们可以通过系统一些功能函数得到动态库加载的基址,然后根据基址+偏移,最后得到目的地址。接下来,我们计算偏移。请看公式1:
目的地址 = 基址 + 偏移
偏移 = 目的地址 – 基址, 所以我们的偏移地址 = 00794B77 – 00730000 = 64B77。

7.接下来,OD出场了,呵呵,久等了。用OD 附加到游戏进程,然后跳转到指令00794B77的位置,童鞋们要注意了,这时候,要退出CE的调试,否者OD会报告进程被其他程序加载而失败。如图所示: 

8.从OD中了解到,该地址的指令是把寄存器EDI中的数值放到EAX+70的地址中,可以肯定的是,EDI中的数值就是金钱。该地址的二进制指令从图中可以看到,是:89 78 70。上图红圈处。为了简单起见,我直接将二进制指令改成89 60 70,也就是把ESP中的数值放在EAX+70的地址中。肯定好多童鞋问为啥。说实话,就是我懒,因为这是个3字节的指令,如果我添加的指令长度超过3字节,就会覆盖程序正常的指令,导致游戏崩溃。如果实在想添加多于3字节的指令,大家可以去看看远程代码注入的知识,做起来比较复杂,100楼之内也说不清。所以,为了省时间,我直接就修改成ESP了。又有童鞋问了,为啥是ESP?呵呵,其实EAX,EBP,ECX…..等等,都成。因为ESP数值肯定不会是0,所以钱肯定就不是0啊。我是偷懒。大家看我图中,ESP的值是16进制的0018E554,换成10进制,大约是1631572这么多。好家伙,160多万块钱,够了吧!

9.然后就是确定动态库基址的问题,大家请看代码:
HMODULE checkModuleAddr(DWORD id)
{
        HMODULE addr = 0;

        MODULEENTRY32 me32={0};
        //在本进程中拍一个所有模块的快照
        HANDLE hModuleSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,id);
        if(hModuleSnap==INVALID_HANDLE_VALUE)
           return 0;
        //遍历快照中记录模块
        me32.dwSize=sizeof(MODULEENTRY32);
        //cout<<"模块名称及地址";

        do
        {
                if(wcscmp(me32.szModule, modName) == 0)
                {
                        addr = me32.hModule;          
                        break;
                }
        }
        while(::Module32Next(hModuleSnap,&me32));

        CloseHandle(hModuleSnap);

        return addr;

}
这段代码就是获得动态库的代码,得到动态地址后,加上刚才算的偏移(64B77),我们就能够每次都算出目的地址啦,然后用WriteProcessMemory函数改写成赋值ESP的二进制,就大功告成啦。如图(注意左下角的金钱):


    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(0)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)