前言

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

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

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

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

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

可以发现找到了403个数据

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


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



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

比如这里,可以发现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] 存放的是使用武器的地址
我们通过猜测结构体,来到具体的内存位置,对人物进行操作,然后对内存进行观察,可以发现一些其他好玩的数据,这里我们来武器的地址为例

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


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

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

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

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

CE有个强大的功能是Ultimap,Ultimap的功能其实是一个筛选代码的功能

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

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

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

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

最终我们找到了这个地址

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

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

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

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

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

浏览内存区域

这里我最初是企图通过向上查汇编代码的方式来看看能不能找到队友基址的函数,但是失败了
虽然没有找到,但是肯定有,于是,换种思路,能不能先找到队友基址,然后再去内存中搜

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

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

再观察程序运行到此处时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位通常是0return 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;
}

成果展示

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

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

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

对CS1.6游戏的分析及心得相关推荐

  1. 著名电子竞技游戏网站分析

    著名电子竞技游戏网站分析   1. www.replays.net   Replays.net的核心理念是For Fun,For Game,意思是去除那些附加在游戏上的冗杂意义,让游戏回归到娱乐,回 ...

  2. 小白学数据分析--回归分析在游戏人气分析的应用探索

    小白学数据分析--回归分析在游戏人气分析的应用探索 昨天简单说了一下相关分析在充值购买失衡方面的应用,今天就接着昨天的话题,说一下回归分析(Regression  Analysis),回归分析是研究一 ...

  3. 游戏日志分析2:全方位数据采集

    系列文章: 游戏日志分析(1):概览 游戏日志分析(2):全方位数据采集 游戏日志分析(3):程序日志规范与埋点 游戏日志分析(4):线上问题定位与排查 游戏日志分析(5):数据库与日志关联分析 游戏 ...

  4. 【游戏分析】《大王不高兴》1.4.0.0版本 游戏体验分析总结

    <大王不高兴>1.4.0.0版本 游戏体验分析总结 <大王不高兴>由中国人气漫画家使徒子与知名研发商灵游坊双巨头联合打造,是一款中国超人气漫画改编的手游,游戏玩法采二次元策略回 ...

  5. 游戏模块分析总结(4)之系统篇

    游戏模块分析总结(4)之系统篇 发布者: wuye | 发布时间: 2014-12-19 12:10| 评论数: 1 1.系统结构 几乎所有游戏都遵循同一个原则,即:玩→获得产出→能力提升→继续玩.每 ...

  6. 《GTA5》游戏拆解分析

    游戏概述 GTA5,也叫<侠盗猎车手V>(英语:Grand Theft Auto V)是一款开放世界动作冒险游戏. GTA5由Rockstar North制作,Rockstar Games ...

  7. 乐元素 X Hologres:一站式高性能游戏运营分析平台

    客户介绍 乐元素创立于2009年,是一家以游戏研发运营为主营业务的游戏公司,同时业务涵盖动画作品.授权商品.音乐.演唱会.广播剧等在内的知名互动娱乐公司 .乐元素旗下拥有<开心水族箱>.& ...

  8. 《雷曼大冒险》之游戏的分析与设计

      阅读Tracy Fullerton, GAME DESIGN WORKSHOP第2-4章(游戏结构.基本元素.戏剧元素).选择一款你喜欢的中等规模游戏如"植物大战僵尸体"为案例 ...

  9. 游戏模块分析总结(1)之文化内涵篇

    转自:http://www.gameres.com/309364.html 游戏模块分析总结(1)之文化内涵篇 发布者: wuye | 发布时间: 2014-12-10 13:09| 评论数: 3 游 ...

最新文章

  1. AI一分钟|倪光南:“中国芯”切勿重硬轻软;阿里达摩院入职95后最年轻科学家,参与无人车研发...
  2. android2.2
  3. Given an integer, write a function to determine if it is a power of two
  4. LINQ to XML .Net 3.5 中的新XML对象
  5. 《使用Nessus进行渗透测试》- 简介
  6. 电脑技巧:Win10自带存储感知功能给电脑磁盘瘦身
  7. 六步创建TCP服务端
  8. 3.12 SE11创建锁对象
  9. Magento教程 4:主机环境准备
  10. Socket编程总结—Android手机服务器与多个Android手机客户端之间的通信(非阻塞)
  11. Android开发的四大组件
  12. ChartDirector画2D,3D图,MFC画图
  13. 《数字图像处理》实验7
  14. 主成分分析matlab代码_主成分分析,换个角度看世界
  15. arcgis_随机数vb脚本
  16. DFS(深度优先搜索算法)——Java实现(含例题)
  17. Lua游戏中常用到的一些动作
  18. 叮,一份详细的LIN收发器选型指南请查收
  19. eclipse链接Hadoop集群时报错Error:Call From xxx/xxx.xxx.xxx.xxx to hostname1:9000 failed on connection excep
  20. EDA和CAD合并建立电子模块热仿真模型 step by step

热门文章

  1. jQuery 三种点击事件写法
  2. 角速度的相似变换定理的证明
  3. el-upload上传阿里云(oss上传)
  4. 【Python】 标准差计算(std)
  5. 微信公众号--php
  6. unity 高德地图 Android
  7. pandas中计算总体标准差
  8. 如何写长尾关键词的文章
  9. 瞬时转速 matlab,基于瞬时转速的发动机故障诊断研究
  10. linux mint 卸载桌面,Linux Mint 默认桌面 Cinnamon 1.6 正式发布