Posts Tagged ‘idiots’

WoWMimic v50

June 11th, 2009

Another WoWMimic build was released recently. I’ve reversed it yet again to bring you the gory details.

They’ve beefed up (by their standards) the obfuscation on this one. I put “by their standards” because they’re morons, and by the standards of any real reverser ‘beefed up’ is hardly the right term. It seems they’ve learned two new ‘tricks’, one they use once, another they use constantly. Both are very lame and very obvious and easy to undo though.

The first is this:

15DEBE67 | 5B            | POP     EBX                         | ; Pop address of current line into EBX

15DEBE68 | 81EB 471A4000 | SUB     EBX, 401A47                 | ; Subtract 401A47 from EBX (15DEBE67) (Final: 159EA420)

15DEBE6E | 8B83 F1194000 | MOV     EAX, DWORD PTR [EBX+4019F1] | ; Move 7CCAE98C into EAX

15DEBE74 | 35 8CE9CA7C   | XOR     EAX, 7CCAE98C               | ; Xor EAX (7CCAE98C) with 7CCAE98C. (Final: 0)

15DEBE79 | 8D8B C81A4000 | LEA     ECX, DWORD PTR [EBX+401AC8] | ; Move EBX (159EA420) + 401AC8 into ECX (Final: 15DEBEE8)

15DEBE7F | 8D0401        | LEA     EAX, DWORD PTR [ECX+EAX]    | ; Move ECX (15DEBEE8) + EAX (0) into EAX (Final: 15DEBEE8)

15DEBE82 | FFE0          | JMP     NEAR EAX                    | ; Jump NEAR to EAX (15DEBEE8). Another obfuscation attempt.

They have attempted to hide the jump address with some VERY basic math. Sorry guys, but you’re gonna have to do better than that.

Second trick:

; MimicVectoredHandler

15DEBE06 | 55            | PUSH    EBP       | ; Standard stack frame setup

15DEBE07 | 8BEC          | MOV     EBP, ESP  | ; Standard stack frame setup

15DEBE09 | 81C4 00FFFFFF | ADD     ESP, -100 | ; Sub ESP 100. Room for local variables

15DEBE0F | EB 50         | JMP     15DEBE61  | ; Jump over garbage and into an instruction. Obfuscation attempt.

; Original - Nice try… Not!

15DEBE60 | 2A60 E8 | SUB     AH, BYTE PTR [EAX-18] | ; Jump lands one byte into this instruction.

15DEBE63 | 0000    | ADD     BYTE PTR [EAX], AL    | ; Just reassemble the bytes to fix it.

15DEBE65 | 0000    | ADD     BYTE PTR [EAX], AL    | ; See below for one I prepared earlier!

; Fixed - Wow.. that was hard…

15DEBE61 | 60          | PUSHAD           | ; Preserve registers

15DEBE62 | EB 00000000 | CALL    15DCBE67 | ; Call next line

They’re attempting to confuse disassemblers by jumping into what seems to be the middle of an instruction. What they don’t seem to realize is that there are two very easy ways to undo this. One is to realign your disassembler for that chunk if it has that functionality. The other is to just dump out the bytes, assemble them externally (in OllyDbg or another tool that can assemble bytes into mnemonics), and just read from there.  Thanks to Nessox and Apoc for doing that for me because Olly was being a whore on my PC.  To put it simply, its no barrier to any reverser with half a brain.

Both obfuscation ‘techniques’ (if you can call them that) just reek of the work of an amateur. I still think they’re waiting for “one of china’s best hackers” to turn up for work.

As for actual changes to the implementation, there isn’t much, they seem to have wasted the last week or so on obfuscation which took them 1000x longer to write than it took me to reverse. Nevertheless, there is one notable change, which is to their ZwQueryVirtualMemory hook.

They no longer null out pMemoryBasicInformation->BaseAddress, but they have started nulling out pMemoryBasicInformation->RegionSize. The reason for this is both obvious and hilarious.

The previous build of WardenMimic (new one coming once I get some free time) worked by enumerating all regions of memory to look for the one that has been hidden. It is identified by detecting the unique return values which would never be returned in normal circumstances. Whilst the change breaks WardenMimic, it does so for all the wrong reasons. Not only do they obviously have no idea how a NtQueryVirtualMemory hook is actually supposed to work, they’ve fucked up and left another gaping hole AGAIN. That’s right, the hook is STILL detectable by Warden because the morons obviously don’t understand the first thing about Windows internals and virtual memory.

The rest of the APIs (GetCursorPos, SetCursorPos, NtGetContextThread) remain unhooked for the time being. (GetCursorPos and SetCursorPos still have the bug that was left there from the previous build.)

So, in summary, the changes are as followed:

  • Had another crack at obfuscating their anti-detection code and failed hard.
  • Attempted to fix their NtQueryVirtualMemory hook. Whilst they broke WardenMimic they fucked up their hook AGAIN and so Mimic is STILL DETECTABLE.

It’s pretty funny it took them this long just to push out such a simple new build. Really says something about either the quality of the developers or the quality of the customer service department. (Regardless though, the fail obfuscation attempts definitely say something about the developers. — In case you’re slow, its says they’re incompetent.)

Full code (with documentation) is available again. Anything marked as “Fixed” has been realigned so most of the obfuscation will not be apparent unless you reverse it yourself.

WoWMimic v50 Anti-Detection Code.