好友
阅读权限10
听众
最后登录1970-1-1
|
红色警戒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/ |
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|