地图全开
00481F9D |> \0FBF56 26 movsx edx, word ptr [esi+26]
00481FA1 |. 0FBF46 24 movsx eax, word ptr [esi+24]
00481FA5 |. 52 push edx
00481FA6 |. 50 push eax
00481FA7 |. 68 10D08100 push 0081D010 ; ASCII "Crate at %d,%d contains 'reveal'",LF
00481FAC |. E8 2F49F8FF call 004068E0 ; 空函数
00481FB1 |. 8B4D 08 mov ecx, dword ptr [ebp+8]
00481FB4 |. 83C4 0C add esp, 0C
00481FB7 |. 8B91 1C020000 mov edx, dword ptr [ecx+21C]
00481FBD |. B9 E8F78700 mov ecx, 0087F7E8
00481FC2 |. 52 push edx
00481FC3 |. E8 C85D0F00 call 00577D90 ; 地图全开
2024年1月3日:已验证可行性。
// 全地图内联代码
void Map_Assemble() {
_asm {
pushad
mov eax,0x00A83D4C
mov edx,[eax]
mov ecx,0x0087F7E8
push edx
mov eax,0x00577D90
call eax
popad
}
}
雷达开启
以下汇编仅作过程分析的参考:
00508DF0 /$ C681 79570000>mov byte ptr [ecx+5779], 0
00508DF7 |. A1 4C3DA800 mov eax, dword ptr [A83D4C]
00508DFC |. 83EC 0C sub esp, 0C
00508DFF |. 3BC8 cmp ecx, eax
00508E01 |. 0F85 4D010000 jnz 00508F54
00508E07 |. 8B81 B8020000 mov eax, dword ptr [ecx+2B8]
00508E0D |. 53 push ebx
00508E0E |. 55 push ebp
00508E0F |. 56 push esi
00508E10 |. 8BB1 B0020000 mov esi, dword ptr [ecx+2B0]
00508E16 |. 57 push edi
00508E17 |. 83FE FF cmp esi, -1
00508E1A |. C64424 10 00 mov byte ptr [esp+10], 0
00508E1F |. 74 0E je short 00508E2F
00508E21 |. 8B15 84EDA800 mov edx, dword ptr [A8ED84]
00508E27 |. 2BD6 sub edx, esi
00508E29 |. 3BD0 cmp edx, eax
00508E2B |. 7D 0A jge short 00508E37
00508E2D |. 2BC2 sub eax, edx
00508E2F |> 85C0 test eax, eax
00508E31 |. 0F85 F8000000 jnz 00508F2F
00508E37 |> A1 30B2A800 mov eax, dword ptr [A8B230]
00508E3C |. 8A90 A4340000 mov dl, byte ptr [eax+34A4]
00508E42 |. 84D2 test dl, dl ; 雷达开启判断
00508E44 |. 0F85 E0000000 jnz 00508F2A
2024年1月4日:已验证可行性,一键开启全图和雷达,无须修改指令。
//全地图内联代码
#pragma pack(1)
void Map_Assemble() {
_asm {
pushad
mov eax, 0x00A83D4C
mov edx, [eax]
mov ecx, 0x0087F7E8
push edx
mov eax,0x00577D90
call eax
popad
}
}
// 雷达全开 [[0x00A8B230] + 0x34A4] = 1
void RadarOn_Assemble() {
_asm {
pushad
mov eax, 0x00A8B230
mov eax, [eax]
mov byte ptr [eax + 0x34A4], 0x1
popad
}
}
// 判断游戏是否运行
bool isGameRunning() {
bool isRunning = false;
__try {
_asm {
pushad
mov eax, 0x00A83D4C
mov eax, [eax]
mov eax, 0x0087F7E8
mov eax, [eax]
popad
}
isRunning = true;
} __except (EXCEPTION_EXECUTE_HANDLER) {
isRunning = false;
}
return isRunning;
}
#pragma pack()
调用:
//地图全开
void openAllMap() {
if (isGameRunning()) {
Map_Assemble();
RadarOn_Assemble();
} else {
::Beep(523, 400); // do
}
}
其他:
- 对 00577D90 函数下断点,创建雷达后断下来跟踪。
- 找到地址: 0x00A83D4C 0x0087F7E8 0x00A8B230 0x34A4 之间的关系和来源,最好能从一个地址出发找到其他地址。
无限信标
联网对战的时候最多只能放置三个信标,当超过三个时需要把多余的删除掉才能放置新的信标,这样就会造成一个麻烦:战况激烈的时候,想放置信标的时候放置不了,还需要在地图上删除一个信标才能继续放置。
解决思路:RA2YurisRevengeTrainer/issues/19
如意箱子
参考:
分析思路:
OD导入,分析字符串,相关联的字符串释义如下:
veterancy # 老兵 veteran # 老兵 base healing # 加血
找到如下的信息:
00481EA3 push 0081D058 crate at %d,%d contains tiberium\n 00481F77 push 0081D034 crate at %d,%d contains 'shroud'\n 00481FA7 push 0081D010 crate at %d,%d contains 'reveal'\n 0048204B push 0081CFF0 crate at %d,%d contains a unit\n 0048246F push 0081CFD0 crate at %d,%d contains money\n 0048256F push 0081CFAC crate at %d,%d contains explosives\n 00482728 push 0081CF8C crate at %d,%d contains napalm\n 0048284A push 0081CF60 crate at %d,%d contains cloaking device\n 0048297C push 0081CF38 crate at %d,%d contains veterancy(tm)\n 00482B99 push 0081CF10 crate at %d,%d contains base healing\n 00482CAB push 0081CEF0 crate at %d,%d contains icbm\n 00482D60 push 0081CED0 crate at %d,%d contains armor\n 00482EB6 mov ecx, 0081CEB8 eva_unitarmorupgraded 00482F40 push 0081CE98 crate at %d,%d contains speed\n 004830A5 mov ecx, 0081CE80 eva_unitspeedupgraded 0048312F push 0081CE5C crate at %d,%d contains firepower\n
以
veterancy
为例,定位到相关汇编代码:00482972 |> \0FBF46 26 movsx eax, word ptr [esi+26] 00482976 |. 0FBF4E 24 movsx ecx, word ptr [esi+24] 0048297A |. 50 push eax 0048297B |. 51 push ecx 0048297C |. 68 38CF8100 push 0081CF38 ; crate at %d,%d contains veterancy(tm)\n 00482981 |. E8 5A3FF8FF call 004068E0
00482972
表明这个从其他地方跳转过来的,找到跳转源头:00481DE0 |. FF2495 C43348>jmp dword ptr [edx*4+4833C4]
分析地址
4833C4
,是一个跳转表:004833C4 00482463 ; crate at %d,%d contains money\n 004833C8 00482041 ; crate at %d,%d contains a unit\n 004833CC 00482B8F ; crate at %d,%d contains base healing\n 004833D0 00482840 ; crate at %d,%d contains cloaking device\n 004833D4 00482565 ; crate at %d,%d contains explosives\n 004833D8 0048271E ; crate at %d,%d contains napalm\n 004833DC 004832F5 ; ??? 004833E0 00481F6D ; crate at %d,%d contains 'shroud'\n 004833E4 00481F9D ; crate at %d,%d contains 'reveal'\n 004833E8 00482D56 ; crate at %d,%d contains armor\n 004833EC 00482F36 ; crate at %d,%d contains speed\n 004833F0 00483125 ; crate at %d,%d contains firepower\n 004833F4 00482CA1 ; crate at %d,%d contains icbm\n 004833F8 004832F5 ; ??? 004833FC 00482972 ; crate at %d,%d contains veterancy(tm)\n 00483400 004832F5 ; ??? 00483404 00481DE7 ; crate at %d,%d contains poison gas\n 00483408 00481E99 ; crate at %d,%d contains tiberium\n 0048340C 90909090 ; nop
一共有
0x12
个地址((0048340C - 004833C4) / 4
),逐一在反汇编窗口中跟随查看地址,并对应一下功能。
实现思路:
对地址
4833C4
起始的0x12
个四字节内容统一修改为想要的功能地址表。例如想要金钱效果,当按下热键时全部修改为0x00482463
,然后再去捡箱子,则无论是什么箱子都会执行的是捡到金钱的效果。类推,可以设计一个主要的热键功能:
金钱 00482463 加血 00482B8F 经验 00482972 防御 00482D56 火力 00483125 速度 00482F36
实现代码:
// 修改所有捡箱子效果:金钱
void SetBoxAllMoney() {
const LPVOID MethodTableAddr = (LPVOID)0x004833C4;
const size_t MethodTableCount = 0x12;
const SIZE_T MethodTableSize = MethodTableCount * sizeof(DWORD);
const DWORD JumpToAddr = 0x00482463; // 捡到的是金钱的跳转地址
// 修改代码保护属性
DWORD dwOldProtect = 0;
if (VirtualProtect(MethodTableAddr, MethodTableSize, PAGE_EXECUTE_READWRITE, &dwOldProtect) == S_OK) {
DWORD* p = (DWORD*)MethodTableAddr;
for (size_t i = 0; i < MethodTableCount; i++) {
*(p + i) = JumpToAddr;
}
// 恢复代码保护属性
if (!VirtualProtect(MethodTableAddr, MethodTableSize, dwOldProtect, &dwOldProtect)) {
OutputDebugString("Failed 2!");
}
} else {
OutputDebugString("Failed 1!");
}
}
验证效果:
单机玩有效果,但是联网对战不行,会卡,可能是触发了什么机制。
如何使用
编译项目 Ra2Tool ,使用任意注入工具把 Ra2Dll.dll
模块注入到游戏进程即可(RATrainer 用不到)。
如果使用HookLoader工具,可以参考如下使用步骤:
【使用说明】 1、运行exe 2、进入游戏之后按下快捷键【ALT + H】即可,一定要进入游戏,保险起见是在出现基地之后,其他场景没测试过。
【作者有话】 全图功能我认为对级别低的玩家比较有帮助,对级别高的玩家帮助没有那么大。其他影响游戏平衡的变态功能全部删除了,只保留了全图这个功能,不然就没有可玩性了。
参考
文档信息
- 本文作者:zhupite
- 本文链接:https://zhupite.com/sec/red-alert2.html
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)