丸子de爸爸 发表于 2019-11-15 20:40

CS1.6修改器DIY(一)无敌和无限金钱

本帖最后由 丸子de爸爸 于 2019-11-15 20:42 编辑

# 前言

这次的帖子拖得有点久,都怪万恶的双十一。大家见谅,我手恢复好的第一时间就想到了继续分享。

本篇来找一下CS1.6人物的基址和实现人物无敌。

接下来基本的自瞄,透视,这些功能应该都会讲到。当然最终还是会易语言整合一波,请大家多多支持。

欢迎文明转载,请注明出处丸子de爸爸

本文所有技术资料仅供研究,不鼓励任何盗版商用行为

请大家支持正版,支持正版!支持正版!!!

PS:如果对很多概念不懂或者看不明白,建议去看一下之前的系列,学习是一个长期功课,别急于一时。

# 工具

- CheatEngine6.7
- CS1.6本体

# 本次基础概念

**内存,一切皆内存,我们操作的全部都是内存。**

所有地址相关的概念,都可以理解为坐标,用来给我们做标记的而已。

如果实在搞不明白,你想想指南针为啥指向北边,为啥叫南北,只是定义,只是公认

PS:上面这一段是重复了,但是我觉得还是有必要多重复一下,看多了,大家就印象深刻一点。

# 实现步骤

## CS游戏调试前准备

游戏的版本(其实这个不重要,都是类似的逻辑)



首先选择“游戏选项”,把游戏调成窗口模式,然后分辨率自己调到舒服的大小



之后可以新建游戏,设置一下红框内容,为了调试方便。



## 无限金钱实现

### CE查找金钱基址

开始游戏,我这仓库地图,建议选择匪徒。(到时候CT会自己跑进来,不用去找他)



在CE中附加CS1.6,然后先搜索金钱数,16000



回到游戏,买一颗雷,然后搜索新的金钱数量。

只有两个数据,根据颜色发现,一个是基址,一个是动态地址。





右键,将第一个基址的值改为10000



回到游戏,发现数值已经改变,但是这时还不能确定,因为有两个地址

此时我们要做的,就是在游戏里面再购买一个道具

如果地址是正确的,那么两个地址都会变成新的值,而且是从10000开始减少

同理,如果此时金钱还是从15700减少,说明第二个才是正确的金钱地址



购买了一个闪光弹,结果金钱增加到了15500,说明我们之前推断是正确的

第一个基址只是用来做界面显示的,第二个动态地址,才是真正的金钱地址



验证一下,将第二个地址改为10000,然后再回到游戏买一个道具试试

果然如我们推测的那样,金钱也变化了



### CE查找扣除金钱关键逻辑

我们需要实现的功能是,购买物品不花钱,而购买物品是需要扣除金钱的

所以我们需要监控“是什么改写了这个地址”



回到游戏,再随便买一个东西,会发现有一条修改记录

选中这一条,双击



详细信息就是这一条记录产生时的一些信息记录,我们分析一下:

红色的就是当前行,也就是扣除金钱的执行

我们能得到什么信息呢?结合汇编,mov ,ecx

就是给esi+1CC这个内存地址赋值ecx寄存器里面的值,ECX的值为251C,转换为十进制正好是金钱数。

所以我们可以得到esi+1CC里面存放的值,就是金钱

这样我们就可以完全翻译这一波汇编,从上到下解读:

- 将金钱放入ecx中
- 金钱增加一个值,仍然放在ecx中,增加可以为负可以为正,这里理解就是改变金钱。
- 将改变后的金钱(不管是增加还是减少)放到金钱内存地址中
- 将改变后的金钱放到eax中



### AA脚本编写

回到之前的列表中,选择“显示反汇编”,跳到汇编界面,在工具中选中自动汇编



自动汇编中按红框中数字顺序先后选择



脚本中就会自动出现模板,将originalcode中的代码中的ecx改为0x3E80。之后选择分配到当前CT表。

