Cont: Detour hooking without GetProcAddress() and VirtualProtect()?

December 28, 2006

It was quite some time since I last blog, since I am really quite busy. Not only did I finished my kernelmode unhooker, I also finished my usermode unhooker.

A few days ago, Uligor suggested that npggnt.des calls GetProcAddress() and VirtualProtect() by directly importing ntdll’s function — NtProtectVirtualMemory() and LdrGetProcedureAddress(). I thought, “Hey how stupid of me to not to think of that?”. The usual kernel32.dll that we import our kernel subsystem functions from, actually re-directs our request to ntdll, and GameGuard is a public software, they are expecting people to attack them for certain. Thus they should be ready for it.

However, things are not like what me and Uligor imagined. I thought in order to defeat npggnt.des, I have to know it well, so I unpacked it, and analysed it.


IAT of unpacked npggnt.des

* Note: Click to enlarge

I viewed the IAT with LordPE, there is no sight of ntdll. This is weird, so I disassemble npggnt.des, so to see wassup in there. I also noticed that npggnt.des have 3 exports.

3 export entries in npggnt.des

After some disassembly, this is what I think they are doing:
1. Inject npggnt.des
2. GameMon calls CreateRemoteThread to call the 3rd export in every running process.
3. The 3rd export hook the functions, and mean while set up a “Hook Table”.
4. It start a thread and return.
5. The thread constantly check for modification to their hook, and overwrite if found.
6. Also check for modification in npggnt.des’s first 0×9000 bytes, if found, notify GameMon through filemapping, and GameMon will close the game.

I guess I am lazy this time, so I just give their “CRC” routine and Hook check routine a “Tick ZF”… And GameGuard’s usermode hook == GameOver.

But how do they do the hooking without calling the functions mentioned in the blog entry topic? I guess I hooked the function incorrectly or they overwrited my hook, LoL!

( Note: I didn’t release where to “Tick ZF” as it is too “anti-leaking” to be left public. )


Arrogant and stubborn — Priceless. MSBot working on GameGuard rev896.

December 23, 2006

I am an arrogant and stubborn person, and being arrogant and stubborn at the wrong time can cost alot…

You might think that finally, this is one blog entry that doesn’t concerns computing. Then you are wrong. I am not going to talk about how I pay the price for being arrogant, instead, I am going to ellaborate on how GameGuard made the mistake, and pay the price.

Let me first explain how GameGuard blocks SendInput. GameGuard use hooking technic, in both usermode and kernelmode. GameGuard detour hook SendInput in usermode, and SSDT hook NtUserSendInput in kernelmode.

MSBot mainly bypass the usermode hook, by using Windows’ NCI ( Native Call Interface ), thus bypassing GameGuard’s usermode detour hook in user32.dll. The kernel-mode hook is somewhat tricky, TiMBuS (Author of MSBot) found out that in GameGuard’s kernel-mode hooks, GameGuard allows maplestory to call NtUserSendInput. Se he injected MSBot’s code in MapleStory.exe’s address space, and viola! It works!

Things are not so good after GameGuard rev8960+, they patched MSBot, by not allowing Maple to pass in its NtUserSendInput hook.

GameGuard prevent their SSDT hook from being unhooked, by repeatly checking that the hook is still there, and overwrite it again if changed. If they detect some entries changed, they will

mov al, 0FEh
out 64h, al

Common sense tells us that we will get a reboot… Nice huh?

Recently, I was reverse engineering GameGuard’s core — dump_wmimmc.sys… and I came across this: ( I commented it.. )
GG checking for their SSDT Hook
This is the first time I seen them thinking for us… Probe if their hook function exist before overwriting to prevent a BSOD… ( Or they are thinking for their customer service I guess… )

Alt_KeSDTST2 is loaded on DriverEntry, with the address of KeServiceDescriptorTableShadow->ServiceTable. It is never again loaded with new value, because GameGuard strongly believes in what it believes.. ( -_-” Duh! ) I have adviced it many times to update their SSDT Service Table pointer to my dummy ServiceTable! ( LoL :P ) But GameGuard is arrogant and stubborn! It refuse to listen to me!

Their arrogance and stubborn comes with a price, I can misuse it to bypass their hooks…
Here’s my plan:
Click to enlarge
Note: Click to enlarge

If GameGuard is so arrogant on the address of ServiceTable base address, we can change it, without them knowing.
So this is what I will do:
1. Allocate KeServiceDescriptorTable->TableSize*sizeof( PVOID ) byte of memory
2. Copy KeServiceDescriptorTable->ServiceTable into the memory
3. Set KeServiceDescriptorTable->ServiceTable to point to the memory.
4. Wait for GameGuard to load, they will hook the memory allocated instead of the real SSDT
5. Restore KeServiceDescriptorTable->ServiceTable with the original address.
6. Do the same to KeServiceDescriptorTableShadow….

And viola! MSBot works again on rev896!!


Lesson Learned: Don’t use outdated software

December 22, 2006

Actually there’s another episode behind the KeygenMe blog entry….

It begin, as I am tired of using Visual C++’s inline assembler to code KeygenMe. Thus, I decided that, it’s time for me to code real assembly, and it should be assembled with real assembler! ( not crappy cl.exe… LoL )

