查看原文
其他

[系统安全] 二十八.CS逆向分析 (1)你的游戏子弹用完了吗?Cheat Engine工具入门

Eastmount 娜璋AI安全之家 2022-11-30

前文分享了WannaCry勒索病毒,主要通过IDA和OD逆向分析蠕虫传播部分,详细讲解蠕虫是如何感染传播的这篇文章将回到逆向知识,利用Cheat Engine工具逆向分析游戏CS1.6,并实现无限子弹功能。基础性文章,主要让大家看看逆向基础,并给反外挂工程师一些思考和借鉴。同时,本文参考B站老师的视频(文末),希望对您有所帮助,如果存在错误或不足之处,还望告知,侵删,加油!

作者作为网络安全的小白,分享一些自学基础教程给大家,主要是关于安全工具和实践操作的在线笔记,希望您们喜欢。同时,更希望您能与我一起操作和进步,后续将深入学习网络安全和系统安全知识并分享相关实验。总之,希望该系列文章对博友有所帮助,写文不易,大神们不喜勿喷,谢谢!如果文章对您有帮助,将是我创作的最大动力,点赞、评论、私聊均可,一起加油喔~

文章目录:

  • 一.CS1.6游戏介绍

  • 二.逆向分析子弹数对应地址

  • 三.地图变换子弹无限固定

  • 四.逆向分析装备类型

  • 五.逆向分析寻找基址并实现无限子弹

  • 六.总结


从2019年7月开始,我来到了一个陌生的专业——网络空间安全。初入安全领域,是非常痛苦和难受的,要学的东西太多、涉及面太广,但好在自己通过分享100篇“网络安全自学”系列文章,艰难前行着。感恩这一年相识、相知、相趣的安全大佬和朋友们,如果写得不好或不足之处,还请大家海涵!

接下来我将开启新的安全系列,叫“系统安全”,也是免费的100篇文章,作者将更加深入的去研究恶意样本分析、逆向分析、内网渗透、网络攻防实战等,也将通过在线笔记和实践操作的形式分享与博友们学习,希望能与您一起进步,加油~

推荐前文:网络安全自学篇系列-100篇

https://blog.csdn.net/eastmount/category_9183790.htm

作者的github资源:

  • WannaCry:https://github.com/eastmountyxz/

    WannaCry-Experiment

  • 逆向分析:https://github.com/eastmountyxz/

    SystemSecurity-ReverseAnalysis

  • 网络安全:https://github.com/eastmountyxz/

    NetworkSecuritySelf-study


声明:本人坚决反对利用教学方法进行犯罪的行为,一切犯罪行为必将受到严惩,绿色网络需要我们共同维护,更推荐大家了解它们背后的原理,更好地进行防护。该样本不会分享给大家,分析工具会分享。(参考文献见后)



一.CS1.6游戏介绍

《Counter-Strike》是Valve1999年夏天开发的射击系列游戏,创始人是杰斯·克利夫和李明(Minh Gooseman Lee)。他们后来和游戏一起进入了Valve。这篇文章逆向分析的就是这款非常经典的游戏CS1.6。

调整游戏取消全屏,设置视频位“窗口游戏”,方便我们调试动态分析。

接着点击“新建游戏”,我们选择一幅最经典的地图“de_dust2”

游戏设置可以将每局时间设长,方便调试。

游戏加载界面如下图所示:

开始吧,让我们逆向分析CS。

逆向分析环境:

  • 游戏版本:CS1.6

  • 逆向工具:Cheat Engine 6.7

  • 操作系统:Wndows10


二.逆向分析子弹数对应地址

第一步,按下ESC,回到桌面打开Cheat Engine软件。

版本信息为Cheat Engine 6.7,其主界面如下图所示。

第二步,点击左上角小电脑加载CS进程。
该软件能监控游戏内存的数据,方便我们后续的读写修改。每一款游戏加载之后,就会存入内存中,无论是金钱、子弹数、时间都存储在内存中。

打开后如下图所示,接下来我们看看怎么操作CE。

第三步,回到CS游戏,我们看到当前的子弹数量是“17”,在CE中输入“17”并点击首次扫描。

扫描结果如下图所示,共发现结果4851条。

当我们点击再次扫描,其结果变为4829,之后再无变化。那么,我们怎么办呢?

