code quite a lot. Even wrote a tool that restores the original ASM code of a function (rather than their spaghetti code with lots of jmp, xchg, etc. instructions). The resources are encrypted. If I remember correctly, the only thing that was a constant, was the fact that the encrypted value for a static value was the same. In the sense that they don't use dynamic cycling. So, if 5000 Minerals are 0x7F58694D, then the next time you have 5000 Minerals you can search for the same 0x7F58694D. Then use the resources and search for the equivalent of another constant (build something, you get 4550; find out what 4550's encrypted value is). That's what I had at the time. I have not kept up with the updates so I don't really know if they've changed the algorithm.
But in short: don't know the value, start with "unknown value". Go with 8 bytes as the type. Create something, so resources decrease: "has changed". Repeat the process, alternating scenarios: build to decrease, acquire to increase, pause the game, open options menu, etc. For each operation do the specific type of scan you feel logic. Just don't scan for "has increased" when your value on-screen has increased. The real value is encrypted and you won't find it with that logic. Always do "has changed", "has not changed".
Code: Select all
[ENABLE]
alloc( Damage, 2048, SC2.exe )
label( back )
label( Damage_exit )
label( Player_do )
label( Damage_next )
label( bResources )
registersymbol( bResources )
label( bMap )
registersymbol( bMap )
label( pResources )
registersymbol( pResources )
label( rAmount )
registersymbol( rAmount )
label( dwMapVal )
registersymbol( dwMapVal )
label( GetResPtrToDword )
label( GetResPtrFromDword )
label( DecryptAddEncryptResource )
label( DecryptAddEncryptResource_exit )
label( GetMapPtr )
label( DecryptMapVal )
label( EncryptMapVal )
label( lResources )
label( Damage_ )
registersymbol( Damage_ )
Damage:
cmp byte ptr [edi+86E],1
jne Damage_exit
cmp byte ptr [bResources],1
jne Damage_next
pushad
movzx ebx,[edi+86E]
call GetResPtrToDword
push pResources
call GetResPtrFromDword
xor esi,esi
mov edi,[pResources]
lResources:
mov eax,esi
mov ecx,edi
lea ecx,[ecx+eax*8+340]
call DecryptAddEncryptResource
inc esi
cmp esi,2 // Minerals and Vespene Gas (change to 4 if you want Biomass as well)
jb lResources
popad
mov byte ptr [bResources],0
jmp Player_do
Damage_next:
cmp byte ptr [bMap],1
jne Player_do
pushad
call GetMapPtr
push edx // store ptr for later
push dwMapVal
call DecryptMapVal
mov eax,[dwMapVal]
cmp eax,-1
setne bl
movzx ecx,bl
neg ecx
sbb ecx,ecx
pop ebx // then pop it here
push ecx
call EncryptMapVal
popad
mov byte ptr [bMap],0
Player_do:
jmp back+2F
Damage_exit:
test [edx+ecx+1C],eax
jmp back+10
GetResPtrToDword:
mov eax,[SC2.exe+1EC9064]
sub eax,[SC2.exe+1B5359C]
mov edx,[eax]
movzx ecx,bl
lea edx,[edx+ecx*4]
ret
GetResPtrFromDword:
push ebp
mov ebp,esp
push esi
push edi
mov edi,[ebp+8]
mov esi,edx
movzx eax,word ptr [esi]
movzx ecx,word ptr [esi+02]
mov edx,eax
and edx,FFF
mov esi,SC2.exe+1B52C18 // added by me
//movzx edx,word ptr [edx*4+SC2.exe+1B52C18]
movzx edx,word ptr [edx*4+esi]
add ecx,edx
mov edx,ecx
and edx,FFF
//movzx edx,word ptr [edx*4+SC2.exe+1B52C18]
movzx edx,word ptr [edx*4+esi]
sub eax,edx
mov [edi],ax
mov [edi+02],cx
pop edi
pop esi
pop ebp
ret 4
DecryptAddEncryptResource:
push ebp
mov ebp,esp
push esi
push edi
// decrypt
mov esi,[ecx]
mov edx,[ecx+04]
mov edi,esi
mov eax,esi
shr edi,C
sub eax,edi
not eax
and eax,FFF
mov ebx,SC2.exe+1B52C18 // added by me
//xor edx,[eax*4+SC2.exe+1B52C18]
xor edx,[eax*4+ebx]
mov eax,edx
shr eax,C
xor eax,edx
and eax,FFF
//mov eax,[eax*4+SC2.exe+1B52C18]
mov eax,[eax*4+ebx]
add eax,esi
mov esi,eax
xor esi,edx
and esi,55555555
xor esi,eax
xor eax,edx
and eax,55555555
xor eax,edx
// add
mov edi,eax
add esi,[rAmount]
mov eax,esi
or eax,edi
jne short @f
// if 0, set value to encrypted NULL, already calculated in pointers below
mov edx,[SC2.exe+1F4C23C]
mov [ecx],edx
mov eax,[SC2.exe+1F4C240]
mov [ecx+04],eax
jmp DecryptAddEncryptResource_exit
@@:
// encrypt
mov edx,esi
mov eax,esi
xor edx,edi
xor eax,edi
and edx,55555555
xor edx,edi
and eax,55555555
xor eax,esi
mov esi,edx
shr esi,C
xor esi,edx
and esi,FFF
mov ebx,SC2.exe+1B52C18 // added by me
//sub eax,[esi*4+SC2.exe+1B52C18]
sub eax,[esi*4+ebx]
mov edi,eax
shr edi,C
mov esi,eax
sub esi,edi
not esi
and esi,FFF
//mov esi,[esi*4+SC2.exe+1B52C18]
mov esi,[esi*4+ebx]
xor esi,edx
mov [ecx],eax
mov [ecx+04],esi
DecryptAddEncryptResource_exit:
pop edi
pop esi
pop ebp
ret
GetMapPtr:
mov edx,[SC2.exe+1B53DD4]
xor edx,[SC2.exe+1C62A84]
add edx,14
ret
DecryptMapVal:
push ebp
mov ebp,esp
push esi
push edi
mov edi,[ebp+8]
mov esi,edx
movzx eax,word ptr [esi]
movzx ecx,word ptr [esi+02]
mov edx,eax
and edx,FFF
mov esi,SC2.exe+1B52C18 // added by me
//movzx edx,word ptr [edx*4+SC2.exe+1B52C18]
movzx edx,word ptr [edx*4+esi]
sub ecx,edx
mov edx,ecx
and edx,FFF
//movzx edx,word ptr [edx*4+SC2.exe+1B52C18]
movzx edx,word ptr [edx*4+esi]
sub eax,edx
mov [edi],ax
mov [edi+02],cx
pop edi
pop esi
pop ebp
ret 4
EncryptMapVal:
push ebp
mov ebp,esp
push esi
lea edx,[ebp+8]
movzx esi,word ptr [edx+02]
movzx eax,word ptr [edx]
mov edx,esi
and edx,FFF
mov edi,SC2.exe+1B52C18
//movzx edx,word ptr [edx*4+SC2.exe+1B52C18]
movzx edx,word ptr [edx*4+edi]
add eax,edx
mov edx,eax
and edx,FFF
//movzx edx,word ptr [edx*4+SC2.exe+1B52C18]
movzx edx,word ptr [edx*4+edi]
add edx,esi
movzx edx,dx
mov [ebx],ax
mov [ebx+02],dx
pop esi
pop ebp
ret 4
bResources:
db 0
bMap:
db 0
pResources:
dd 0
rAmount:
dd (int)5000
dwMapVal:
dd 0
SC2.exe+4EDFD7:
Damage_:
jmp Damage
nop
back:
[DISABLE]
Damage_:
db 85 44 0A 1C EB 10
unregistersymbol( Damage_ )
unregistersymbol( dwMapVal )
unregistersymbol( rAmount )
unregistersymbol( pResources )
unregistersymbol( bMap )
unregistersymbol( bResources )
dealloc( Damage )
It's an example, I don't know how to find it in current version or whatever other questions you have. Just know the code is ripped from the game's engine itself (am using their function from that version of the game, at the time). Which code: the code that's executed when you type in the cheats which give you resources
I've found where the effect is when the cheat is processed, understood how it works and ripped that code to use it myself.
P.S.: The problem I didn't have back in the day was I could debug the game. Now they have this shitty driver-like mechanism which blocks debugging in any form. I think they also disallow changing executable code (so no scripts). They do let you scan memory and change values (which are not in the executable code)