吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 8510|回复: 130

[原创] 对CS1.6游戏的分析及心得

    [复制链接]
L15263458908 发表于 2020-3-17 17:19
本帖最后由 L15263458908 于 2020-4-28 15:14 编辑

前言

前段时间分析了一下CS1.6游戏,一直没有时间整理思路写帖子,最近,由于疫情关系,忽然想起了这件事,又重新回顾了一下,写下这篇文章与网友们互相交流学习。
本文主要是讲一下指针扫描器和Ultimap的具体使用以及它的强大之处,然后讲一下自己分析游戏数据的一些心得。

使用指针扫描器快速寻找基址

使用CE寻找基址,一般的思路就是

  • 查找游戏数据,找到数据的临时地址
  • 右键查看谁改变了这个地址指向的数据,得到一个地址X + 偏移
  • 然后我们再内存搜索地址X,得到很多地址Ys,一个个右键查看谁改变了这个地址Y指向的数据,刷新游戏
    然后再找地址

就这样,一层层的去上找,不断尝试,最终找到绿色的即为基址。可见这种找基址的方式非常的麻烦,这里介绍一个神奇的工具,CE的指针扫描器 ,可以帮助快速找到基址
我们开局游戏,添加几个机器人,(添加机器人的目的是,因为找到基址后,即便不刷新游戏,有的基址指向的数据是不断变化的,其实里面是敌人和队友的基址,为了排除这种情况,添加几个机器人)
拿HP做实现,找到HP的临时地址,右键->对这个地址进行指针扫描

1.png

可以发现找到了403个数据

2.png

然后我们进行筛选,这里我们可以通过最后一层偏移进行筛选,我们对HP数据右键->找出是什么改写了这个地址,扔个手雷使自己掉血

3.png
4.png

可以发现,最后一层偏移是160,现今HP是4,下面进行筛选

5.png
6.png
7.png

经过筛选后,进行排序,然后双击第一个,添加到数据列表,退出游戏重新打开,发现里面指向的数据仍然是自己的HP,它就是基址。
其实在筛选的过程中,还有一些其他技巧,比如这个例子,在找到改变HP的地址后,可以查看相关地区汇编代码来寻找倒数第2层偏移

8.png

比如这里,可以发现mov eax, [esi+04],而 eax + 160是HP的地址,所以可以判断倒数第2层偏移是4,这样在筛选的时候可以加上二层偏移,当然也可以再往上找寻找倒数第3层偏移,使筛选的结果更准确。

通过搜索部分数据猜测游戏结构体来分析其他数据

通过上面指针扫描器的方法,我们又找到了一些其他数据的基址

属性 地址
坐标X [[[cstrike.exe+11069BC]+7C]+4]+8
坐标Y [[[cstrike.exe+11069BC]+7C]+4]+C
坐标Z [[[cstrike.exe+11069BC]+7C]+4]+10
HP [[[cstrike.exe+11069BC]+7C]+4]+160
是否掉血(0免疫伤害) [[[cstrike.exe+11069BC]+7C]+4]+16C
护甲 [[[cstrike.exe+11069BC]+7C]+4]+1BC
阵营(1恐怖分子2反恐精英) [[cstrike.exe+11069BC]+7C]+1C8
我的金钱 [[cstrike.exe+11069BC]+7C]+1CC
随地购物(1) [[cstrike.exe+11069BC]+7C]+3C0
准星指向(0墙1友2敌) [[cstrike.exe+11069BC]+7C]+710
当前枪子弹数目 [[[cstrike.exe+11069BC]+7C]+5EC]+CC
当前枪后坐力 [[[cstrike.exe+11069BC]+7C]+5EC]+100
是否正在使用武器 [[[cstrike.exe+11069BC]+7C]+5EC]+D4
左键冷却 [[[cstrike.exe+11069BC]+7C]+5EC]+B8

通过分析的这些数据可以猜测一下人物的结构体
[cstrike.exe+11069BC]+7c]             存放的是整个人物的基址
[[cstrike.exe+11069BC]+7c]+4]         存放的关于游戏内人物具体属性的具体地址
[[cstrike.exe+11069BC]+7c]+5EC]        存放的是使用武器的地址
我们通过猜测结构体,来到具体的内存位置,对人物进行操作,然后对内存进行观察,可以发现一些其他好玩的数据,这里我们来武器的地址为例  

9.png

首先在地址列表中添加一个地址,指向当前的使用武器,通过切换武器来找到每个武器的地址,进而对相关内存区域进行对比
打开分析数据窗口,填入当前主武器,副武器,刀子的地址

10.png

11.png