第四步,我们继续射击,然后输入新的数字“16”进行搜索。

发现结果还剩196条。

接着继续射击及扫描,但此时的结果为196后,不再继续减少。

第五步,Ctrl+A选中所有结果,然后右键“加入选择的地址到地址清单”

第六步,结合二分法,按住Shift键选中一般内容,右键更改记录数值,比如20。

修改后的内容如下图所示:

接着回到游戏,我们可以看到子弹数量变成了20,然后点击射击变成了19,接着我们删除不是20的其余部分。

第七步,同样的方法我们修改剩余的一半为30,继续看游戏对应的数值是否变化,并删除不是对应的部分值。

注意,规则总结如下:

  • 如果选中正确地址并修改,则未选中部分的数值隔一段时间后会跟着变为30。

  • 如果未选中正确地址修改,则剩余部分会跟随之前的子弹数量变换。比如,我将第一行数值修改为20,它立刻会自动变成84(当前子弹数)。


最终确定的地址为:

  • 0129BEE4


第八步,选中该条记录,双击修改为“手枪子弹数”,然后修改子弹为88。

修改该值可以看到游戏中的子弹数量也跟着变化。

继续修改为100发,游戏子弹数量继续变化。

那么,我们怎么能将子弹数量固定(不减少)呢?

第九步,点击锁定,它会将内存地址锁定。。

此时,再回到游戏中来,射击后的子弹不再变化。

最后,我们换一张地图来试试效果。按下H换地图,但子弹发生变化了。那怎么解决呢?

写到这里,先简单总结:

  • 该部分主要通过Cheat Engine来查找存放子弹的地址,并设置固定值。

  • 后续读者可以尝试C++代码自定义子弹数量并实现该无限子弹功能。


三.地图变换子弹无限固定

这部分我们将解决地图变换,但CS1.6子弹数量仍然保持不变的功能。

  • 解决方法是:找到内存地址中存放子弹且不改变的地址


程序打开后会加载到内存中,通常分为两块内存,其中一块称为“基址”。

  • 基址:不会改变,用于存放血量、金钱等。当它不够或需要存放更多数据时,它会跟系统申请地址,这个地址是系统分配的。所以,变换地图后显示的子弹数地址也会发生变化,我们需要找到其变化规律(偏移地址)即可


第一步,通过前面部分的方法找到子弹数存放的地址(复现上面操作)。
在逆向过程中,我们可以将每局时间设置长一些,方便调试。

我们可以看到,在196条结果中有绿色和黑色地址。

  • 绿色就是基址,只要程序启动,这些地址就归游戏使用。

  • 黑色是临时申请使用的。


因此,我们需要找到一个绿色的地址,但其实这里的绿色地址都不是我们想要的地址。

接着使用二分法找到对应的子弹数量地址。

同样的方法,我们最终确定地址为:

  • 0BB556DC


但是,它是临时存放子弹数量的地址。现在我们有个新的猜想,通过一张图来构想如何寻找基址。

  • 当前子弹数量为17,对应的地址为0BB556DC,它存放在临时地址中(换地图可能变换)。而对应的基址xxxxx,存储的是临时地址的地址,即0BB556DC。这里我们需要通过地址关联,从而进一步发现基址,实现地图变换子弹无限固定的功能,并且它可能是多层指针


第二步,双击地址并复制0BB556DC,然后勾选“十六进制”点击“首次扫描”,运行如下图所示。

但此时没有任何数据,上面的猜想是失败了吗?

原因是存在偏移地址(指针偏移),因此我们需要执行如下操作。

第三步,选中地址右键“找出是什么改写了这个地址”。

接着弹出如下图所示的对话框。

进入游戏尝试射击,可以看到:

  • 计数:调用次数

  • 指令:汇编代码

  • 同时给出该汇编指令的上下文


第四步,分析汇编代码。
汇编代码如下,“mov [esi+000000CC],eax” 表示将eax赋值给[esi+000000CC]中。这个偏移加上后就对应我们的子弹数。分析如下:

  • ESI = 0BB5561

  • 0ESI + CC = 子弹临时地址0BB556DC

170E6E9A - 48 - dec eax
170E6E9B - 8B CE - mov ecx,esi
170E6E9D - 89 86 CC000000 - mov [esi+000000CC],eax <<
170E6EA3 - 8B 86 A4000000 - mov eax,[esi+000000A4]
170E6EA9 - 8B 40 04 - mov eax,[eax+04]

