吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 14648|回复: 45
收起左侧

[原创] 红色警戒2-逆向分析---士兵铁幕的实现

  [复制链接]
zhaihs 发表于 2019-9-29 19:02
红色警戒2-逆向分析---士兵铁幕的实现
红色警戒2的逆向分析文章不少,研究了如科技全开,单位三星,快速建造,无限超武等等
个人虽然有这方面的经验和修改器作品,但是毕竟别人已经写过,不再讨论。
红色警戒2中,士兵是不能加铁幕的,加铁幕士兵就会死亡。我在逆向分析红警过程中,实现了士兵铁幕修改,就把这个作为进入我爱破解的第一帖吧

为了实现士兵铁幕,我们首先要找到各个单位基地址,红警2中具体单位基地址搜索的问题,论坛中其他人已经说过怎么查找,不再详说
我逆向分析时,一般会设想如果我来设计程序,会采用什么方法来存储数据。
从设计程序思路来说,用鼠标选中一个单位,那么肯定会把这个单位的基地址存储到一个位置,来标记这个单位被选中。
先开一局,把对手打到剩一口气。好了,我们可以专心研究了。

开cheatengine,选中红警2的game.exe,来回点鼠标更换选中单位,很快找到第一个选中单位基地址指针 记录的 位置06CF7040,它是一个动态数据,需要不断找到它上一级的指针,直到找到一个最上级的静态地址,然后把它一层层记录下来。
很幸运,这个指针只有一层,00A40C64 这个静态地址里存储着06CF7040。
我们知道红警2允许选中多个单位,而且选中多个单位后,如果多于255人,多余的人不能正常调动。所以我猜想,这个选中单位列表会存储在一个连续的区域里,而且有一个数值记录列表中有多少单位,这个数值可能是一个字节。
顺着这个思路,继续用cheateengine搜索发现,选中多个单位、士兵、建筑时,对应的基地址会加入这个06CF7040后面的位置。而选中了多少个单位士兵建筑,数字会计入00A40C70。
所以,选中第一个单位基地址的指针为  [game.exe+640C64],偏移0,选中第2个单位挨着第一个单位指针,偏移4。
这个基地址列表在后面会用到。所以在cheatengine里登记一下对应指针。下面找到的各个数据也都用指针的形式记录下来。

现在选中一个单位,根据[game.exe+640C64] 指向位置,找到我选中的这个单位的基地址在内存区域0E071448

从设计程序思路来说,单位基地址是单位基础数值存储的起始位置,单位自身的基础数据(生命值,所属方,火力,装甲),应该存储在单位基地址后面那个数据区里。
用自己的几个单位互殴,很快找到生命值的偏移位置。捡几个箱子,依次找到火力,装甲,等级……的位置,这个在其他弟兄的帖子里已经有过,不再详说。
为了方便使用铁幕,通过超武时间查找,通过代码开启了超武无限。这个在其他弟兄帖子也有,不再详说。

另外单位基础属性里,肯定还要包含单位自身的X,Y,Z坐标,这个通过来回移动单位,也可以搜索到。从单位基地址计算,偏移地址是88,80,91。
由于尤里的存在,红警2单位有所属方,控制方的区别,这个属性应该也在单位地址数据区里。通过选择敌方单位,己方单位的变化对比,找到所属方数据地址0E0715FC,偏移地址1B4
由于我计划让选中单位就能加铁幕,肯定不想让敌方加,所以下面加铁幕时,会先检查单位所属方,本方才加铁幕。

现在开始设想铁幕的问题,我们知道铁幕生效的时候,那段代码肯定要访问了单位基地址。
由于我已经把电脑打废了,他们不可能使用铁幕,现在能够访问铁幕代码的都会受到我的操作影响。

由于铁幕到一定时间会失效,那么登记哪些单位有铁幕,铁幕多长时间,应该有个数据存储区。
设想如果我来设计程序,一个办法是把铁幕生效时间写到单位基础数值里,也就是单位基地址对应区域里。
对一个单位使用铁幕,然后用cheatengine 对单位基地址对应的4K内存区域内搜索有关变化的值。一开始我是按照铁幕时间来查找的,实验证明不行,数字不是规律的。
然后我设想铁幕生效后是一个变化的值,而失效后估计是0.按这个思路找到一个地址0E0715B4,在单位基地址后偏移16C的位置。然后直接修改这个地址为非0数值,发现铁幕效果没有出现。
因此推测这个地址只是一个记录在单位属性里的“时间”。应该有另一个铁幕单位列表在起效果。

右键,找出访问0E0715B4 的地址,然后在游戏里对单位施加铁幕。于是找到了一个过程

006D86B0 - a1 2c 0d a4 00             - mov eax,[00a40d2c] : 00000000
006D86B5 - 83 ec 0c                   - sub esp,0c
006D86B8 - 8b 54 24 10                - mov edx,[esp+10]
006D86BC - c7 81 6c 01 00 00 00 00 00 00 - mov [ecx+0000016c],00000000
006D86C6 - 56                         - push esi
006D86C7 - 8d b1 54 01 00 00          - lea esi,[ecx+00000154]
006D86CD - 89 81 54 01 00 00          - mov [ecx+00000154],eax
006D86D3 - 8b 44 24 08                - mov eax,[esp+08]
006D86D7 - 89 46 04                   - mov [esi+04],eax
006D86DA - 89 56 08                   - mov [esi+08],edx
006D86DD - 5e                         - pop esi
006D86DE - 83 c4 0c                   - add esp,0c
006D86E1 - c2 04 00                   - ret 0004