我们切换武器和左键点击,观察内存,对3个数据进行对比
我们可以很明显的发现3个变化,即+D4这个区域,如果为1的话,表示当前武器正在使用
+B8这个位置,如果持续点击左键的话,这个位置的数据会增加

12.png

我们将刀子+B8的数据锁定为-1,就会出现2秒17刀的效果,,,


通过这种方式,不断进行内存数据的对比,也可以发现很多其他好玩的数据,感兴趣的网友自行尝试。这里讲解的主要目的主要是通过猜测游戏结构体来获取游戏的相关数据

13.png

使用Ultimap分析手雷CALL实现自定义手雷爆炸位置

CE有个强大的功能是Ultimap,可以帮助我们筛选代码,帮助找CALL

14.png

15.png

类似于CE的内存数据筛选,只不过Ultimap是代码筛选,可以搜索程序中的CALL, 比如我们要找手雷爆炸的CALL,可以点击开始,然后晃动窗口,人物随机走动,发射子弹等操作,然后点代码没有运行,筛选除去很多没用的代码,然后扔个手雷,暂停游戏,点代码没有运行,等手雷爆炸后,点代码已经运行,上图中的 代码没有调用计数 可以筛选函数执行的次数,比如可以扔2个手雷等爆炸后,次数设置为2,点击代码没有调用计数按钮就可以筛选

启用Ultimap需要开启DBVM,这个需要电脑支持才可以,点击帮助,关于,可以看到电脑是否支持

16.png

强烈建议使用CE7.0版本,因为我用其他版本的时候,使用Ultimap会失败,甚至有的版本显示系统不支持DBVM,但是7.0不会。还有如果成功开启之后,Banch目标始终为0的话,需要用管理员身份打开目标程序,比如这里需要以管理员身份运行CS1.6

17.png

下面来找手雷爆炸CALL来实现自定义手雷爆炸的位置
我们按照上述的步骤进行一点点筛选

18.png

最终我们找到了这个地址

19.png

对其进行HOOK即可改变手雷爆炸位置  

通过分析堆栈找到准星指向敌人基址,实现吸人

前面已经说过[[cstrike.exe+11069BC]+7C]+710 在这个地址处存放着准星指向的相关数据,比如如果对准敌人,这个地址的数据是2,对准队友是1,对准墙什么的是0,我想实现一个只要准星对准敌人或队友就可以把他吸过来的功能,这个时候就需要获取准星指向人的地址

对  [[cstrike.exe+11069BC]+7C]+710  下断,看是什么改写了这个地址,游戏中添加3个机器人,控制台启用bot_stop 1使机器人停止行动

我们把准星从墙移动到队友身上

20.png

浏览内存区域

21.png

这里我最初是想着通过向上查汇编代码的方式来看看能不能找到队友基址的函数,但是失败了
虽然没有找到,但是肯定有,于是,换种思路,能不能先找到准星对准人物基址,然后再去内存中搜
按照上面指针扫描的方式找到3个机器人的基址(搜血量,然后指针扫描)

22.png

我们在这个那个地址处下断点,将准星移动到敌人上,程序断下,搜索敌人基址

23.png

然后再把准星移动到队友身上,程序断下,发现地址又变为了队友的基址

24.png

再观察程序运行到此处时ESP,[ESP- 0XD8]就是指向人物的基址

mp.dll+9C0EC - 89 7D 00              - mov [ebp+00],edi

当然指向墙的时候,[esp - 0XD8]存放的是其他的数据,因此我们对此HOOK的时候需要判断一下数据是不是人物基址

BOOL IsPeopleBase(DWORD base)  
{
        if (dwPointPeopleBase > 0){
                if (!(0XF0000000 & dwPointPeopleBase))//人物基址前4位通常是0
                        return TRUE;
                try{//如果不是的话也有可能是人物基址,判断血量即可
                        float blood = *(float *)(*(DWORD *)(dwMyBase + 4) + 160);
                        if (blood < 100 && blood > 0)
                                return TRUE;
                }
                catch (...)        {
                        return FALSE;
                }
        }        
        return FALSE;
}

这里贴出按E吸人,按T瞬移过去的全部代码

#include "stdafx.h"

#define PATCHLENGTH        6
#define OFFSET 0X9C0C9                        //HOOK mp.dll的偏移位置

//0AD2C0C9    50              push eax
//0AD2C0CA    6A 00           push 0x0
//0AD2C0CC    51              push ecx
//0AD2C0CD    6A 01           push 0x1
typedef struct _stPos{
        float x;
        float y;
        float z;
}stPos, *pstPos;