EAX=0000002C
EBX=00000000
ECX=0BB55610
EDX=02511E60
ESI=0BB55610
EDI=00000001
ESP=0019F324
EBP=00000001
EIP=170E6EA3

接着我们点击“手动加入地址”,然后输入0BB55610加上CC,可以看到结果为18,对应当前子弹数量。

接着我们进行简单的描述备注。

第五步,我们继续扫描,找到存放0BB55610地址的对应地址,共计6个结果。

  • 0BB55610


但是,它们还不是绿色的基址,说明它们是存放临时数据的临时地址,其结果图有可能如下图所示。

接下来,我们继续查找。

第六步,进入游戏中尝试射击,或按下H尝试刷新游戏。

我们可以看到出现了4个红色的数值修改,

并且我们的子弹数现在是20,不再是14。

  • 地址:0BB5E89

  • 4数值:01213E90

  • Previous:0BB55610


第七步,接下来我们依次对这些地址进行扫描。

注意:有时候场景自动切换会导致之前增加的“临时子弹数”和“子弹数+CC”地址失效,这需要我们重新扫描子弹数量,方法和之前的一样。建议先调整无限时间,方便我们调试程序。

如果你是初学者,建议反复熟悉这些流程。这里再简单总结步骤:

  • 扫描数值子弹数

  • 射击继续扫描得到196个结果,选择加入地址清单

  • 然后二分查找确定手枪子弹数临时地址
    – 0BB86674

  • 接着选中地址“找出什么改写这个地址”,发现 mov [esi+000000CC],eax
    – EAX = 00000035 - 子弹数(53)

    – ESI = 0BB865A8

    – 0BB865A8 + CC = 0BB86674(临时地址)

  • 勾选十六进制扫描地址0BB865A8

  • 最后依次判断其4条返回结果的地址(均没有绿色基址)


第八步,依次添加7条结果,然后进行十六进制地址新扫描。

如果点击“新的扫描”没有反馈结果,可以直接删除,发现这7条内容都没有结果。

该部分暂时失败!
逆向其实就是反复去尝试的过程,假设失败是非常正常的事情。


四.逆向分析装备类型

第一步,接着上面的过程继续观察,我们尝试丢枪,看这些地址的变化情况。

  • 地址19C2CD30 => 00000000

  • 地址19C2CD40 => 0122DB60

  • 地址19C2CD44 => 0122DB60


我们再尝试拿取手枪,数值还原成0BB865A8。

接着再次丢枪,换成AK,并尝试设计,发现子弹数不变,说明前面临时变量对应手枪的子弹数。

  • 地址19C2CD30 => 00000000

  • 地址19C2CD40 => 19860DE0

  • 地址19C2CD44 => 19860DE0


尝试换成刀其值也对应变化。

因此我们进行简单的备注,这个地址是手持物品,其它无关的地址我们删除。

  • 当前手持物品1

  • 当前手持物品2

  • 另一个即是否持手枪的标记变量


我们尝试把AK扔掉,发现其地址继续变换。

  • 地址19C2CD30 => 00000000

  • 地址19C2CD40 => 0122DB60

  • 地址19C2CD44 => 0122DB60


第三步,我们需要确定手持物品的基址,右键点击“找出是什么改写了这个地址”。

变换结果如下图所示:

核心代码如下,偏移地址是5E8。

  • mov [esi+000005E8],edi

  • ESI = 19C2C758

17171C4A - 6A 00 - push 00
17171C4C - FF 90 0C010000 - call dword ptr [eax+0000010C]
17171C52 - 89 BE E8050000 - mov [esi+000005E8],edi <<
17171C58 - 8B 17 - mov edx,[edi]
17171C5A - 8B CF - mov ecx,edi

EAX=00000000
EBX=0122DB60
ECX=19C2C758
EDX=0C2A3C54
ESI=19C2C758
EDI=0122DB60
ESP=0019F9E0
EBP=19860DE0
EIP=17171C58

将当前物品1描述为加上5E8。

同时,我们点击手持物品2,可以看到其计数在不断刷新。它是不断去查询玩家手持物品。

  • mov [esi+000005EC],eax

  • ESI=19C2C758


