War3 局域网开局地图校验机制分析

为了保证局域网内每个玩家的地图一致,War3在游戏开局前会同步、校验玩家的本地地图。

一、查找本地是否有匹配的地图

通过枚举游戏相关目录查找一样名字的地图文件,代码片段如下:

00C9785B  |.  0F1045 14     movups xmm0,dqword ptr ss:[ebp+0x14]
00C9785F  |.  57            push edi
00C97860  |.  FF75 38       push [arg.13]
00C97863  |.  8B75 08       mov esi,[arg.1]
00C97866  |.  8B7D 2C       mov edi,[arg.10]
00C97869  |.  8B5D 30       mov ebx,[arg.11]
00C9786C  |.  8945 F8       mov [local.2],eax
00C9786F  |.  8B45 34       mov eax,[arg.12]
00C97872  |.  50            push eax                                                      ;  OUT FullMapFilePath
00C97873  |.  51            push ecx                                                      ;  计算SHA-1回调函数
00C97874  |.  8D45 D4       lea eax,[local.11]
00C97877  |.  50            push eax                                                      ;  OUT SHA-1
00C97878  |.  52            push edx                                                      ;  计算Hash回调函数
00C97879  |.  8D45 CC       lea eax,[local.13]
00C9787C  |.  50            push eax                                                      ;  OUT MapHash
00C9787D  |.  8D45 C4       lea eax,[local.15]
00C97880  |.  50            push eax                                                      ;  OUT UnkonwBuffer
00C97881  |.  8D45 C8       lea eax,[local.14]
00C97884  |.  50            push eax                                                      ;  OUT MapFileSize
00C97885  |.  8D45 D0       lea eax,[local.12]
00C97888  |.  50            push eax                                                      ;  OUT MapName
00C97889  |.  56            push esi                                                      ;  IN MapFilePath
00C9788A  |.  0F1145 E8     movups dqword ptr ss:[ebp-0x18],xmm0                          ;  服务器的地图SHA-1
00C9788E  |.  E8 DDFCFFFF   call Warcraft.00C97570
00C97893  |.  83C4 28       add esp,0x28                                                  ;  如果文件找到返回true
00C97896  |.  83F8 01       cmp eax,0x1
00C97899  |.  75 46         jnz short Warcraft.00C978E1
00C9789B  |.  8B45 CC       mov eax,[local.13]
00C9789E  |.  3B45 0C       cmp eax,[arg.2]                                               ;  比较hash是否相同
00C978A1  |.  75 3E         jnz short Warcraft.00C978E1
00C978A3  |.  8D4D D4       lea ecx,[local.11]
00C978A6  |.  BE 10000000   mov esi,0x10                                                  ;  SHA-1长度 16个字节
00C978AB  |.  8D55 E8       lea edx,[local.6]
00C978AE  |.  66:90         nop
00C978B0  |>  8B01          /mov eax,dword ptr ds:[ecx]                                   ;  比较SHA-1
00C978B2  |.  3B02          |cmp eax,dword ptr ds:[edx]                                   ;  服务器的地图SHA-1
00C978B4  |.  75 2B         |jnz short Warcraft.00C978E1
00C978B6  |.  83C1 04       |add ecx,0x4
00C978B9  |.  83C2 04       |add edx,0x4
00C978BC  |.  83EE 04       |sub esi,0x4
00C978BF  |.^ 73 EF         \jnb short Warcraft.00C978B0
00C978C1  |.  8B4D D0       mov ecx,[local.12]
00C978C4  |.  B8 01000000   mov eax,0x1
00C978C9  |.  890F          mov dword ptr ds:[edi],ecx                                    ;  MapName
00C978CB  |.  8B4D C8       mov ecx,[local.14]

函数原型:

bool __cdecl FindMapFile(IN char *szMapFilePath,
    			OUT char *szMapName,
			OUT int *pMapFileSize,
			OUT char *szUnkonwBuffer,
			OUT int *MapHash,
			OUT pvoid pCalcMapHash,
			OUT char *szSHA1,
			OUT pvoid pCalcMapSHA1,
			OUT char*szFullMapFilePath);