As an open source supporter, my first choice is nasm, also known as Netwide Assembler by Peter H. Anvin. I didn’t try GAS (GNU Assembler) because I don’t really like AT&T assembly syntax, I just use it for jokes.. ( not funny :P ) At the end, I didn’t use nasm as nasm is not really suited to Windows, I would definatly use nasm on Linux. With nasm, most APIs are not supported, and it doesn’t even come with a linker! ( On windows, of course… )

My next try would be something that is designed for Windows. So that’s either masm, also known as Microsoft Macro Assembler, or tasm, also know as Turbo Assembler, by Inprise/Borland. I don’t have masm with me, or rather, it comes with Windows XP Driver Development Kit, and doesn’t have complete support for all the usual user mode calls like printf, VirtualAlloc.. etc

Turbo Assembler comes with Borland Developer Studio, and the path is already set up, so I gave tasm a try. In fact, I gave it more than a try, I downloaded many sample code and read them. I also read many tutorials. The KeygenMe in my previous blog entry is assembeld with Turbo Assembler.

However, there’s an unexpected problem, after uploading it. Xentar messaged me that the file is missing one critical DLL — cc3270.dll. I instantly know that it’s a borland DLL. After some googling, I found out that I used the RTL .lib (cw32i.dll), instead, I should use the static .lib (cw32.lib) to link my KeygenMe. I happily modified my makefile and assembled it again, then uploaded it. I reckon that there’s not going to be anymore trouble…

However, the trouble is not over yet, after uploading it, I tried it myself. My KeygenMe terminated immediately after running. Something is very wrong. As it is late, I have no choice but to sleep first and solve the problem tomorrow. I uploaded the old KeygenMe with cc3270.dll from my system32/

The next day, after a whole morning of debugging with OllyDbg…

I found out that the stream is not initialize. with the static build. Unfortunately, the cw32.lib’s routine isn’t documented, I have no choice but to give up.

The main problem I have with Turbo Assembler is that:
- Many routines undocumented
- New Windows NT APIs are not completely supported
- Not much tutorial ( comparing to masm )
- Not much sample codes ( comparing to masm )

All this, is because Turbo Pascal is no longer supported by Borland, and they are not releasing new assemblers. This taught me a lesson, don’t use obsolete software.

Another conclusion about assembly programming:
Use gas if you want to be called a nerd. Just kidding :P ( LoL, brian )
Use gas if you need to be compatible with gcc, or you are working with Linux Kernel….
Use tasm if it’s year 2000 now.
Use nasm if you are with any POSIX system.
Use masm, if the above doesn’t fit….

You can expect my next KeygenMe to be assembled with masm. :D


Time for some cracking!

December 20, 2006

I guess I need a break from that intense reverse engineering of Windows operating system and fighting over the right to overwrite some piece of memory… So I redirected my attention to cracking ( Isn’t that reverse engineering as well? Perhaps I am a bit blur today… )

Instead of finding something to crack, I write something for others to crack!

Normally it works like this. Someone write an application, that will take some serial or username as input, then determine if you are correct. Then what you have to do, is to find out how the serial is verified and write a keygen for it, or if the rules permit, patch the application.

Previously I did write an KeygenMe also, in fact more difficult than the following. But that’s purely in Visual C++’s inline assembly. Oh my! Abuse of inline assembler!!

So, this time I decided to code it out of real assembly. I used Turbo Assembler this time….

Here’s my KeygenMe:
http://filexoom.com/files/2006/12/20/49476/KeygenMe2-WithDLL.zip
You are to write a keygen for it
No patching please.
Both the number and the serial is 32 bit signed integar.
Difficulty: Beginner.

You can expect me to release the source code of it once you crack it. :D

Note: Thanks to xentar for reminding me that I should include the DLL


Detour hooking without GetProcAddress() and VirtualProtect()?

December 19, 2006

MapleStory is one of my favourite online game. I don’t really play it, I hack it.

Life ain’t good for us game hackers. The game company implemented an Anti-cheating system, called nProtect GameGuard. A nasty fellow, I have been fighting with this anti-cheating software for quite sometime already. It’s a war between us the hackers and the game company.

I decided to deal with GameGuard’s detour hooking mechanism in usermode. They overwrite the first 5 byte of a function with a jmp, and possibly a few byte after that also to prevent us from detouring the hook. Not only do they just overwrite and leave it, like normal rootkit/softwares, they repeatly overwrite it so we cannot patch their hook back, attituded huh?

I thought that is smart ( but offensive, imagine the CPU cycles it would take to do such a thing. ), but I am sure that we hackers are smarter, I guess they will have to use GetProcAddress() to retrieve the addy to the function that they are hooking, and then use VirtualProtect so that they can overwrite the bytes. So I happily set off writing a detour hook that detour GetProcAddress and VirtualProtect….

As a surprise for me, without callling those functions, they are able to access kernel32.dll and user32.dll’ memory, and change them! It’s late now, and I guess I will have to stop here and continue my war against GameGuard, tomorrow perhaps. I am sure I will have pretty much fun with it! ( I will post how they do it, possibly in the next entry! )