之所以改ecx,上面已经分析了很多了,ecx是动态的金钱,扣除或增加了之后,再赋值到金钱内存中。

这里直接改为0x3E80(十进制16000),就等于,不管加钱还是减钱,都直接变为16000。



然后回到CE界面,你的脚本已经在下面的列表中了,红框位置选择激活。再回到游戏,可以乱买了,是不是不扣钱了。



## 金钟罩铁布衫实现

### CE查找生命基址

开一个新的搜索,先搜索100。然后折磨自己,用雷炸也行,跳楼也行。掉个血搜一次,掉个血搜一次。

最终可以得到7-8个这样的结果,而且会发现,不管怎么搜,都筛选不出来。

这时候就可以用点特殊的方法了。



之前金钱的详细信息中,金钱的内存信息是esi+1CC,一个偏移值。我们通过图,可以知道esi是05414008,金钱是通过这个值来偏移的。在之前的分享中,我有介绍过对象的概念,也就是相同的数据,会存放在相近的内存位置。所以我们可以大胆猜测,真正的生命值位置,也在05414008附近。

PS:这个0541是我本地的,你们的不一定一样,是动态的。但是都可以根据金钱旁边的位置找。



回到CE看一看,离金钱最近的地址果然有一个054145BC。(你们那的地址应该不一样)

双击这个地址,把他添加到下面的列表中,也可以修改描述。



选择最靠近金钱那个地址,右键“是什么访问了这个地址”

这里选择访问的原因,是因为CS游戏中,你掉血死亡都是即时的,也就是说,他一直有个线程在循环访问生命值,如果为0,就是死亡了。

当然你要搜改写也行,这样就每一次掉血,会改写一次,你就会先找到改生命值的位置。然后需要往上推导,当然如果运气好的话,直接就可以把扣血改为0。(这里我就是先尝试的改写,但是逻辑不太一样,当然最终还是可以找到正确的位置,但是太曲折,你们也可以锻炼一下自己)

PS:下图的金钱动态地址,是我打错名字了,很后面才发现,懒得改了,大家注意看数值哈。金钱我是没添加到下面列表的,下面列表的全是生命相关。



发现只有一个访问,就是一个对比的命令,我们同样双击,查看详细信息



这里的esi仍然是05414008,生命值也是由esi+5B4得来,所以我们可以大概得知esi对应的地址就是玩家信息的首地址。然后这里在使用eax和生命值比较,eax=0x64=100,意思暂时猜不到啥意思,用生命比较生命,暂时不知道啥意思,不如我们就动一下。



在CE中,将生命的值改为90,发现立刻又变回了100,这样一来,eax的意思就更加明确了,上面的eax应该是准确的生命值,用ESI+5B4和eax比较,如果不一致,则以eax为准。

可以简单理解为,cmp作为比较指令,肯定要有一个标准嘛,比如说和0比,和1比,这里就是和eax比。为啥是和eax比,因为我们修改了ESI+5B4的值,如果是以他为准,生命值直接就会变成90,但是变回了100,说明以eax为准。

那接下来我们就需要分析eax是从哪里赋值的,在之前查看访问列表中选择“查看反汇编”,进入汇编界面



可以发现cmp上面一行就是一个方法(如果不懂汇编,先去看下我之前其他的教程),这个方法里面对eax赋值的可能性很大。所以在上面方法处按下F5打断点,并按F7进入方法。

一路按F8步进,同时观察eax的值,最终发现,在一句指令执行完之后,eax的赋值变为了生命值。

发现这里的赋值是ebp-0C,而ebp这个寄存器一般是作为通用的,不作为数据存储使用,所以大概率代表这个方法是一个公共的方法,而不是专门的方法,往上看,会发现有几个fldce,fistp,fldcw,这种的汇编指令。具体啥意思大家都不用去了解,简单理解就是对浮点型数据的操作,也就是带小数点的数进行操作的,但是他也是通过进栈出栈的方式进行操作。

