Jump to content

An insight on M2Bob and Overall DECENT Anti-Cheat Protection Measures

Recommended Posts

Hello guys.

I'm Narvikz, I've been in the Metin2 scene since forever, actually I feel like I'm kind of the furniture already and unluckily full of dust by now

This will actually be one of the slight amount of contributes I've given to metin2dev, I've jumped off ship a while back since this game died but apparently some troll still support it, anyway that's not related to this thread so let's keep it out of here.


As there's still demand for some reason so is there a supply of game hacks, it's the basics of games, the more players there are the bigger the market for payhax and so the more profitable they are.


I was contacted by a friend of mine (Runah Services) which told me that he wasn't unable to detect m2bob in any way, he also said that there are very few people who are doing it and those who are able to detect were keeping it private, he did not find anyone providing a satisfactory service to protect against these tools.


What I have to say about this?

You fools, you clueless fools.


So, let's face it, you guys just don't have a clue about what you are doing.


Right off the bat I could enumerate dozens of ways to systematically detect that m2bob is running on some system and think of its basic architecture.



But first, let's talk about its architecture and how we can defeat it.



M2Bob - Patcher.exe:

This is the start up process when you first start using M2bob, this will generate a 128-bit Digest (probably md5) for each file that is to be checked on disk, send it through a POST HTML request to an API that will compare the client side files to the server side up-to-date files, if any file's digest is any different it will download the most up to date file using the HTTP protocol and replace it at disk.

This patcher will connect to a web server hosted at the subdomain ni220471_1.vweb02.nitrado.net and as you can see in the spoiler, little reservations has Slait as to what's hosted there.






Once everything is updated it will open M2Bob.exe which we'll talk about next.



This file when opened from outside the Program Files will create a randomly named (yet with constant size - 10 characters) folder inside of the Program Files folder of your computer and then another one with the same template. After that it will spawn a copy of itself with a random name (yet same size once again) and do the same for the M2Bob_Dll.dll changing its extension to ".e" instead of "dll".

After that it will open that randomly named executable and execute from there.

Once you press the button to start the game it will spawn a metin2client instance, it will inject its module into the process memory.

After that it doesn't close the open HANDLE to the game which leaves us a HUGE detection vector to take advantage of.



This module once injected into metin2client will run a few Signature Scans to find the game's subroutines it needs to call in order to simulate game actions. If you take a look into the module's memory you can see those patterns and its masks quite easily, this uses a standard FindPattern function that's been around since the very start of the cheating scene.

It will then automate the actions of the player using complex algorithms which are not relevant for what we care about.

Security wise all M2Bob does is hooking Module32Next and whenever at your iteration through the module list you hit the m2bob random named module it jumps it to the next one, successfully hiding its module from the simplest of all module enumeration techniques. Good job Slait, always work for the minimal standards and do not think out of the box ;)

The hooking method used is the BIGGEST PILE OF CRAP I'VE EVER SEEN being done on a Windows NT based Operative System

This is still a detour with a trampoline hook at function start but instead of replacing the first 5 bytes with a JMP + 32 bit absolute memory address he does THE MOST RETARDED SHIT I'VE SEEN IN A WHILE. Trust me guys, I've seen so much retarded shit lately, but Slait takes the crown on this one, he really deserves it since he's put a lot of effort into this.

Instead of copying the first five bytes of this function, replacing it by a simple JMP to a memory region where it has these first five bytes followed by his detour function and then a trampoline JMP back to where it all started, he managed to do a 8 FUCKING BYTE LONG in-line hook, when literally every Windows API function is compatible with Hotpatching (easy first 5 bytes hooks).


System Overview

The whole system is really weak, it circumvents the protection mechanisms that is supposed to which are a PILE OF CRAP like Hackshield and GameGuard or whatever the fuck GameForge is using nowadays, but it doesn't really think out of the box when it comes to protection and obfuscation. Slait wouldn't stand a chance if GameForge purchased an actual decent service from someone who has a single clue about what they're doing (lol, even fucking Bastian Suter would perform better) instead of this pile of crap.

