Started poking around some time back but never got around to seeing what they added to stop function calls. Below is part of GetLocalPlayer,
0x000B70E4
Code:
push ebp
mov ebp, esp
sub esp, 0x10
mov dword ptr [ebp - 8], 0x19b5c47
mov edx, dword ptr [ebp + 4] //Return Address
push edi
push esi
mov dword ptr [ebp - 4], 0xd41000 //0xD40000 Image Base + 0x1000 Header
cmp byte ptr [edx - 2], 0xff //[edx - 2] = D4, ZF = 0
sete cl //cl = 0
cmp byte ptr [edx - 3], 0xff //[edx - 3] = 42, ZF = 0
sete al //al = 0
or cl, al //cl = 0
cmp byte ptr [edx - 4], 0xff //[edx - 4] = 48, ZF = 0
sete al //al = 0
or cl, al //cl = 0
cmp byte ptr [edx - 6], 0xff //[edx - 6] = C3, ZF = 0
sete al //al = 0
or cl, al //cl = 0
cmp byte ptr [edx - 5], 0xe8 //[edx - 5] = E8, ZF = 1 <-- Main Check
sete al //al = 1
or cl, al //cl = 1
cmp byte ptr [edx - 7], 0xff //[edx - 7] = 5D, ZF = 0
sete al //al = 0
or cl, al //cl = 1
je 0xdf7246 //Jump if ZF equal 1 (ZF = 0)
cmp edx, dword ptr [ebp - 4] //0x00d41000 > Return Address
jb 0xdf7246 //Jump if above or equal Image Base + Some Size (not base off page type)
cmp edx, dword ptr [ebp - 8] //0x019b5c47 <= Return Address
jae 0xdf7246
As you can see they are checking if the caller is coming from inside wow and if the caller is using the opcode E8.
I can only think of one reason that they are checking the caller, I'm guessing for ret hopping. But even then wow has some calls that still work like,
00C74B04
Code:
call 004EDC9E+wow.exe
ret
Simple wrapper,
Code:
retAddress = 00C74B09h
GetLocalPlayer = 00160767h
-------------------------------------------------
call SPOOF_RET
jmp END
SPOOF_RET:
mov eax, retAddress
push eax
mov eax, GetLocalPlayer
jmp eax
END:
Anyone know why they check for 0xFF? I feel like it just opens them up to more possibilities, as 2, 3, 4, 6 or 7 could be FF and bypass the E8 check.
--edit
nvm, skipped over
Code:
mov edx, dword ptr [ebp + 4]
....
mov cl, byte ptr [edx - 5]
cmp cl, 0xe8
je 00EA094D
mov al,[edx-07]
cmp al, 0x9A
je 00EA094D
cmp al, 0xFF
jne 00EA08D0
Guess they check if its E8 or 9A Call. Then a 2nd check later.
They also check the range again,
Code:
mov esi, dword ptr [0x19bd650] //Image Base Pointer
...
mov eax, dword ptr [0x19bd654] //Image Size Pointer
add eax, esi
cmp edx, esi
jb 0xea0dc6
cmp edx, eax
jae 0xea0dc6
Does anyone have an idea what they are doing after the return check?
Code:
lea eax, dword ptr [ebp - 0x14]
mov dword ptr [ebp - 0x14], 0x62a8cceb
push eax //Arg2 0xC
lea eax, dword ptr [ebp - 0x18]
mov dword ptr [ebp - 0x18], 0x9da41324
push eax //Arg1 0x8
....
mov edx, dword ptr [ebp + 0xc] //-> 0x62a8cceb
mov eax, 0xb821a50c
mov esi, dword ptr fs:[0x20] //Process ID
mov ecx, dword ptr [edx] //0x62a8cceb
ror ecx, 0xb
sub eax, ecx
mov dword ptr [edx], eax
mov dword ptr [ebp + 0xc], 0x511e2d55
lea ecx, dword ptr [ecx]
mov edx, dword ptr [ebp + 8] // -> 0x9da41324
mov ecx, dword ptr [edx] //0x9da41324
imul ecx, esi
not ecx
xor ecx, 0x94d2769e
xor dword ptr [edx], ecx
I think its just returning a key.
IDAs attemp,
Code:
int __cdecl sub_4071C0(_DWORD *a1, _DWORD *a2)
{
int v1; // ecx@1
int result; // eax@1
v1 = __ROR4__(*a2, 11);
result = 0xB821A50C - v1;
*a2 = 0xB821A50C - v1;
*a1 ^= ~(__readfsdword(32) * *a1) ^ 0x94D2769E;
return result;
}
....
DWORD __cdecl GetSomething(_DWORD *a1, _DWORD *a2)
{
int v1; // ecx@1
int result; // eax@1
//Caller Check
v1 = __ROR4__(*a2, 11);
result = 0xB821A50C - v1;
*a2 = 0xB821A50C - v1;
*a1 ^= ~(__readfsdword(32) * *a1) ^ 0x94D2769E;
DWORD* _array = (DWORD*)0xFA31E0;
DWORD unk1 = _array[result >> 14];
DWORD unk1 = _array[result & 0xFFF];
/* TO DO
mov esi, 0x11044FC+wow.exe
mov ebx, 1324h
pop ecx
pop ecx
movzx ecx, si
mov eax, ebx
shr esi, 10h
sub eax, ecx
xor esi, eax
mov edi, 511E2D55h
shl esi, 10h
or esi, ecx
mov edx, [ebp-14h]
mov eax, edx
shr eax, 14h
and edx, 0FFFh
movzx ecx, si
shr esi, 10h
mov eax, 0xFA31E0+wow.exe[eax]
shr eax, 10h
ror eax, 3
add eax, eax
sub eax, ecx
xor esi, eax
mov eax, 0xFA31E0+wow.exe[edx]
shl esi, 10h
or esi, ecx
movzx ecx, ax
xor esi, [ebp-18h]
movzx edx, si
mov eax, edx
ror ecx, 0Bh
shr esi, 10h
not eax
xor eax, ecx
mov [ebp-8], edi
xor esi, eax
shl esi, 10h
or esi, edxstc
shr dl, 0
movzx ecx, si
mov edi, 2768h
shr esi, 10h
mov eax, edi
sub eax, ecx
xor esi, eax
shl esi, 10h
or esi, ecx
*/
}