Register at our server: https://igroglaz.com/en/rom2
Join our discord: https://discord.gg/5tW79kb
In this guide by NOVA you will find an explanation how RoM2 community works on the game.
So you want to disable the GM Hack cheating on your HAT, eh?
Ok, let’s examine how we figure out where/how this mode is turned ON and then maybe we can figure out how to turn it OFF.
ALWAYS make a backup of any file BEFORE editing it.
Using W32Dasm, get a disassembly listing of your rom2server.exe program file. Now click on the Strn Ref icon (it’s just left of the printer icon along the top row, I’ve circled it below). This will bring up all the string references used within the rom2server.exe program. Scroll down slowly from the top just a little bit and you will find an interesting one called,
” enable cheating.”
This is indeed interesting. Double click on this “ enable cheating.” text which will take you to the lines of program code that call this string reference and then close the Strn Ref window to get it out of the way. You will see the following code listing. Below is an annotated and marked-up screen shot of my code listing when I double clicked “ enable cheating.” I will explain what all this gibberish means. But let’s start with the code listing itself:
Starting from the red “ enable cheating.” StringData Ref near the bottom, refer to my notes in purple along the right side. We’re going to work backward through program execution trying to find out where the program decides that the player IS authorized to turn on the cheat mode and thus gets the on screen message “ enable cheating”. If we can find the program spot where the decision is made to turn ON the cheat mode, perhaps we can find a way to STOP it from being turned on. We’re working from the bottom upward because we are tracing backward through program execution starting from the point where the player is told that cheating has been successfully enabled.
All the code block directly above the string reference is the part that leads up to informing the player that “cheat has been enabled”. So the starting line of code for successfully turning on the cheat mode is virtual address 005031CB (the line highlighted in light blue). Just above this, WDasm informs us that there are two possible conditional jump sources for how we could have gotten here: 0050318F & 005031B5. So as my notes alongside the code indicate, let’s start with the 2nd (and thus nearest one when working backward) and see how that route could have gotten us to this cheat enabled code. It turns out to be VERY near indeed….just a few lines above in fact. That jump is the following code:
005031B5 7414 je 005031CB
So let’s examine the handful of code lines right above this jump, shall we? It will tell us why we are jumping to the cheat enabled section. Following is the assembly code which is there along with my brief explanation for what is happening on each line:
Mov eax, dword ptr [ebp+FFFFE00] | this line is moving stored data into CPU register eax |
cmp dword ptr [eax], F6D04773 | this line is comparing eax register against hex number “F6D04773” |
jne 005031B7 | jump to address 005031B7 if not equal |
mov ecx, dword ptr [ebp+FFFFFE00] | this line is moving stored data into CPU register ecx |
cmp dword ptr [ecx+04], 00000004 | this line is comparing the value in ecx register against hex number “00000004” |
je 005031CB | the player IS authorized to enable the cheat mode, so jump to the cheat code |
So what exactly is happening here? Well, it appears that two numbers are being read into CPU registers (EAX and then ECX) and they are then being compared against two hard coded values. Depending if each of those comparisons show an exact match or not, program execution jumps conditionally based upon the outcome of those comparisons.
The program is in fact reading two values from the player’s character file one at a time and placing each value into a different CPU register for comparison against a hard-coded value. These hard-coded values turn out to be the passkeys needed for your character to be authorized to turn on the cheat mode. The program checks the first value against the first correct passkey. If the player passes this first comparison (in other words they have the correct cheat code passkey, which apparently is F6D04773), then the comparison WILL be equal [TRUE]. This means the JNE comparison will fail so the program simply continues on with the next line of code….which checks the second passkey. If they get this 2nd passkey correct as well (which apparently is 00000004), then the program jumps to execute enabling the cheat mode and informs the player.
So notice that if the player fails the first comparison (meaning the comparison was NOT EQUAL), the program execution jumps AWAY to the code at virtual address 005031B7 (which continues on with game play as normal and does NOT wind up getting to the cheat enabled code). This means they did NOT have the correct first passkey in order to turn on the cheat mode.
SO at this point can you think of any ideas for how we could disable the cheat mode entirely?
How about if we simply had the program act as though the player FAILED this first passkey check all the time (even if the player actually has the right passkey)? So, instead of “jne” (jump if not equal), let’s have program execution just “jmp” (jump all the time) no matter what. That would be a really simple way to totally prevent ANYONE from ever turning on the cheat mode because the passkeys would literally become irrelevant. The code for cheating still exists inside the rom2server program (we haven’t removed that). But program execution would just never be able to get there. It would now be DEAD CODE.
So now that we have an idea for how to do this in principle. We just need to convert this logical idea into the proper Intel 8086 CPU Op codes.
Notice the line where the jne jump actually happens is as follows:
005031A9 750C jne 005031B7
The “75” which I highlighted is the Intel Op code for telling the CPU to process the (jump short) statement “jne” and 0C is the short distance (in hexadecimal) for how far program execution jumps. So, as an assembly code side track…..how does the computer know that 0C means to jump to virtual address 005031B7? Well, since we’re processing this line of code, the next line (where the CPU pointer is currently at) would be 005031AB (the line right below 005031A9). To that we add the 0C (use a HEXIDECIMAL calculator if it helps). That adds up to be 005031B7…..which is where program execution jumps to.
So back to our original mission…..If we want to change “jne” into “jmp”, what is the Intel 8086 CPU Op code for jmp? That turns out to be “EB” (you can find that if you search the internet for Intel 8086 Op codes or get any reference book on Intel CPU Op codes).
So what we really want to do after all this searching around turns out to be rather simple. We just need to change that “75” into “EB” and we will have changed the “jne” into “jmp” which will mean the passkeys will become totally irrelevant and the cheat mode can NEVER be enabled…..ever. And we want to do this at virtual address: 005031A9 (where that 75 is at).
Ok, so how do we do that?
Well, this disassembly listing is using Virtual Addresses to simulate memory addresses as they would appear in RAM if you were actually running the rom2server.exe program. But in order to make a file edit, we need to hex edit the raw executable file not virtual memory. So what we need to know is the file Offset Address (“offset” is simply how far from the beginning of the rom2server file the data in question is located). So we have to convert this virtual address 005031A9 into an offset address in the rom2server.exe file. How do we do that?
Here is the formula for doing that:
Offset address = Virtual address – ImageBase – text relative virtual offset (RVA) + raw offset
But all we have so far is the Virtual address (005031A9). How do we find all those other values? It’s really pretty simple. W32Dasm tells us all of them if we know where to look. They are listed at the very top of the W32Dasm listing as follows:
So, now we have:
Imagebase = 400000
Text Relative Virtual Address (RVA) = 1000
Text raw offset = 400
So after all this, what is the actual offset where we must make this change using a hex editor?
Offset address = Virtual address – ImageBase – text relative virtual offset + raw offset
= 005031A9 – 400000 – 1000 + 400 (use a hex calculator to figure this total)
= 1025A9
So we need to use a hex editor program (any will do) and find offset 001025A9 in the rom2server.exe file At that offset we will find “75” is already there. We just need to change that to “EB”…..and then save the file.
So here’s the simple little tidbit of information we were after this whole time, using the same convention Exlend uses for his HackIt patch info:
001025A9 75 EB
Congratulations, you have just modified your rom2server.exe file so that NO ONE (not even you) can ever turn the cheat mode on because even if the character does have both correct passkeys and IS thus authorized to turn CHEATS on, the rom2server program will act like they were NOT authorized and will jump away from the cheat program code no matter what.
It’s pretty insane how simple that turned out to be once you knew how to find all the right information and came up with a plan for how to alter program execution to your new intentions (i.e. totally disabling the cheat mode).
BUT HOW COULD YOU ENSURE THAT ONLY YOU HAVE ADMIN CHARACTER’S ON YOUR HAT?
So let’s take this exercise a bit further. Let’s say you don’t want to totally disable the ability to turn cheat mode on. YOU still want to be able to turn the cheat mode on yourself (for instance you wish to have admin capabilities using an admin character from within the game) but of course you don’t want just anyone to be able to activate the powers of the cheat mode. Well, the stock out-of-the-box rom2server.exe file comes with the two passkey values hard-coded as shown above. So anyone who is savvy enough to dig out those passkeys from their own copy of rom2server.exe will now know those passkeys for YOUR HAT too (because they’re all the same). Granted, just having these passkey numbers is not enough. The player still has to know how to inject them into their character in the game. But that CAN be done and there are several ways to do it. Let’s not worry about HOW you could do that. Instead, let’s focus on how to retain the ability to turn the cheat mode ON, but modify the program somehow so only YOU are able to do it.
Since the rom2server.exe file is used ONLY server side to start each map on your HAT, you could edit YOUR rom2server.exe to change the value of these two stock passkeys and then no one (except those people you tell) will know your brand new unique passkey values. And we already know what both of those stock passkeys are and where they are located in the program because we have our disassembled program listing when we were searching for the “enable cheating” code within rom2server.exe (see above) and here they are:
005031A3 cmp dword ptr [eax], F6D04773
first passkey is F6D04773
, located at virtual address 005031A3
005031B1 cmp dword ptr [ecx+04], 00000004
second passkey is 00000004
, located at virtual address 005031B1
So, using the same formula that we used to determine the offsett address for the jne to jmp change, we can convert these virtual addresses where the passkeys are hard-coded into offset values (i.e. the program code locations) as well. And then at those offsets, we can simply change one or both of the stock passkey numbers to whatever new numbers we want them to be.
IMPORTANT NOTE: Be careful when altering the 2nd passkey. It is currently just one byte pair in length and all the preceding zeroes are truncated (because of Intel’s Little-endian byte pair ordering) and thus dropped from the value within the rom2server.exe hex code. Because machine code utterly relies upon all code and data being in exact offset locations in order to jump to the right spot, we cannot change the size (length) of this 2nd passkey. It HAS to remain exactly 1 byte pair in length or we would wind up pushing all the code/data that comes after it to higher offset values and it would utterly corrupt the entire rom2server.exe program. So, unless you intend to go on a grand mission to find and properly adjust EVERY single reference and jump throughout the entire rom2server.exe file to offset locations that come after this 2nd passkey, I suggest you stick with the 2nd passkey being just one byte pair in length. You can still change that one byte pair to any new value you wish….just keep your new value as just one byte pair in size.
So use your favorite hex editor once again, this time to alter the authorization passkeys to whatever values you wish. And remember to keep an unmodified backup copy of your rom2server.exe file just in case something goes wrong. You did remember to change the “EB” back to “75” so the cheat mode can even be reached, didn’t you???
Now, having changed one or both of these passkeys to new values, you need to be sure that only YOUR characters are created with these proper new passkey values. But how exactly are these two values assigned to every ROM2 character at the time of that character’s creation? Fairly simply, really. In the solo game, every character is hard-coded to be created with the proper stock passkeys by default. This means that every character you ever make in solo play is already authorized by default to turn on the cheat mode. To prevent this in multiplayer (or HAT) mode, the rom2.exe (client) program takes a snapshot of your CPU clock and CPU date to effectively generate two random numbers the instant you hit the create new character button. These two random numbers are then assigned to your new character file as your first and second passkeys. This completed character file (with your now randomly generated passkeys) is sent to the HAT server as soon as you hit the final OK button so that your new character can be added to your login account. The chances of both passkeys randomly generating the exact hard-coded stock values inside the rom2server.exe file (though technically possible) is so remote as to be essentially impossible. But nothing is stopping you from fiddling with things to ensure your character does have the right passkeys.
You have several options to give your admin character the proper new (or old if you never changed them) passkeys that you just hard coded into your rom2server.exe file so that you authorize your multiplayer or HAT character(s) to turn on the cheat mode on your server.
You can hex edit your rom2.exe (client) program to replace all the code that takes a time and date stamp and instead hard code the new passkey values. This way ALL the multiplayer or HAT characters you ever create will have your unique passkeys hard-coded (similar to how all solo characters get the out-of-the-box hard coded passkeys).
You can use a process editor if you know how to find the exact RAM location of these two passkey values. You will replace the random values currently there with your new authorization passkeys before you submit this newly generated character to the HAT program.
(probably the best option) Since you have access to the server side (after all you are the HAT admin, right) you can ignore all this fancy character generation client-side stuff (rom2.exe) and instead just create your character normally and let it get added to your HAT login account with the randomly determined passkeys. Then using Exlend’s excellent charedit utility, you can view your character inside your account and simply change the character’s passkeys to your new unique ones you set in rom2server.exe and resave your login account. Now this character has your new passkeys.
Good gaming!
– NOVA