HMODULE hMpdll = 0;                                                        //保存mp.dll的基址
HMODULE hModule = 0;                                                //保存cstrike.exe的基址
BYTE byHookPatch[PATCHLENGTH] = {};                        //保存打的补丁
DWORD dwHookAddr;                                                        //保存HOOK的地址
DWORD dwHookRetAddr = 0;                                        //保存HOOK函数的返回点
BOOL IsHooked = FALSE;
DWORD dwPointPeopleBase;                                        //保存指向人的基址
DWORD dwMyBase;                                                                //保存我的基址
pstPos pMyPos;                                                                //我的坐标
pstPos pOtherPos;                                                        //指向人坐标

void __declspec(naked) HookProc()
{
        __asm {
                pushad;
                pushfd;

                mov eax, dword ptr ss : [esp + 0X24 - 0XD8];        
                mov dword ptr ds : [dwPointPeopleBase], eax;        //保存指向人物的基址

                popfd;
                popad;

                push eax;
                push 0x0;
                push ecx;
                push 0x1;
                jmp dword ptr ds:[dwHookRetAddr];
        }
}

void GetHookInfo() {
        hMpdll = GetModuleHandle("mp.dll");
        hModule = GetModuleHandle(NULL);
        dwHookAddr = (DWORD)hMpdll + OFFSET;
        dwHookRetAddr = dwHookAddr + PATCHLENGTH;
        memset(&byHookPatch[0], 0X90, PATCHLENGTH);
        byHookPatch[0] = 0XE9;
        *(DWORD *)&byHookPatch[1] = (DWORD)HookProc - dwHookAddr - 5;
}

void SetHook() {
        DWORD dwOldProtect;
        if (!IsHooked) {
                VirtualProtect((LPVOID)(hMpdll + OFFSET), PATCHLENGTH, PAGE_EXECUTE_READWRITE, &dwOldProtect);
                WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwHookAddr, byHookPatch, PATCHLENGTH, NULL);
                VirtualProtect((LPVOID)(hMpdll + OFFSET), PATCHLENGTH, dwOldProtect, NULL);
                IsHooked = TRUE;
        }
}

void GetPosInfo() {
        dwMyBase = *(DWORD *)((DWORD)((DWORD *)*((DWORD *)((DWORD)hModule + 0X11069BC))) + 0X7C);
        pMyPos = pstPos(*(DWORD *)(dwMyBase + 4) + 8);
}

void CopyPos(pstPos a, pstPos b)
{
        a->x = b->x;
        a->y = b->y;
        a->z = b->z;
}

BOOL IsPeopleBase(DWORD base)
{
        if (dwPointPeopleBase > 0){
                if (!(0XF0000000 & dwPointPeopleBase))
                        return TRUE;
                try{
                        float blood = *(float *)(*(DWORD *)(dwMyBase + 4) + 160);
                        if (blood < 100 && blood > 0)
                                return TRUE;
                }
                catch (...)        {
                        return FALSE;
                }
        }        
        return FALSE;
}

DWORD WINAPI ThreadFunc(LPVOID lParam)
{
        GetHookInfo();
        SetHook();;
        GetPosInfo();
        while(TRUE){
                if (GetAsyncKeyState('E')){                        //按E吸人
                        if (IsPeopleBase(dwPointPeopleBase)) {
                                pOtherPos = pstPos(*(DWORD *)(dwPointPeopleBase + 4) + 8);
                                CopyPos(pOtherPos, pMyPos);
                        }
                }
                else if (GetAsyncKeyState('T')) {        //按T瞬移至指向人身边
                        if (IsPeopleBase(dwPointPeopleBase)) {
                                pOtherPos = pstPos(*(DWORD *)(dwPointPeopleBase + 4) + 8);
                                CopyPos(pMyPos, pOtherPos);
                        }
                }
                Sleep(100);
        }
        return 0;
}

BOOL APIENTRY DllMain( HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved){
    switch (ul_reason_for_call){
    case DLL_PROCESS_ATTACH:
                CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
                break;
    }
    return TRUE;
}

xiren.gif

成果展示

最终,经过不断尝试,自己另外还制作了一个CS1.6的小辅助

25.png

实现功能的视频演示: https://www.bilibili.com/video/av68192542

辅助源码:https://github.com/LiZiQiang191/CS1.6_Hook



最后,制作不易,如果你觉得本文对你有帮助的话,希望你动动小手点点下面的评分,谢谢~~

免费评分