对其进行备注如下图:

  • 当前手持物品1-19C2C758+5E8

  • 当前手持物品2-19C2C758+5EC


此时存在两个偏移地址,下面介绍手动添加过程。

第四步,点击“手动加入地址”,点击“指针”,并输入19C2C758+5E8+CC。

可以看到当前AK的子弹数为12。

尝试射击后变成了10。

我们尝试换成手枪,发现子弹数变成了14,说明该指针对应的值为当前子弹数。

  • 当前手握枪的子弹数:19C2C758+5E8+CC



五.逆向分析寻找基址并实现无限子弹

接着之前继续。

第五步,我们继续查询存放该值的基址,扫描地址19C2C758。
发现仍然没有绿色的值,说明不是我们要找的值。

先删除为0的值,然后继续添加查找基址。添加进去后换一张地图,显示如下图所示:

我们需要通过地图切换来查询是否存在对应的基址,通过丢枪、换地图、买枪各种操作,最终保留2个可能的地址(非0)。

第六步,点击“找出什么改写了这个地址”按钮,然后切换地图看其地址变化情况。

最终确定0C2A3C50地址在切换地图时发生变化,刷新地址先清零,然后再将EAX赋值

  • mov [esi+7C],00000000

  • mov [esi+7C],eax

  • ESI = 0C2A3BD4


找到这个地址之后,我们通过同样的指针方式进行确认。

  • 0C2A3BD4+7c+5e8+cc


第七步,继续查找0C2A3BD4地址,发现了3个绿色基址。

将绿色的添加进去继续判断。

注意,此时的三级指针地图切换地址对应当前子弹数量,即使我们切换地图该值仍然一一对应。


第八步,尝试切换地图,发现这三个绿色值仍然没有变化。接着我们断开连接,然后删除最后一个值。

删除基址3,如果CE断开可以重新打开CS程序即可。

最终确认基址1和基址2应该都是正确的。

第九步,双击基址2的地址并复制,然后进行手动添加地址。

  • 基址1:pcawwclconfig_mm.dll+10A40

  • 基址2:cstrike.exe+1100ABC


第十步,通过基址添加三级指针,从而定位子弹数。

  • cstrike.exe+1100ABC+7c+5e8++cc


注意该基址带有cstrike.exe名称。

最后锁定该地址,对应下图最后一行。

至此,我们无限子弹的功能成功完成,并且切换地图和枪也是无限子弹。运行效果如下图所示:

最重要的截图如下所示:


六.总结

写到这里,这篇文章就介绍完毕。本文主要通过Cheat Engine逆向分析CS1.6游戏,并实现无限子弹功能,希望您喜欢。

  • 一.CS1.6游戏介绍

  • 二.逆向分析子弹数对应地址

  • 三.地图变换子弹无限固定

  • 四.逆向分析装备类型

  • 五.逆向分析寻找基址并实现无限子弹


同时,文章存在几个问题需要读者自行完善(作者也会继续分享)。

  • 问题1:锁定后敌人也是无限子弹,怎么解决呢?

  • 问题2:读者能不能用VS编写程序定位基址,然后能修改自己想要的子弹数量。

  • 问题3:FPS游戏怎么实现穿墙、血量无敌、猫准等功能呢?

  • 问题4:怎么通过OD动态调试CS1.6游戏呢?


这篇文章中如果存在一些不足,还请海涵。作者作为网络安全初学者的慢慢成长路吧!希望未来能更透彻撰写相关文章。同时非常感谢参考文献中的安全大佬们的文章分享,感谢师傅们的教导,深知自己很菜,得努力前行。

前文回顾(下面的超链接可以点击喔):


2020年8月18新开的“娜璋AI安全之家”,主要围绕Python大数据分析、网络空间安全、人工智能、Web渗透及攻防技术进行讲解,同时分享CCF、SCI、南核北核论文的算法实现。娜璋之家会更加系统,并重构作者的所有文章,从零讲解Python和安全,写了近十年文章,真心想把自己所学所感所做分享出来,还请各位多多指教,真诚邀请您的关注!谢谢。2021年继续加油!

晚安女神,爱你和小宝❤

(By:Eastmount 2021-04-19 周一夜于武汉)


参考文献:

  • https://www.bilibili.com/video/BV1F4411z7Wx


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存