asmhack
05-04-2008, 09:39 PM
; warcraft 3 cd key grabber by asmhack
; asmhack@live.com
; win32 x86, flat assembler syntax
format pe console on 'nul'
entry @@entry
include 'win32a.inc'
; warcraft 3 uses dma (dynamic memory allocation)
; after some memory analyzing, we can see that RoC key
; is stored everytime at $XXXXXA0 address and the FT key
; is stored 6 bytes after the end of the RoC key
; (the keys are stored encrypted inside an .mpq file after the installation
; and are loaded everytime into the memory when we enter local area network or battle.net)
WC3_KEY_ADDRESS_PATTERN equ $00000A0
; |
; dma scan addresses jump |
WC3_KEY_ADDRESS_JUMP equ $0010000
; | |
; maximum address | |
WC3_KEY_ADDRESS_MAX equ $FFF0000+WC3_KEY_ADDRESS_PATTERN
; $FFF00A0
; key length
WC3_KEY_LENGTH equ $6+$4+$6+$4+$6
;
; key distance |RoC-FT|
WC3_KEY_DISTANCE equ WC3_KEY_LENGTH+$6
section '' import data code writable readable executable
library kernel32,'kernel32',user32,'user32',advapi32,'adva pi32',crtdll,'crtdll'
import kernel32,ExitProcess,'ExitProcess',\
GetCurrentProcess,'GetCurrentProcess',\
Sleep,'Sleep',\
OpenProcess,'OpenProcess',\
ReadProcessMemory,'ReadProcessMemory'
import user32,FindWindowA,'FindWindowA',\
GetWindowThreadProcessId,'GetWindowThreadProcessId ',\
GetAsyncKeyState,'GetAsyncKeyState'
import advapi32,OpenProcessToken,'OpenProcessToken',\
LookupPrivilegeValueA,'LookupPrivilegeValueA',\
AdjustTokenPrivileges,'AdjustTokenPrivileges'
import crtdll,printf,'printf'
struc TOKEN_PRIVILEGES
{ .privilegecount dd $0
.low dd $0
.high dd $0
.attributes dd $0 } tkp TOKEN_PRIVILEGES
roc db 'RoC: ',$0
ft db $D,$A,'FT: ',$0
SE_DEBUG_NAME db 'SeDebugPrivilege',$0
WC3_WND_NAME db 'Warcraft III',$0
pro dd $0
tmp dd $0
chr db $0
buffer rb WC3_KEY_LENGTH+$1 ; buffer to store key
; (size = key length + 1 (null-terminated string))
message rb WC3_KEY_LENGTH+$4+$1 ; buffer to store final formated key
; (size = key length + 4 seperators (-) + 1 (null-terminated string))
@@entry:
xor ebx,ebx
call [GetCurrentProcess] ; get debug privileges
stdcall [OpenProcessToken],eax,$28,tmp ; so we can access/read process memory
stdcall [LookupPrivilegeValueA],ebx,SE_DEBUG_NAME,tkp.low
mov dword[tkp.privilegecount],$1
mov dword[tkp.attributes],$2
stdcall [AdjustTokenPrivileges],[tmp],ebx,tkp,ebx,ebx,ebx
@@switch:
stdcall [Sleep],$FF ; wait for [Insert] key press
stdcall [GetAsyncKeyState],VK_INSERT ; the key should be pressed after
test eax,eax ; we enter [Local Area Network] in the game
jz @@switch
stdcall [FindWindowA],ebx,WC3_WND_NAME ; is the game opened ?
test eax,eax
jz @@switch
stdcall [GetWindowThreadProcessId],eax,tmp ; get process handle
stdcall [OpenProcess],PROCESS_ALL_ACCESS,ebx,[tmp]
mov [pro],eax
mov ebp,WC3_KEY_ADDRESS_PATTERN
@@scan: ; scan the memory for the key
cmp ebp,WC3_KEY_ADDRESS_MAX
jz @@switch
lea ebp,[ebp+WC3_KEY_ADDRESS_JUMP]
stdcall [ReadProcessMemory],[pro],ebp,chr,$1,ebx
test eax,eax
jz @@scan
mov [tmp],ebp
jmp @f
@@check:
stdcall [ReadProcessMemory],[pro],[tmp],chr,$1,ebx
test eax,eax
jz @@scan
@@:
cmp byte[chr],$30 ; A <= byte <= Z or 0 <= byte <= 9
jb @@scan
cmp byte[chr],$5A
ja @@scan
cmp byte[chr],$3A
jb @f
cmp byte[chr],$40
jbe @@scan
@@:
inc [tmp]
mov eax,[tmp]
sub eax,ebp
cmp eax,WC3_KEY_LENGTH ; check until we have whole the key
jb @@check
sub [tmp],WC3_KEY_LENGTH
stdcall [ReadProcessMemory],[pro],[tmp],buffer,WC3_KEY_LENGTH,ebx ; read RoC key
call @@format ; format
cinvoke printf,roc ; display
cinvoke printf,message
add [tmp],WC3_KEY_DISTANCE
stdcall [ReadProcessMemory],[pro],[tmp],buffer,WC3_KEY_LENGTH,ebx ; read FT key
call @@format ; format
cinvoke printf,ft ; display
cinvoke printf,message
stdcall [Sleep],-$1
@@format: ; insert 4 seperators (-)
mov ecx,buffer
mov edx,message
mov eax,dword[ecx]
mov dword[edx],eax
mov ax,word[ecx+$4]
mov word[edx+$4],ax
mov byte[edx+$6],'-'
mov eax,dword[ecx+$6]
mov dword[edx+$7],eax
mov byte[edx+$B],'-'
mov eax,dword[ecx+$A]
mov dword[edx+$C],eax
mov ax,word[ecx+$E]
mov word[edx+$10],ax
mov byte[edx+$12],'-'
mov eax,dword[ecx+$10]
mov dword[edx+$13],eax
mov byte[edx+$17],'-'
mov eax,dword[ecx+$14]
mov dword[edx+$18],eax
mov ax,word[ecx+$18]
mov word[edx+$1C],ax
ret
; asmhack@live.com
; win32 x86, flat assembler syntax
format pe console on 'nul'
entry @@entry
include 'win32a.inc'
; warcraft 3 uses dma (dynamic memory allocation)
; after some memory analyzing, we can see that RoC key
; is stored everytime at $XXXXXA0 address and the FT key
; is stored 6 bytes after the end of the RoC key
; (the keys are stored encrypted inside an .mpq file after the installation
; and are loaded everytime into the memory when we enter local area network or battle.net)
WC3_KEY_ADDRESS_PATTERN equ $00000A0
; |
; dma scan addresses jump |
WC3_KEY_ADDRESS_JUMP equ $0010000
; | |
; maximum address | |
WC3_KEY_ADDRESS_MAX equ $FFF0000+WC3_KEY_ADDRESS_PATTERN
; $FFF00A0
; key length
WC3_KEY_LENGTH equ $6+$4+$6+$4+$6
;
; key distance |RoC-FT|
WC3_KEY_DISTANCE equ WC3_KEY_LENGTH+$6
section '' import data code writable readable executable
library kernel32,'kernel32',user32,'user32',advapi32,'adva pi32',crtdll,'crtdll'
import kernel32,ExitProcess,'ExitProcess',\
GetCurrentProcess,'GetCurrentProcess',\
Sleep,'Sleep',\
OpenProcess,'OpenProcess',\
ReadProcessMemory,'ReadProcessMemory'
import user32,FindWindowA,'FindWindowA',\
GetWindowThreadProcessId,'GetWindowThreadProcessId ',\
GetAsyncKeyState,'GetAsyncKeyState'
import advapi32,OpenProcessToken,'OpenProcessToken',\
LookupPrivilegeValueA,'LookupPrivilegeValueA',\
AdjustTokenPrivileges,'AdjustTokenPrivileges'
import crtdll,printf,'printf'
struc TOKEN_PRIVILEGES
{ .privilegecount dd $0
.low dd $0
.high dd $0
.attributes dd $0 } tkp TOKEN_PRIVILEGES
roc db 'RoC: ',$0
ft db $D,$A,'FT: ',$0
SE_DEBUG_NAME db 'SeDebugPrivilege',$0
WC3_WND_NAME db 'Warcraft III',$0
pro dd $0
tmp dd $0
chr db $0
buffer rb WC3_KEY_LENGTH+$1 ; buffer to store key
; (size = key length + 1 (null-terminated string))
message rb WC3_KEY_LENGTH+$4+$1 ; buffer to store final formated key
; (size = key length + 4 seperators (-) + 1 (null-terminated string))
@@entry:
xor ebx,ebx
call [GetCurrentProcess] ; get debug privileges
stdcall [OpenProcessToken],eax,$28,tmp ; so we can access/read process memory
stdcall [LookupPrivilegeValueA],ebx,SE_DEBUG_NAME,tkp.low
mov dword[tkp.privilegecount],$1
mov dword[tkp.attributes],$2
stdcall [AdjustTokenPrivileges],[tmp],ebx,tkp,ebx,ebx,ebx
@@switch:
stdcall [Sleep],$FF ; wait for [Insert] key press
stdcall [GetAsyncKeyState],VK_INSERT ; the key should be pressed after
test eax,eax ; we enter [Local Area Network] in the game
jz @@switch
stdcall [FindWindowA],ebx,WC3_WND_NAME ; is the game opened ?
test eax,eax
jz @@switch
stdcall [GetWindowThreadProcessId],eax,tmp ; get process handle
stdcall [OpenProcess],PROCESS_ALL_ACCESS,ebx,[tmp]
mov [pro],eax
mov ebp,WC3_KEY_ADDRESS_PATTERN
@@scan: ; scan the memory for the key
cmp ebp,WC3_KEY_ADDRESS_MAX
jz @@switch
lea ebp,[ebp+WC3_KEY_ADDRESS_JUMP]
stdcall [ReadProcessMemory],[pro],ebp,chr,$1,ebx
test eax,eax
jz @@scan
mov [tmp],ebp
jmp @f
@@check:
stdcall [ReadProcessMemory],[pro],[tmp],chr,$1,ebx
test eax,eax
jz @@scan
@@:
cmp byte[chr],$30 ; A <= byte <= Z or 0 <= byte <= 9
jb @@scan
cmp byte[chr],$5A
ja @@scan
cmp byte[chr],$3A
jb @f
cmp byte[chr],$40
jbe @@scan
@@:
inc [tmp]
mov eax,[tmp]
sub eax,ebp
cmp eax,WC3_KEY_LENGTH ; check until we have whole the key
jb @@check
sub [tmp],WC3_KEY_LENGTH
stdcall [ReadProcessMemory],[pro],[tmp],buffer,WC3_KEY_LENGTH,ebx ; read RoC key
call @@format ; format
cinvoke printf,roc ; display
cinvoke printf,message
add [tmp],WC3_KEY_DISTANCE
stdcall [ReadProcessMemory],[pro],[tmp],buffer,WC3_KEY_LENGTH,ebx ; read FT key
call @@format ; format
cinvoke printf,ft ; display
cinvoke printf,message
stdcall [Sleep],-$1
@@format: ; insert 4 seperators (-)
mov ecx,buffer
mov edx,message
mov eax,dword[ecx]
mov dword[edx],eax
mov ax,word[ecx+$4]
mov word[edx+$4],ax
mov byte[edx+$6],'-'
mov eax,dword[ecx+$6]
mov dword[edx+$7],eax
mov byte[edx+$B],'-'
mov eax,dword[ecx+$A]
mov dword[edx+$C],eax
mov ax,word[ecx+$E]
mov word[edx+$10],ax
mov byte[edx+$12],'-'
mov eax,dword[ecx+$10]
mov dword[edx+$13],eax
mov byte[edx+$17],'-'
mov eax,dword[ecx+$14]
mov dword[edx+$18],eax
mov ax,word[ecx+$18]
mov word[edx+$1C],ax
ret