参与人数 56威望 +1 吾爱币 +71 热心值 +51 收起 理由
站在顶点的人 + 1 支持支持!!
mai1zhi2 + 1 + 1 我很赞同!
hwx920301 + 1 + 1 我很赞同!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
zw4218719 + 1 + 1 有没有成品直接用一下
heroking + 1 大佬优秀
佛丶珠 + 1 + 1 用心讨论,共获提升!
msfind + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
300块钱跑啦 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
sniper9527 + 1 + 1 谢谢@Thanks!
万恶的意外 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
Ponderfly + 1 + 1 我很赞同!
幼幼小白兔 + 1 + 1 谢谢@Thanks!
spg200 + 1 + 1 谢谢@Thanks!
shanci521 + 1 热心回复!
masterenlu + 1 + 1 用心讨论,共获提升!
198738655 + 1 + 1 我很赞同!
毛阿毛 + 1 谢谢@Thanks!
sumyes + 1 + 1 谢谢@Thanks!
夜降临Forever + 1 我很赞同!
xingdh + 1 + 1 我很赞同!
Black_山猫 + 1 用心讨论,共获提升!
hhxlrm + 1 + 1 谢谢分享,不过git不下来呢,会自动中断
showwindows + 1 + 1 有所收获
交易的朋友 + 1 + 1 用心讨论,共获提升!
Mini小新 + 1 + 1 谢谢@Thanks!
如风闲云 + 1 + 1 我很赞同!
寒枫雨雪 + 1 + 1 谢谢@Thanks!
鱼在江湖之远 + 1 + 1 虽然看不懂,但是很佩服楼主的耐心
spring104 + 1 用心讨论,共获提升!
rsice + 1 + 1 谢谢@Thanks!
jamesmeng + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
夢裡二三事。 + 1 + 1 谢谢@Thanks!
cr7890 + 1 + 1 谢谢@Thanks!
腾旭 + 1 谢谢@Thanks!
MockingJay + 1 + 1 用心讨论,共获提升!
飞行堡垒 + 1 + 1 用心讨论,共获提升!
Id!0tNe + 1 + 1 热心回复!
wuyaqing981206 + 1 + 1 谢谢@Thanks!
我就是左叔 + 1 + 1 我很赞同!
FFF全部成为F + 1 有很多我不会的呢,拿来参考参考,
lynxtang + 1 + 1 谢谢@Thanks!
琪a + 1 + 1 谢谢@Thanks!
q74330 + 1 楼主很牛比,耐心没的说
boyulin + 3 + 1 我很赞同!
暗夜杀神 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
dmxayjn + 1 + 1 我很赞同!
吾爱支持 + 1 谢谢@Thanks!
炸弹二锅头 + 1 + 1 用心讨论,共获提升!
hf2009 + 1 + 1 用心讨论,共获提升!
BG沉默 + 1 + 1 谢谢@Thanks!
罗氏家族 + 1 + 1 用心讨论,共获提升!
j542936 + 1 + 1 牛掰~~~
gunxsword + 1 + 1 我很赞同!
alicc + 1 + 1 用心讨论,共获提升!
陈世界 + 1 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

  • · 好帖|主题: 200, 订阅: 19

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

xia1999 发表于 2020-3-17 21:37
炸弹二锅头 发表于 2020-3-17 19:46
哈哈哈哈,你这个太不厚道了,会被打的;记得以前上计算机课的时候,和班上同学打CS就有同学 ...

我高中的时候,也是这样子的。微机课全班男生连局域网打CS,一个课堂整成了网吧,然后有一次我开了gua,然后。。。那一次,我所向披靡。幸亏我没有改名,下课后都在骂是谁作弊
炸弹二锅头 发表于 2020-3-17 19:46
xia1999 发表于 2020-3-17 17:53
emmmm,和室友在宿舍打游戏坑一波

哈哈哈哈,你这个太不厚道了,会被打的;记得以前上计算机课的时候,和班上同学打CS就有同学开挂,那时候不懂太单纯,我还一直奇怪为啥老是挂的莫名其妙,然后下课同学就请我们吃饭坦白了
karius 发表于 2020-3-17 17:33
 楼主| L15263458908 发表于 2020-3-17 17:34
karius 发表于 2020-3-17 17:33
發自肺腑想說一句,,,牛逼!!!!

求评分,求评分
IceRainow 发表于 2020-3-17 17:39
能过175平台的反作弊吗
gtp_ 发表于 2020-3-17 17:40
厉害了。。。
adslbbxin 发表于 2020-3-17 17:42
大老牛逼!厉害厉害
GJH588 发表于 2020-3-17 17:43
看完了,学到了一点知识,谢谢楼主
fzp2077 发表于 2020-3-17 17:43
然而这有什么用
 楼主| L15263458908 发表于 2020-3-17 17:44
fzp2077 发表于 2020-3-17 17:43
然而这有什么用

有用的人自然有用
aixiaodemj 发表于 2020-3-17 17:52
谢谢分享 提供了一种思路 从以前拿CE改小游戏到现在一直很感兴趣
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2020-7-5 21:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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