跟踪这个过程,找到了这个过程上一级的调用
004CD49E - 51                         - push ecx
004CD49F - 8b ce                      - mov ecx,esi
004CD4A1 - e8 0a b2 20 00             - call 006d86b0

发现这个过程调用很简单,esi就是单位的基地址,调用006d86b0前把ecx压到堆栈,esi的值赋给ecx,调用就行。
如果继续向上分析,可以找到上一级的铁幕过程,在上一级铁幕过程中,对单位的属性(士兵,载具,建筑)进行了识别,从而实现不同的效果。我们想让士兵也能加铁幕,这里就不追查上一级的代码了。

试试吧
右键,找出改写[00A40C70]的地址(记录选中单位数),目的是找到选中单位时,程序执行的那段代码

005D3032 - 89 0D 700CA400        - mov [game.exe+640C70],ecx

为了能够访问所有选中单位,我需要找到它的上一级调用过程
这段过程的的上一级调用来自
006C91E7  call 005D2E70

用cheatengine 的内存浏览器,找到这一行,工具,自动汇编,模版,框架代码,代码注入,文件,保存到CT表。
这段代码用其他工具也可以注入,需要适当修改。在这里我只是为了自己修改测试方便。

脚本内容是这样的:

[ENABLE]
alloc(newmem,2048) //分配内存
label(returnhere)  
label(originalcode)
label(exit) //定义3个跳转标签

006C91E7:
jmp newmem
returnhere:

newmem:
PUSH EAX           //保存EAX入栈
MOV EAX,[00A35DB4]  // 读取玩家所属方ID
CMP [ESI+1B4],EAX   //对比当前选中单位是否玩家所属方
//MOV EAX,[ESI+1B4]
POP EAX            //恢复EAX,避免破坏系统原有环境
JNE  originalcode  //如果当前选中单位不是玩家的,就执行原命令
MOV [ESI+11C],40000000    //如果是玩家的单位,升级为三星,这里的ESI就是当前选中那个单位的基地址。
mov [esi+00000124],40000000  //护甲升级
mov [esi+0000012c],40000000  //火力升级
//mov byte ptr [esi+0000032a],01  //隐形
pushad  //保存系统寄存器,调用上面我们找到的给单个单位加铁幕的代码     
push ecx     
mov ecx,esi
call 006d86b0
popad //恢复系统寄存器

originalcode:
call 005d2e70  //继续执行原代码

exit:
jmp returnhere


[DISABLE]  //停用脚本恢复原程序
//code from here till the end of the code will be used to disable the cheat
DEalloc(newmem)
006C91E7:
call 005d2e70

保存脚本,然后启用后,就可以看到选中的单位都加了铁幕,包括步兵。

再进一步修改,还可以找到系统初始化时的代码,让玩家的单位一出生就铁幕升级。
脚本测试修改成功后,就可以像KAQQI 发的修改过程那样,实现修改器,或者直接保存到程序代码里了。

https://www.bilibili.com/video/av68399233/

免费评分

参与人数 20威望 +1 吾爱币 +22 热心值 +19 收起 理由
jjfflash + 1 + 1 我很赞同!
知止 + 1 我很赞同!
森林游狼 + 1 我很赞同!
Hmily + 1 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
你比我非 + 1 热心回复!
majia4075669072 + 1 我很赞同!
红米大魔王 + 1 + 1 对我有帮助
初晨曦流辉 + 1 谢谢@Thanks!
多幸运遇见baby + 1 + 1 用心讨论,共获提升!
385290864 + 1 + 1 用心讨论,共获提升!
sniper9527 + 1 + 1 谢谢@Thanks!
LOLQAQ + 1 + 1 我很赞同!
SYWZWL + 1 + 1 我很赞同!
炒年糕的大叔 + 1 + 1 谢谢@Thanks!
rsnyx + 1 用心讨论,共获提升!
haisenshi + 1 + 1 热心回复!
bugof52pj + 1 + 1 谢谢@Thanks!
weiwei321 + 1 + 1 我很赞同!
thepassion + 1 + 1 热心回复!
\CPU\ + 2 + 1 用心讨论,共获提升!

查看全部评分

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

\CPU\ 发表于 2019-9-30 10:48
一键获胜能做到吗
 楼主| zhaihs 发表于 2020-7-22 12:04
c66d88 发表于 2020-5-30 10:29
JNE  originalcode  //如果当前选中单位不是玩家的,就执行原命令     能请教一下这一句为什么是判断选中单 ...

在单位属性里有单位所属方代码。
在系统变量里有玩家所属方代码。
比较这两个代码,判断当前单位是否属于玩家。
 楼主| zhaihs 发表于 2019-9-29 19:45
lindusy 发表于 2019-9-30 10:24
虽然看不懂,但是得回贴。
CZ77 发表于 2019-9-30 10:34
核弹爆炸闪电风暴范围能修改吗
shaunkelly 发表于 2019-9-30 10:49
最好弄几个图片直观点吧,这样排版看着累啊
shaokui123 发表于 2019-9-30 11:59
联网对战可以吗
airborne 发表于 2019-9-30 12:33
虽然看不懂,但还是谢谢分享!
YYZR 发表于 2019-9-30 15:32
支持支持
索伦艾克 发表于 2019-9-30 16:54
纯粹技术贴,达人养成系列
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-12-24 10:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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