There's no solid DRM and the system is overall really weak and shouldn't take much longer than a few hours to crack to a talented reverse engineer.


Detection Vectors

Well, I don't even know where to start, the whole system is flawed and weak, there's holes everywhere so I'll enumerate some quick detection vectors I can think off, and yes, I HAVE TESTED MOST OF THOSE AND THEY WORK


Method #1 - Hidden Memory Pages (TESTED & WORKING)

Iterate through memory pages and using VirtualQuery find those which are 4096 byte long (size of the PE Header) and being used, for those check if you can get a DOS MZ executable signature, and if you do then you most probably have a PE Header memory page.

Interpret cast that memory address to NT Header and check the TimeDateStamp and or SizeOfCode or other parameters that are constant (there's tons of them) and allow you to uniquely identify m2bob.

Method #2 - Open HANDLEs to game process (TESTED & WORKING)

You're gonna have to use the Native API and some Undocumented structures and functions to get this done, it's really easy to do so though, shouldn't take you longer than an hour to being able to enumerate all you need to do this.

Calling NtQuerySystemInformation with SystemHandleInformation as first parameter while the return value of this function is different than STATUS_INFO_LENGTH_MISMATCH or STATUS_BUFFER_OVERFLOW you are able to populate a SYSTEM_HANDLE_INFORMATION object which will have the first 4 bytes as the count of SYSTEM_HANDLE objects present in an array that follows it.

This list once populated will contain a list that contains all the HANDLEs opened in your environment, this means all the File, Registry Keys, Processes, Threads, etc, HANDLEs will be enumerated and will be in that list.

But to know the type of HANDLE you're dealing with you have to first call QueryObject on that HANDLE with ObjectTypeInformation to know more about it. This will get you a UNICODE string that will contain the HANDLE type, you only want the ones that are "Process" so you can filter the irrelevant ones out.

Then you can check if the HANDLE is targeting your game's process id (you can get your process id at the PEB of your process), if it is you're gonna want to run some checks on that process to check whether if it's a legit one or a blacklisted one.

You can do this by opening a HANDLE to it with OpenProcess and PROCESS_QUERY_LIMITED_INFORMATION as parameter.

Then you're gonna want to get the executable path in disk using QueryFullProcessImageName, from there you can just read the first 4096 bytes of that file, cast them to NT Header and do the same checks as mentioned above.

Alternatively you could just open the handle with PROCESS_VM_READ privileges, and use ReadProcessMemory to get the PE Header, but PROCESS_QUERY_LIMITED_INFORMATION never fails, even if the process is run as administrator or it is a system process and since m2bob doesn't use any Dynamic Forking technique it is pointless to use anything more than that.


Method #3 - Integrity checks at Module32Next (TESTED & WORKING)

Okay, this might sound retarded because there's malware that will spread to every process in the target system and hide itself using a user-mode rootkit that might hook Module32Next, thing is, Slait's kind of hooking is so retarded there is no actual way this would raise a false positive.

This is his retarded hook:


The 1st byte will always be FF, the 2nd will always be 25, the 7th will always be E4 and the 8th stays at a constant F8 as well.

Check those and insert a huge dildo in Slait's ass, seriously, isn't that hard really.


bool isM2BobRunning()
    HMODULE hKernel32 = GetModuleHandle("Kernel32.dll");
    DWORD dwModule32Next = (DWORD)GetProcAddress(hKernel32, "Module32Next");
    if (*(BYTE *)(dwModule32Next) == 0xFF &&
        *(BYTE *)(dwModule32Next + 1) == 0x25 &&
        *(BYTE *)(dwModule32Next + 5) == 0xE4 &&
        *(BYTE *)(dwModule32Next + 6) == 0xF8
        return true;
    return false;


Do you think that's even hard? Please......


Method #4 - DNS Cache (Untested But Will Work)

So, now we're jumping to the shitty methods that are only here to fill the thread just so you can be proven wrong when you say it can't be done.

Basically whenever you resolve a domain name a UDP request is sent to your DNS Server asking for the resolution of a certain domain or subdomain, it will answer with some records for that domain, these records contain the IP Address it resolves to, and that IP address will be the one you'll connect using the Internet Protocol version 4.

Your operative system will cache those resolutions so that each time you need to have that domain solved it doesn't bother your DNS Server with requests each time and there is a faster resolution, you can use this to beat M2Bob once again.

You don't wanna look for m2bob.net since that could flag players that just crawled around that website, but if you flag their patch server subdomain, you can actually accurately flag players that have been using m2bob.

Remember ni220471_1.vweb02.nitrado.net?

Yup, flag the shit out of it.

Method #5 - USN Journal (Untested But Will Work)

The USN Journal is a system in the NTFS that keeps track of changes to files in the user's system.

It will contain the timestamp of the said change, the file name and the reason for the log. The first two need no explanation, as to the third it could range from Opening the file, deleting, moving, renaming, creating, etc, etc.

How's this useful?

Remember how opening M2Bob.exe spawns a different executable in the Program Files folder and opens it? Well, you don't access that executable directly, you still open M2Bob.exe, this means that you could just look for entries in the USN Journal in the last 15 minutes or so that contain the name M2Bob.exe and are followed by some program in the Program Files folder a few milliseconds after (or even skip the latter) that has been opened and just kick the player from the game whenever you detect it.


Aditional Methods

Detection Vectors, detection vectors everywhere, I laugh at all the incompetents that for months tried to do it and failed systematically, you fools, how can you be so clueless?

  • Even though Module32Next is hooked Module32NextW is not, which means that if you use the UNICODE alternative of the kernel32 library you will get unfiltered results - Good fucking job Slait, Incompetence at its fittest (inb4 every incompetent out there edits a public anti cheat source to use Module32NextW LOL)
  • Haven't checked it, but even though Windows API module enumeration modules are hooked to spoof the results, you should be able to use the InInitializationOrderModuleList, InLoadOrderModuleList or the InMemoryOrderModuleList to find its module.
  • Just be h4rdc0r3 and use Syscalls. Since you're incompetent you won't do this, hell you couldn't even get the indexes for your own operative system version let alone do it for 20 different versions per each function you wanna call. Anyway just implement the native API functions without actually calling them, this can be done really easy and WITH LITTLE INLINE ASM CODE using naked hooks, that will make sure that you don't break the stack inside of the function. You can look into this HERE. Your function call will be done within the kernel, meaning that this would bypass any placed hooks by Slait.
  • Why the hell would your metin2 game process own 2 windows bruh? Doesn't make sense to me, just kick them dude.
  • Signature Scans, this is pointless because his system is all flawed but could be a nice backup resort if he ever decides to use his brain.
  • Pretty sure m2bob has some exported shit in their PE Header, just scan for it using the hidden PE Header detection shown above.


As I'm really fucking tired already of writing a long ass thread incomparable to anything ever seen before here or anywhere released publicly online I won't even write down any more detection vectors, the system is filled with holes, I think I've proven my point already and it's pointless to keep doing this.


This is a rant thread because you guys that own a metin2 server to make a quick buck should be ashamed of how unskilled you actually are, you are complete incompetents that keep leeching public releases and stealing other people's/servers' work, claiming it as your own or often not even mentioning it since people just don't even care any more.


You provide public PAID services on an area you don't have a clue about, you're just scamming customers and selling them dreams.


It is really frustrating for me since I left the scene when I was still a kid, I barely knew English and I stayed mostly on my local country's forums, my contributes back then were merely in the translation area, I've put a lot of effort into it now that I think about it, after that I limited my contributes to helping people with general Linux/BSD issues, but then it seemed that owning a Metin2 Private Servers built with pieces and pieces of stolen or leaked work was a trend, and I got really really pissed at the whole scene, I just started trolling all the retards asking for assistance with BSD issues that are from 101 classes, obvious errors that even my grandfather could solve and other retarded threads.

Have Fun guys, I know most of you won't use this for anything since even being spoonfed all the methods you're so clueless you can't write this down on code, but maybe there's some one out there that will actually use some nice tips like this, and since I gave them to one guy privately on skype I might as well post them publicly for everyone to see.


I've been contacted by SandMann016 to work with him, and to be honest it kind of makes me sad that I am releasing this, I never managed to proceed with those plans but still, he seemed to be a decent guy back when I first met him, but oh well, here it is now.


  • Love 28

Share this post

Link to post

Haha, thanks for this topic, didn't laugh so much for quite long :D Finally, someone who knows something about RE :)

* The moment when you're re-thinking your life, why the fuck am I trying to develop self-healing & advanced anticheat-system with advanced syscall emulation & others :( *

Share this post

Link to post
14 hours ago, sandmann016 said:

Hey dude,

don't be sad about it.

I'm no longer involved in that project as one of the main developers,

the last action should be about one year ago.

By the way, some of this "retarded shit" is grown on my handle .

What a shame that we lost contact, but everything is fine.

Until now i hired three employees and the development is running fine.

Hope your business is running fine, too.

To be honest at the time we talked I wasn't even remotely capable of doing anything remotely close to what I am now, 2-3 years passed I think?

Glad to see it's all going well with your business, mine's had better days honestly, there were months where I could easily hit 5K€ back then, now I'm banking none lol, but hey no worries, I'm rethinking on another approach on my projects.

13 hours ago, Unc3nZureD said:

Haha, thanks for this topic, didn't laugh so much for quite long :D Finally, someone who knows something about RE :)

* The moment when you're re-thinking your life, why the fuck am I trying to develop self-healing & advanced anticheat-system with advanced syscall emulation & others :( *

You're welcome, I mean, the dude clearly circumvents the piece of bloatware this is meant to primarily work on, but he could've think out of the box and went way further than that, his system is so flawed.


Using syscalls for this kind of stuff isn't hard, what's hard is actually getting all the indexes you need to work on all the operative systems you want it to work for, this means easily > 20 indexes for each system function you want to call.


There's information online already with the indexes for operative systems ranging from Windows XP to Windows 8, however there's stuff clearly missing there like the Windows Server 2003 R2, Windows Server 2008 R2, Windows 8.1, Windows Server 2012 R2, Windows 10 and Windows Server 2016, you gotta do your homework for those.

You can check a public table here: x86  |  x86-x64

It's relatively easy to implement them though, you can even do wrappers quite easily if you don't have prologue/epilogue on your function using the naked keyword.



The patcher files are now located at this subdomain: ni871050_1.vweb02.nitrado.net


Obviously Slait's been lurking around and seen this, now there's no public list of files available but the harm that there was to be done was already done by now, I guess it's pointless to just change your subdomain now isn't it Slait?

  • Love 1

Share this post

Link to post

Man I've had LOTS of fun reading this. It's been a long time since I read big ass posts like this one, but I can sure tell it wasn't boring at all.

The main thing that made me smile is that you've been able to provide a form of tutorial without actually giving a spoonfed result.

That's right kids, I've been told to RTFM way too many times. Next on that list is the fact that you actually provided a way of blocking a big pile of shit "bloatware" that exploits the weaknesses of a program but isn't even capable of dealing with its own issues.

Secondly, I've still enjoyed reading this long ass thread because of the complexity of the things explained in detail and with simple words.


In conclusion, even after years (sorry for being late) I still find this thread awesome and want to thank you for the fun I had reading this, adding to that, the useful information provided. Have a nice day, mate.

  • Love 2

Share this post

Link to post

New domain for patch files : zap391342-1.plesk06.zap-webspace.com/o/Patch/

Download M2Bob.exe from zap391342-1.plesk06.zap-webspace.com/o/Patch/M2Bob.exe

Share this post

Link to post

Only one word for you @Narvikz  "a big thank you" you can even imagine how glad am i now :D I hope is everything good with you family and friends man during this COVID thing.. Once again appreciate you time and this lesson was really helpful !  PS: Sorry for my bad English!  

Share this post

Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.