所以在方法前面,一定会有对需要操作的数进行的赋值,也就是用相同的fld等语句,将数字放到栈里,由公共方法统一读取操作。所以我们跳出这个方法,往方法前面查看一下。



方法前面两句:

esi是人物对象的动态地址

- edi赋值为esi+04的值
- 将edi+160的值压到浮点数计算的栈里

感觉应该就是这里了,也就是ESI+04存放的内存地址,里面的地址再偏移160,得到的地址,才是真实的生命内存地址。



选择内存窗口,ctrl+G,输入对象基址+4,我的是05414008+4你们的看之前金钱那的ESI。

确定之后,记录左下角红框里的值,逆向记录内存中的值06EC1BFC,为啥逆向记录我之前教程有说。



刚才我们拿到了ESI+4中的内存地址,接下来还需要把这个地址偏移160。

在CE中选择手动添加地址,输入刚才查到的值06EC1BFC+160。点确定,发现是乱七八糟的值。

是不是忘记了,这个是浮点数,将类型改为float之后,数值变为了100。



将刚才添加的地址的值给改为90,然后发现CE中,所有的生命记录都是90了,而且游戏中的血量也变为了90。

说明我们这才算是找到了真正的生命值地址。



### 玩家对象动态指针构造

右键在生命值真实地址上,选择“什么访问了这个地址”,发现有一个mov eax,,按之前的方法,查看一下详细信息,发现ebx中的值就是对象的基址。就在这里做指针把。选择mov那一条,显示反汇编。

PS:不选择其他的fld是因为,fld是放到float栈里,公用的概率很大,mov公用的概率小一些。如果公用,就可能导致对象基址一直会变,因为玩家数量很多,他循环调用,就会导致无敌失效,会一人无敌一小会。



还是按照之前的方法,创建AA脚本。

具体啥意思不多解释了,就是自己构建了一个动态指针,详细解释在植物大战僵尸第一篇。

```assembly

alloc(newmem,128)
registersymbol(pointer)
alloc(pointer,4)
label(returnhere)
label(originalcode)
label(exit)

newmem:

originalcode:
mov ,ebx
mov eax,

exit:
jmp returnhere

"mp.dll"+65101:
jmp newmem
nop
returnhere:



dealloc(newmem)
dealloc(pointer)
unregistersymbol(pointer)
"mp.dll"+9AF86:
mov edi,
fld dword ptr
//Alt: db 8B 7E 04 D9 87 60 01 00 00
```

创建完成后,打开脚本,我们就可以添加生命值基址了,按照刚才那样添加偏移。

金钱基址pointer+1CC就行



### CE查找扣除生命逻辑

对刚才添加的生命基址右键,“找出是什么改写了地址”,然后选择指针改写的地址。这里改写的原因,是找到扣除生命值的地方,直接把赋值修改,和前面不同的原因是,访问里面东西太多了,不好定位。



回到游戏,自残一下,发现多出了一条记录。



### AA脚本编写

选择这条记录,显示反汇编,之后直接在选中位置创建AA脚本

启动脚本后,再去自残试试,发现已经不掉血了。但是这又会出现一个问题,如果是通过这种公共的方法赋值,那多个敌人或者队友,都会无敌,这是我们不希望的,添加个敌人试试。

```assembly

//code from here to '' will be used to enable the cheat
alloc(newmem,128)
label(returnhere)
label(originalcode)
label(exit)

newmem:

originalcode:
//fstp dword ptr 这是原来的代码,直接注释让他不生效
mov ,0x42C80000               //把生命值改为100,后面这一串是100的浮点数值显示

exit:
jmp returnhere

"mp.dll"+66F05:
jmp newmem
nop
returnhere:


//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"mp.dll"+66F05:
fstp dword ptr
//Alt: db D9 98 60 01 00 00
```

果不其然,我和电脑互相打得满地鲜血,结果神仙打架,都伤不了对方分毫。于是我们看一下刚才生命基址的改写内容的列表,双击,查看一下详细信息。

