魔兽争霸3的显示魔法的实现原理和源代码
汇编源码:
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 显示魔法
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 需要注入到WAR3中执行的代码
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
REMOTE_CODE_START equ this byte
_lpLoadLibrary dd ? ;导入函数地址表
_lpGetProcAddress dd ?
_lpGetModuleHandle dd ?
_fconst1 dq 0.03
_fconst2 dq 0.004
_fconst3 dq 0.300
_fconst4 dq 72.0
_fconst5 dq 0.00050
_fconst6 dq 0.00600
_lpMessageBox dd ?
_lpVirtualProtect dd ?
_lpStrom401 dd ?
_lpHook1 dd ?
_lpHook2 dd ?
_lpFunc1 dd ?
_lpFunc2 dd ?
_lpFunc3 dd ?
_lpFunc4 dd ?
_lpFunc5 dd ?
_lpFunc6 dd ?
_lpFunc7 dd ?
_lpFunc8 dd ?
_lpFunc9 dd ?
_lpReturnHook1 dd ?
_lpFuncUnknow dd ?
_szTip1 db 'hook1',0
_szTip2 db 'hook2',0
_szDllUser db 'user32.dll',0
_szDllKernel db 'Kernel32.dll',0
_szDllGame db 'game.dll',0
_szDllStorm db 'storm.dll',0
_szMessageBox db 'MessageBoxA',0,0
_szVirtualProtect db 'VirtualProtect',0,0
_szscale db 'scaleFactor',0
_strom401return dd ?
_nebx dd ?
_bGetFuncTab dd 0
_lpFuncTable db 128 dup(0),0
;------------------------------------------------
HOOK1_SUB:
call @F
@@:
pop ebx
sub ebx,offset @B
;--------------------------
push edi
push 0
push 0
push 0
mov ecx,esi
call [ebx+_lpFunc5]
fld qword ptr [ebx+_fconst1]
push 0
fstp dword ptr [esi+58h]
xor edx,edx
mov ecx,esi
mov edi,dword ptr [ebx+_lpFunc4]
call edi
fld qword ptr [ebx+_fconst2]
push 0
fstp dword ptr [esi+5ch]
xor edx,edx
mov ecx,esi
mov edi,dword ptr [ebx+_lpFunc4]
call edi
fld qword ptr[ebx+_fconst3]
push 1
sub esp,8
fst dword ptr[esp+4]
xor edx,edx
fstp dword ptr[esp]
push 1
mov ecx,esi
mov edi,dword ptr [ebx+_lpFunc3]
call edi
mov eax,dword ptr [esi]
mov eax,dword ptr [eax+64h]
pop edi
xor edx,edx
mov ecx,esi
jmp eax
HOOK1 equ this byte
call @F
@@:
pop edi
sub edi,offset @B
;--------------------------
mov [edi+_nebx],ebx
mov ebx,edi
pop eax
mov dword ptr [ebx+_lpReturnHook1],eax
pop eax
add eax,eax
push eax
call [ebx+_lpStrom401]
pushad
mov dword ptr[ebx+_strom401return],eax
add eax,158h
mov esi,eax
call HOOK1_SUB
popad
mov ecx,dword ptr [ebx+_lpReturnHook1]
mov ebx,[ebx+_nebx]
push ecx
retn
HOOK2_SUB3:
push ebx
call @F
@@:
pop ebx
sub ebx,offset @B
;--------------------------
mov eax,dword ptr [ebx+_lpFuncUnknow]
mov eax,dword ptr [eax+64h]
push esi
push edi
mov esi,edx
mov edi,ecx
call eax
mov eax,dword ptr [ebx+_lpFuncUnknow]
mov eax,dword ptr [eax+64h]
lea ecx,dword ptr [edi+158h]
pop edi
mov edx,esi
pop esi
pop ebx
jmp eax
HOOK2_SUB4:
push ebx
call @F
@@:
pop ebx
sub ebx,offset @B
;--------------------------
mov eax,dword ptr [ebx+_lpFuncUnknow]
mov eax,dword ptr [eax+68h]
pop ebx
jmp eax
HOOK2_SUB2:
mov [ebx+_lpFuncUnknow],ecx
xor eax,eax
.while eax<80h
mov dl,byte ptr [eax+ecx]
mov byte ptr [eax+_lpFuncTable+ebx],dl
inc eax
.endw
lea eax,dword ptr [ebx+_lpFuncTable]
add eax,64h
lea edi,[ebx+offset HOOK2_SUB3]
mov [eax],edi
lea eax,dword ptr [ebx+_lpFuncTable]
add eax,68h
lea edi,[ebx+offset HOOK2_SUB4]
mov [eax],edi
retn
HOOK2_SUB1:
sub esp,10h
mov edi,[ebx+_strom401return]
mov eax,dword ptr [edi+50h]
.if eax
mov edi,dword ptr [eax+0ch]
push esi
lea esi,dword ptr[edi+158h]
mov eax,[ebx+_bGetFuncTab]
.if !eax
mov ecx,dword ptr [edi]
push edi
call HOOK2_SUB2
pop edi
mov [ebx+_bGetFuncTab],1
.endif
push 0
lea eax,dword ptr [esp+8]
push eax
xor edx,edx
mov ecx,dword ptr[ebx+_strom401return]
push eax
;------------------------------
lea eax,[ebx+_lpFuncTable]
;mov edi,dword ptr [edi+0ch]
mov [edi],eax
pop eax
call [ebx+_lpFunc1]
fldz
fcomp dword ptr [esp+4]
wait
fstsw ax
.if !(ah & 1)
@@: pop esi
add esp,10h
retn
.endif
push 3
lea eax,[esp+8]
push eax
xor edx,edx
mov ecx,dword ptr[ebx+_strom401return]
call [ebx+_lpFunc1]
fldz
fcomp dword ptr [esp+4]
wait
fstsw ax
test ah,5
jpe @b
mov eax,[esi]
mov eax,[eax+74h]
push ebp
mov edi,dword ptr[ebx+_strom401return]
push edi
xor edx,edx
mov ecx,esi
call eax
mov edi,dword ptr [ebx+_lpFunc3]
mov ebp,dword ptr [ebx+_lpFunc4]
lea ecx,dword ptr [esp+14h]
push ecx
lea edx,[esp+10h]
mov ecx,dword ptr[ebx+_strom401return]
call [ebx+_lpFunc2]
mov ecx,dword ptr[ebx+_strom401return]
mov ecx,[ecx+30h]
mov eax,[ebx+_lpFunc6]
lea edx,[ebx+_szscale]
call eax
.if eax
fld dword ptr [eax+54h]
.else
fld1
.endif
fstp dword ptr [esp+8h]
push 0
fld dword ptr [esp+0ch]
xor edx,edx
fmul qword ptr [ebx+_fconst4]
mov ecx,esi
fmul qword ptr [ebx+_fconst5]
fstp dword ptr [esi+58h]
call ebp
fld dword ptr [esp+10h]
push 1
fsub qword ptr [ebx+_fconst6]
sub esp,8
xor edx,edx
mov ecx,esi
fstp dword ptr [esp+1ch]
fld dword ptr [esp+1ch]
fstp dword ptr [esp+4]
fld dword ptr [esp+18h]
fstp dword ptr [esp]
push 1
mov edi,dword ptr [ebx+_lpFunc3]
call edi
mov eax,dword ptr [esi]
mov eax,dword ptr [eax+68h]
xor edx,edx
mov ecx,esi
call eax
pop ebp
pop esi
.endif
add esp,10h
retn
HOOK2 equ this byte
call @F
@@:
pop ebx
sub ebx,offset @B
;--------------------------
pushad
mov dword ptr[ebx+_strom401return],ecx
call HOOK2_SUB1
popad
mov eax,[ebx+_lpFunc7]
xor ebx,ebx
jmp eax
DoHook proc
local @lpOldProtect :DWORD
call @F
@@:
pop ebx
sub ebx,offset @B
;------------------------------------------
mov ecx,[ebx+_lpHook1]
lea edi,@lpOldProtect
_invoke [ebx+_lpVirtualProtect],ecx,5,40h,edi
mov ecx,[ebx+_lpHook2]
_invoke [ebx+_lpVirtualProtect],ecx,5,40h,edi
mov esi,[ebx+_lpHook1]
mov byte ptr [esi],0e8h
add esi,5
lea ecx,[offset HOOK1+ebx]
sub ecx,esi
mov dword ptr [esi-4],ecx
mov esi,[ebx+_lpHook2]
mov byte ptr [esi],0e8h
add esi,5
lea ecx,[offset HOOK2+ebx]
sub ecx,esi
mov dword ptr [esi-4],ecx
Ret
DoHook EndP
ShowMana proc _Version
local @hDllUser :DWORD
local @hDllKernel :DWORD
local @hDllStorm :DWORD
local @hDllGame :DWORD
local @VersionH :BYTE
local @VersionL :BYTE
call @F
@@:
pop ebx
sub ebx,offset @B
lea eax,[ebx + offset _szDllUser]
_invoke [ebx + _lpGetModuleHandle],eax
mov @hDllUser,eax
lea esi,[ebx + offset _szMessageBox]
lea edi,[ebx + offset _lpMessageBox]
_invoke [ebx + _lpGetProcAddress],@hDllUser,esi
mov [edi],eax
lea eax,[ebx + offset _szDllKernel]
_invoke [ebx + _lpGetModuleHandle],eax
mov @hDllKernel,eax
lea esi,[ebx + offset _szVirtualProtect]
lea edi,[ebx + offset _lpVirtualProtect]
_invoke [ebx + _lpGetProcAddress],@hDllKernel,esi
mov [edi],eax
lea eax,[ebx + offset _szDllStorm]
_invoke [ebx + _lpGetModuleHandle],eax
mov @hDllStorm,eax
lea edi,[ebx + offset _lpStrom401]
_invoke [ebx + _lpGetProcAddress],@hDllStorm,191h
mov [edi],eax
lea eax,[ebx + offset _szDllGame]
_invoke [ebx + _lpGetModuleHandle],eax
mov @hDllGame,eax
;------------------------------------------------------------
;分离版本号
mov ecx,_Version
mov @VersionH,ch
mov @VersionL,cl
.if @VersionH==4 && @VersionL==2 ;1.24c
lea ecx,[eax+27B950h]
mov [ebx+_lpFunc1],ecx
lea ecx,[eax+334C00h]
mov [ebx+_lpFunc2],ecx
lea ecx,[eax+606860h]
mov [ebx+_lpFunc3],ecx
lea ecx,[eax+606370h]
mov [ebx+_lpFunc4],ecx
lea ecx,[eax+35A740h]
mov [ebx+_lpFunc5],ecx
lea ecx,[eax+32D300h]
mov [ebx+_lpFunc6],ecx
lea ecx,[eax+2C7F10h]
mov [ebx+_lpFunc7],ecx
lea ecx,[eax+37A563h]
mov [ebx+_lpHook1],ecx
lea ecx,[eax+37A968h]
mov [ebx+_lpHook2],ecx
.elseif @VersionH==0 && @VersionL==4 ;1.20e
lea ecx,[eax+1C0030h]
mov [ebx+_lpFunc1],ecx
lea ecx,[eax+1264D0h]
mov [ebx+_lpFunc2],ecx
lea ecx,[eax+13780h]
mov [ebx+_lpFunc3],ecx
lea ecx,[eax+13AB0h]
mov [ebx+_lpFunc4],ecx
lea ecx,[eax+1529A0h]
mov [ebx+_lpFunc5],ecx
lea ecx,[eax+111700h]
mov [ebx+_lpFunc6],ecx
lea ecx,[eax+1D63D0h]
mov [ebx+_lpFunc7],ecx
lea ecx,[eax+166A14h]
mov [ebx+_lpHook1],ecx
lea ecx,[eax+167639h]
mov [ebx+_lpHook2],ecx
.elseif @VersionH==4 && @VersionL==3 ;1.24d
lea ecx,[eax+27B95h]
mov [ebx+_lpFunc1],ecx
lea ecx,[eax+334C60h]
mov [ebx+_lpFunc2],ecx
lea ecx,[eax+6068C0h]
mov [ebx+_lpFunc3],ecx
lea ecx,[eax+6063D0h]
mov [ebx+_lpFunc4],ecx
lea ecx,[eax+35A7A0h]
mov [ebx+_lpFunc5],ecx
lea ecx,[eax+32D360h]
mov [ebx+_lpFunc6],ecx
lea ecx,[eax+2C7F70h]
mov [ebx+_lpFunc7],ecx
lea ecx,[eax+37A5C3h]
mov [ebx+_lpHook1],ecx
lea ecx,[eax+37A9C8h]
mov [ebx+_lpHook2],ecx
.endif
call DoHook
Ret
ShowMana EndP
REMOTE_CODE_END equ this byte
REMOTE_CODE_LENGTH equ offset REMOTE_CODE_END - offset REMOTE_CODE_START
DoShowMana proc
local @lpRemoteCode :DWORD
invoke GetModuleHandle,addr szDllKernel
mov ebx,eax
invoke GetProcAddress,ebx,offset szLoadLibrary
mov lpLoadLibrary,eax
invoke GetProcAddress,ebx,offset szGetProcAddress
mov lpGetProcAddress,eax
invoke GetProcAddress,ebx,offset szGetModuleHandle
mov lpGetModuleHandle,eax
invoke VirtualAllocEx,hProcWar3,NULL,REMOTE_CODE_LENGTH,MEM_COMMIT,PAGE_EXECUTE_READWRITE
.if eax
mov @lpRemoteCode,eax
invoke WriteProcessMemory,hProcWar3,@lpRemoteCode,\
offset REMOTE_CODE_START,REMOTE_CODE_LENGTH,NULL
invoke WriteProcessMemory,hProcWar3,@lpRemoteCode,\
offset lpLoadLibrary,sizeof dword * 3,NULL
mov eax,@lpRemoteCode
add eax,offset ShowMana - offset REMOTE_CODE_START
;将魔兽的版本号作为参数,结构为1.2xy中的xy,ah=x,al=y
mov ecx,nWar3VersionH
mov dh,cl
mov ecx,nWar3VersionL
mov dl,cl
invoke CreateRemoteThread,hProcWar3,NULL,0,eax,edx,0,NULL
invoke CloseHandle,eax
.endif
invoke CloseHandle,hProcWar3
Ret
DoShowMana EndP