函数如果找到地图了,则返回true后面校验地图是否相同,如果相同则会执行下面的地图校验 ,否则会去执行下载地图操作。

二、校验地图是否为游戏局内地图 (这里的逻辑只有地图文件存在才会去做)

0087EAF6  |.  5B            pop ebx                                  ;  0251C320
0087EAF7  |.  8B4D FC       mov ecx,[local.1]
0087EAFA  |.  33CD          xor ecx,ebp
0087EAFC  |.  E8 D7805300   call Warcraft.00DB6BD8
0087EB01  |.  8BE5          mov esp,ebp
0087EB03  |.  5D            pop ebp                                  ;  0251C320
0087EB04  |.  C3            retn
0087EB05  |>  0FB643 30     movzx eax,byte ptr ds:[ebx+0x30]
0087EB09  |.  56            push esi
0087EB0A  |.  83E0 01       and eax,0x1
0087EB0D  |.  6A 00         push 0x0
0087EB0F  |.  50            push eax
0087EB10  |.  E8 4BFB0800   call Warcraft.0090E660
0087EB15  |.  83C4 08       add esp,0x8
0087EB18  |.  F783 48010000>test dword ptr ds:[ebx+0x148],0x200
0087EB22  |.  0F85 CC000000 jnz Warcraft.0087EBF4
0087EB28  |.  68 04010000   push 0x104
0087EB2D  |.  8D85 F8FEFFFF lea eax,[local.66]
0087EB33  |.  50            push eax                                 ;  OutFullMapFilePath
0087EB34  |.  8D43 54       lea eax,dword ptr ds:[ebx+0x54]
0087EB37  |.  50            push eax                                 ;  MapPath
0087EB38  |.  E8 03C92700   call Warcraft.00AFB440
0087EB3D  |.  83C4 0C       add esp,0xC
0087EB40  |.  8D43 40       lea eax,dword ptr ds:[ebx+0x40]
0087EB43  |.  8BCF          mov ecx,edi
0087EB45  |.  50            push eax                                 ;  SHA-1
0087EB46  |.  FF73 3C       push dword ptr ds:[ebx+0x3C]             ;  Map Hash
0087EB49  |.  8B83 48010000 mov eax,dword ptr ds:[ebx+0x148]
0087EB4F  |.  25 FF030000   and eax,0x3FF
0087EB54  |.  50            push eax                                 ;  1
0087EB55  |.  8D85 F8FEFFFF lea eax,[local.66]
0087EB5B  |.  50            push eax                                 ;  MapFilePath
0087EB5C  |.  E8 9FABF5FF   call Warcraft.007D9700                   ;  CheckMap
0087EB61  |.  85C0          test eax,eax
0087EB63  |.  74 23         je short Warcraft.0087EB88
0087EB65  |.  53            push ebx
0087EB66  |.  8D4F 38       lea ecx,dword ptr ds:[edi+0x38]
0087EB69  |.  E8 02A2F4FF   call Warcraft.007C8D70
0087EB6E  |.  8B77 30       mov esi,dword ptr ds:[edi+0x30]
0087EB71  |.  8B83 44010000 mov eax,dword ptr ds:[ebx+0x144]
0087EB77  |.  8947 48       mov dword ptr ds:[edi+0x48],eax
0087EB7A  |.  85F6          test esi,esi
0087EB7C  |.  75 1D         jnz short Warcraft.0087EB9B
0087EB7E  |.  6A 57         push 0x57

这里的CheckMap就是校验本地的地图是否与加入局使用的地图一致

bool WINAPI CheckMap(char *szMapFilePath,int nMode,DWORD dwMapHash,char *szSHA1);

这个函数执行可以被忽略,如果参数中 dwMapHash = 0xFFFFFFFF, szSHA1 = NULL,则直接返回true

PS1.以上代码片段来自于 War3 129版本

PS2.只要过掉这2个地图校验,就可以加载修改版的地图,然而有几率会产生不匹配的错误

你可能感兴趣的:(那些年我们玩过的网游,逆向分析)