WoWMimic v50
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.
I’m curious, what disassembler do you use? Maybe i’m wrong, but I get the impression that you only use OllyDBG in specific situations.
well, i must say that i am impressed that you took the time to reverse this mess of work /’calling mimic ‘work’ is an OVER-statement’\ you must have been very bored. Ive reversed the past build only to find a nasty coded bot, that compares to the china iphone fake… *peice of shit!* .. By looking at mimics source , only a few things come to mind… Ethier, the cheaply paid devs. /if u can call them that\ dont give 2 fucks bout their users and purposly lie about *fixing* mimic , OR they truely are as ignorant and un-educated as they seem to reversers like myself… In my opinion , its all of the above, they dont give a shit AND are ignorant… Id like to hear your true opinion on this subject cypher… Also ive got an idea that will destroy mimic for good…. Let me know if your interested. -kam
@Eradicator
The dumps are from MHS.
http://memoryhacking.com/
Hey, Cypher… I’ve been luring/reading these a while… Just wondering, with all the free time you’ve got, when should we (the public) be expecting your bot to be coded, tested, and released?
@heyyon
I’m not writing a public bot…
@Cypher
I think he was trying for sarcasm, but it’s hard to tell with that one.
So, regarding the jump to the middle of an instruction “obfuscation,” as sad as it is, this is pretty much the state of the art in x86 instruction-level obfuscation; this is what most VX devs still use. It’s not intended to completely prevent reversing. The only point of the jump-into-an-instruction thing is to slightly slow down a newbie reverser; because most disassemblers won’t handle this gracefully without a little nudging, it can derail the noob. Anybody with any experience reversing malware will see through it immediately, of course.
I think the Mimic devs — all epeen flexing aside — would be better to focus on defeating the WoW devs, not trying to be “uber hackers.” Make their code metamorphic (obviously, they’re halfway there since they’re looking at VX techniques) and they’ll pretty much make signature-hashing impossible. Don’t try to make the code unreversible (since that will never happen), just try to make it so that *Warden can’t hash against it*, and they’ve won the battle (until Warden is updated to use heuristic scanning in addition to the proven-broken signature scanning).
I tell you, this whole thing is shaping up to be virus writers vs. antivirus companies, all over again, except that the clock has been rolled back to about 1995 or so.
Oh, one correction. I didn’t want to imply that jump-into-instruction is state of the art in VX writing (it’s not, by a long shot). But for the express purposes of slowing down an automated disassembly, it’s about the best you can get without self-encrypting code.
@amadmonk
Hey, nice to see you here!
First things first. Hashing is currently the least of their worries imo. To hash the VH or the Mimic module they’d have to do one of a few things:
1. Manually walk the VH chain using the undocumented structure returned by AddVectoredExceptionHandler.
2. Use Warden’s VEH more aggressively to ‘cock-block’ mimic and intercept the API hooks before mimic does (not hard to do, just keep yourself at the top of the chain).
3. Exploit the hole in their NtQueryVirtualMemory hook.
All three of those require a lot of work (by the Warden dev’s standards of course - one unit of normal ‘work’ for a decent programmer is equal to one hundred units of ‘work’ for the Warden dev).
A much easier (and generic) solution is to sneak in some stack-trace code into functions like FrameScript_Execute (Lua_DoString), GetObjectByGUID, ClickTerrain, etc etc.
You can encrypt your module all you want, but its not gonna save you from a stack trace.
And yeah, the point is though, they’re not facing “newbies”. The Warden guy is lazy, but he’s not stupid. They need to stop wasting their time on security by obscurity, and actually implement some REAL protection.
@Cypherjb
I guess that makes sense. I think that if the Warden guys are at all competent it’s going to come down to plausible deniability (in other words, inter-modular calls are going to be fair game, intra-modular calls are going to be unsafe).
Has anyone explored carving a code-cave out of WoW’s .text segment? Or you could sneak a hook table into the PE header or something unused (just sort of wrap it around the loaded module lists, or something). Just something so that fn calls look like they’re “coming from” (or “going to” a location inside WoW itself). Of course, that would only work until Warden starts hashing every byte of the binary, or even just the particular function you’re hooking…
@Cypherjb
The more I think about it, the more I start to think that Lax’s technique (just counter each individual Warden module as it shows up, and kill the app if an unknown module appears). Then you don’t have to worry about “what if’s,” you can just implement code and fool Warden into saying that the code is good.
Seeing as how we have physical control of the box and access to every bit of binary/net traffic on it, that should work — in theory — even though it’s a lot of work.
er… last comment should be “Lax’s technique is a good one”
Hi, interest post. I’ll write you later about few questions!
No. There was no sarcasm involved. He showed exactly what I suspected: He can criticize the shit out of what they do… but he can actually program no better. If he can program a more secure bot, he’s not the fortitude to sell it as the programers of WowMimic do. In other words… he’s another 18 year old kid without the balls to do a damn’d thing but whine. Cry cry, as you do nothing, boy.
@heyyon
Rofl. Do you even know what ‘fortitude’ means? Because it makes no sense in the context you’re using it in.
Also, it has nothing to do with ‘balls’. I have written public botting tools (I’m a maintainer of the CURRENT ISXWoW, a previous maintainer of OpenBot, previous maintainer of the public model edit fix, creator of various WoW hacking tools and libraries, etc etc). It’s solely to do with legal issues and personal issues.
Programming skill has nothing to do with whether or not I release a bot publicly. I’m an Australian, which puts me in a very tight legal position. If I were to sell a bot I could easily be sued. Mimic are based in China, which is a totally different story.
The irony in your post is delicious. Do you not realize how immature you sound? YOU are the one crying and complaining. I on the other hand am exposing a public bot in the hopes they’ll stop their lies and deceptive business practices.
P.S. If you’re gonna try and call someone out on something it helps if you do your research. I have contributed a LOT of code and software to the WoW hacking community, it’s obvious you’re just another mimic fanboy who’s upset because their precious bot is being attacked.
@amadmonk
You still need to watch the client VERY carefully though. ISXWoWs last banwave was from a client change that hijacked an existing packet to send a key to the client, which in turn was used to decrypt and execute an encrypted code stub used to detect one of ISXWOWs hooks.
@amadmonk
I completely emulate Warden (on the packet level) and do exactly as you said. It really isn’t as simple as you might think. With every update (and patch), you’re required to sit down for hours and check for changes and update various modules of the emulator.
For instance, i need to update all my hashes of client files and memory offsets to return the clean values.
@kynox
Yo dawg, we put wardens in your wardens so you can hack while you hack.
@Cypherjb
Bah. I was sort of thinking about that on the way home from work; how the big weakness of Warden is that it’s a single point of attack. Once they start weaving aspects of its code into other code (like the masquerading attack you mention), things get sticky.
@kynox
Hmm. How many “types of things” do you need to hash? The last I looked at the list of known checks, it was just a dozen or so offsets. I can see how you’d need to stay on top of the changes in Warden, but how often does some IAT entry change?
Actually… thinking about how I’d implement Warden, lemme guess: the key they use to hash with changes dynamically, so that with each update to Warden you have to rehash with the new key.
Bah. Nothing’s easy.
@amadmonk
Very sticky. Last night with Kynox’s sister type sticky.
@amadmonk
Polymorphism in every cranny you can think of.
When i meant updating hashes, i meant all the client files it hashes, all the offsets it checks, etc. In a way, it’s nice having to do it because you end up easily noticing if anything new was added.
@Cypherjb
I was a longtime user of Innerspace and ISXWow. I thought when Lax stopped releasing ISXWarden, the ISXWow project all but vanished? The forums are dead, and one person updated it a month ago, but isn’t safe to use. I asked him. It is too bad really, because I really miss the functionality and universal scripting of the bots, and combat assist routines I made.
From what I can tell, Mimic, even though detectable is the closest thing out there to what I used to be able to do. I am not a programmer, so maybe I am offbase here.
Hmm. Thinking about the “on-the-wire” Warden em. You’d have to keep a man-in-the-middle encryption proxy going, I assume (so you can drop packets or send extra packets). Then you’d intercept the SMSG_WARDEN_DATA packets and send the “clean” CMSG_WARDEN_DATA packets back? Does the hash key/seed/whatever vary dynamically, or only by patch?
It does seem like a lot of work, but it also seems like most of the work is up front; once you know what to hash and what data to use to hash it, you can write a little script or something to re-hash known data (offsets, files, whatever — that was where I was going with the “how many kinds of things do you need to hash” question) when something changes.
I like your technique, a lot. It completely eliminates the need for something like binary self-encryption. It wouldn’t do anything to prevent so-called “cock blocking” (nice term, btw, Cypher) but once you’re not worried about consistency checks you can just block the cock blockers and you’re set.
Hmm… I think it’s time for me to start actively looking at those SMSG_WARDEN_DATA packets (and responses)…
Now, how would you handle the “hijacked opcode” issue… you’d have to have some at least semi-deterministic way of finding out if an opcode received led to the code path that it “should” be running. Otherwise you’d have to distinctly handle every known opcode (and that would be an insanely huge amount of work).
@amadmonk, you should have a look at http://sharesource.org/project/sniffitzt/ ,this programm can intercept and decrypt the wowtraffic and knows how to find the “key” used for encryption.
Might be useful
@amadmonk
You’d pretty much have to store some basic info on every single packet.