在ESI位置,果然还是看到了熟悉的东西,这不就是玩家对象的基址么,那如果我们拿之前我们有默认存储的pointer和这里的ESI进行对比,是不是就可以区分开了呢?

PS:这里我是有尝试,敌人在打我和我打他,都会触发这个方法,但是ESI不同



修改上面的脚本内容

```

//code from here to '' will be used to enable the cheat
alloc(newmem,128)
label(returnhere)
label(originalcode)
label(exit)

newmem:
fstp dword ptr     //正常扣血逻辑
cmp ,ESI                //比较对象基址和当前玩家基址
jne exit                         //如果不是玩家的话,就不无敌。是玩家,就把血量改回来。
mov ,0x42C80000   //把生命值改为100,后面这一串是100的浮点数值显示
originalcode:

exit:
jmp returnhere

"mp.dll"+66F05:
jmp newmem
nop
returnhere:


//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"mp.dll"+66F05:
fstp dword ptr
//Alt: db D9 98 60 01 00 00
```

完事,添加一群一群的电脑,杀戮,大刀向敌人头上砍就行了。

# 结尾

CS的修改比起植物大战僵尸就要稍微复杂一些,不过还是那些套路,先找到内存中正确的存放地址,然后通过地址找到逻辑,分析逻辑,构造指针,然后完成脚本。建议看不懂的兄弟们结合之前的文章知识一起观看,有啥问题欢迎提出来一起讨论,但是请描述清楚和带有基本的尊重哦,多谢各位的支持。

丸子de爸爸 发表于 2019-11-16 22:39

潇潇暮雨寒 发表于 2019-11-16 20:18
把血调的多,目的不就是防止血量为零的时候死掉吗,建议楼主把这段代码找出来,然后修改成血量为零也不死, ...

{:1_907:}兄弟,我没有把血调多。那个0x42C80000只是汇编中浮点数的100而已....
{:1_924:}建议你可以看仔细一点,我做的就是在他扣血的时候把血改为了满血,所以本来就一直不会死。
想要检查血量为0不死也可以,但是这种即时战略游戏,他通过一次次的观察者刷新世界来打到检测判断,如果你要去查询,一是工作量太大,第二我怕写出来,真的没人看了,那会太多....谢谢关注,但请也先认真看完,也是对我们作者的尊重。{:1_893:}

kai2510 发表于 2019-11-16 22:20

九条可怜 发表于 2019-11-16 20:47
都是回忆啊,跟同学打cs那个时代都过去了呀

现在还有不少玩的~上个学年上电脑课 我们班有一半都在玩。。在电脑教室的局域网里玩得不亦乐乎

听歌能减肥 发表于 2019-11-15 21:03

这游戏暴露了楼主的年龄:Dweeqw

丸子de爸爸 发表于 2019-11-21 20:13

ID0617 发表于 2019-11-21 19:44
楼主我按你教程操作成功了,可是想自己做个挂机吧勇士的ct 只能找到钱币的地址,到找模块初始基址就是找不 ...

{:1_893:}谢回复,找不到基址就自己做一个动态指针把。
也挺简单的,我一般都是直接动态指针。
如果还是想找基址,我之前的植物大战僵尸一里面,有思路流程图,可以去看看
希望对你有帮助

shui3322 发表于 2019-11-15 21:01

不错。得学习一下CE。

18748611145 发表于 2019-11-15 21:02

感谢分享

wsrfde 发表于 2019-11-15 21:15

收藏了,好贴

委员长_ 发表于 2019-11-15 21:17

感谢分享,这游戏用来学fps辅助还是不错的

tsts022 发表于 2019-11-15 21:36

曾经的经典游戏 不知道现在还能不能联网玩

菠菜汤 发表于 2019-11-15 21:49

说的太详细了

wangbingjun 发表于 2019-11-15 21:50

不错有学习了

刘样andholiday 发表于 2019-11-15 21:51

很详细相反可能小白根本不领情
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: CS1.6修改器DIY(一)无敌和无限金钱