Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Road to a Localhost

Skilled Illusionist
Joined
Apr 26, 2015
Messages
302
Reaction score
77
Hi.
I'm trying to create a localhost for BMS v1 from 2008(equivalent to GMS v52), which uses yoda's crypter 1.x / modified packer.
To acomplish this, I started learning how to unpack an packed executable and so far I've got a running client with stolen bytes, IAT, OEP fixed...
Basically what I did was:


  • Find the original entry point(use the ESP trick)
  • Dump the client.
  • Find the stolen bytes using cheat engine and fix it with Olly.
  • Fix minor OEP problems.
  • Fix the import table.
  • Remove game guard.

Tools:


  • ImportREC
  • OllyDbg
  • IDA
  • LordPE
  • PEiD
  • Phantom olly plugin
  • Dump ollyplugin
  • BinDiff IDA Plugin
  • Process Hacker
 
Last edited:
Skilled Illusionist
Joined
Apr 26, 2015
Messages
302
Reaction score
77
Gameguard removed.

Now lets try to skip the AES.
 
Skilled Illusionist
Joined
Apr 26, 2015
Messages
302
Reaction score
77
Good job on your progress so far, no offense but - is there a reason to skip AES?
I think it may be easier than retrieve the key.



I skip AES in my clients cuz I don't feel like handling it server side
@sunnyboy Which function do you skip and how you find it?

I tried to construct an AOB for the AES functions, but failed so far.

Anyways, your v52 PDB was really useful for finding common functions in IDA. BMS v1 is the same as GMS v52.

Have you ever experienced a disconect when clicking on the login button? It's strange because it suddently closes the game with a disconect exception, whichout sending any data to the server.
Editted: I'm so newbye, the disconect problem is just because the key was wrong(of course), had forgot about that the decoder runs first and if the header is invalid, it just closes the connection.



Good job on your progress so far, no offense but - is there a reason to skip AES?
BTW, do you know how can I find the key in ZLZ.DLL?



If someone wants to help to retrieve the keys, here's the setup:
https://mega.nz/#!QB83VCgY!ZAO7np3Wfw7Hi2O6PoP2A2wQ0YJTaTMO09VhRseXlrE
 
Last edited:
Skilled Illusionist
Joined
Apr 26, 2015
Messages
302
Reaction score
77
@Eric
Do you know a method to retrieve the AES key or to disable it?



According to

"The cipher's key length is 256 bits, or 32 bytes. The key was static, until version 118, when Nexon changed it."

No need to disable AES or the key.
had forgot about it
:)
 
Custom Title Activated
Loyal Member
Joined
Mar 14, 2010
Messages
5,363
Reaction score
1,343
@Eric
Do you know a method to retrieve the AES key or to disable it?



According to

"The cipher's key length is 256 bits, or 32 bytes. The key was static, until version 118, when Nexon changed it."

No need to disable AES or the key.
had forgot about it
:)
I figured you knew that but wanted it gone anyway lawl
 
Skilled Illusionist
Joined
Apr 26, 2015
Messages
302
Reaction score
77
I figured you knew that but wanted it gone anyway lawl
LOL, i've had forgotten about this aspect old old clients.
Now there's another problem:

What could cause a problem like this?

You list the available worlds, but when you click on it, nothing happens, the channels available not appears.

My testing serverlist structure:
 
Custom Title Activated
Loyal Member
Joined
Mar 14, 2010
Messages
5,363
Reaction score
1,343
LOL, i've had forgotten about this aspect old old clients.
Now there's another problem:

What could cause a problem like this?

You list the available worlds, but when you click on it, nothing happens, the channels available not appears.

My testing serverlist structure:

Post ida version also, i don't feel like making an idb
 
Skilled Illusionist
Joined
Apr 26, 2015
Messages
302
Reaction score
77
Still cannot find the reason why I cant see the channels when I click in the world.

Any ideas? Eric, sunnyboy
 
Everything is possible~
Loyal Member
Joined
Jan 9, 2008
Messages
818
Reaction score
847
The AES should be the full key, instead of the 'left side' (every first 4 bytes of 16 bytes of the key).
No channels when you click the world? Possibly wrong information in the world packet? screenshot maybe?
 
Skilled Illusionist
Joined
Apr 26, 2015
Messages
302
Reaction score
77
The AES should be the full key, instead of the 'left side' (every first 4 bytes of 16 bytes of the key).
No channels when you click the world? Possibly wrong information in the world packet? screenshot maybe?

Whats the name of the 'world' packet in v95 IDB?

The server list packet seens correct and I can see the first world.
 
Last edited:
Junior Spellweaver
Joined
Apr 30, 2012
Messages
100
Reaction score
40
Whats the name of the 'world' packet in v95 IDB?

The server list packet seens correct and I can see the first world.
It's "OnWorldInformation", you send the total number of channels and a bit of information per channel there. This would be "getServerList" in Odin, so you probably have it correct.
 
Skilled Illusionist
Joined
Apr 26, 2015
Messages
302
Reaction score
77
It's "OnWorldInformation", you send the total number of channels and a bit of information per channel there. This would be "getServerList" in Odin, so you probably have it correct.
By looking at the IDA structure, it seens correct.
No Idea why the channels arent displayed..
 
Custom Title Activated
Loyal Member
Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139
By looking at the IDA structure, it seens correct.
No Idea why the channels arent displayed..

I'd have to of seen the structure and IDB myself to make sure everything was properly name and used throughout each packet, but if you're right about what you're saying and BMS v1 is equivalent to GMS v52 then all structures would be nearly identical to GMS packet structure. I don't believe GMS v52 used Yoda at the time though, but that could also just be a BMS thing. Anyways, could it be possible that something you modified, bypassed, or removed in order to achieve this localhost has caused an issue with loading channels? Nice progress along the way nonetheless.

Also, since you asked me if there was a way to find the AES key, one easy way I found was this: bDefaultAESKeyValue. Since I already have it defined in a constants file it's fast for me to retrieve, but you can find it very easily yourself either online or in some program (even in another PDB itself). The default AES key value defined here unlike the real AES key utilizes every byte in each column per row. Here's the key:
PHP:
public static final byte[] DefaultAESKeyValue = {
    0xC6, 0x50, 0x53, 0xF2,
    0xA8, 0x42, 0x9D, 0x7F,
    0x77, 0x09, 0x1D, 0x26,
    0x42, 0x53, 0x88, 0x7C,
    0x00, 0x40, 0xE0, 0xFD
};

To find AES, all you'll need to identify is CAESCipher::Encrypt which gives a direct offset reference to CAESCipher::UserKey. To identify it using the above key, simply do an AoB search on the first four bytes. Since this is a default with the Cipher Nexon used as implementation, it is the same defaulted value in all client versions since it's entirely unused (this goes far post-bb; even when the AES key changed, Nexon does not VM these subs and thus you may ALWAYS find them through this method). You can do a quick AoB search by doing ALT+B, entering C6 50 53 F2 (first 4 bytes), ticking 'Find all occurences', and search. You'll get one result with it that won't lead you to a function, but instead the offset containing that array. XREF it (just click on the dword and click X) and you'll get two xrefs: CAESCipher::Enc_Init, and CAESCipher::Dec_Init. This will give you your xrefs to all AES encryption/decryption. Nonetheless, you would jump to either one of those two subs and XREF them. The only XREF to AES Enc/Dec Init functions are the CAESCipher::Encrypt/Decrypt functions, and they will include the initialization of the cipher's key schedule. The first parameter within that function will be a dword, and that dword is your UserKey. There you have it though, simple guaranteed way to always find it :). I know you realize the AES key is always the same, but in our emulators the only key stored for the UserKey is the first column byte per row, not the full key. This means that you replace the last 3 bytes with 0x00's, and you won't find that AoB in the client at all. If you wish to remove it (a common thing for very low versions such as this), then that'd be the easiest way imo to find it in IDA.

Good luck with your further progress though! I really want to take the time to master the steps involved to be able to do all this myself as well, just wish I could find the time. :p
 
Moderator
Staff member
Moderator
Joined
Jul 30, 2012
Messages
1,102
Reaction score
432
I don't believe GMS v52 used Yoda at the time though,

GMS started use Themida at v0.56, the same patch that has pirates and a lot of other stuff in the data. Before that they still used Yoda, iirc
 
Everything is possible~
Loyal Member
Joined
Jan 9, 2008
Messages
818
Reaction score
847
PHP:
public static final byte[] DefaultAESKeyValue = {
    0xC6, 0x50, 0x53, 0xF2,
    0xA8, 0x42, 0x9D, 0x7F,
    0x77, 0x09, 0x1D, 0x26,
    0x42, 0x53, 0x88, 0x7C,
    0x00, 0x40, 0xE0, 0xFD
};
Yes, this is the 'key'; however, in MapleStory dev terms its the 'IV', and its only 16 bytes (4x4).
In the V.3 client, only the first 4 bytes are used (memset with either the input key or 0xC65053F2, then memcpy to struct).

I know you realize the AES key is always the same, but in our emulators the only key stored for the UserKey is the first column byte per row, not the full key. This means that you replace the last 3 bytes with 0x00's, and you won't find that AoB in the client at all.
This is because of the error I've previously described (only every first 4 bytes of 16 byte rows are copied).

The encryption should be the same as V.55/v.62: just AES and that maple crypto (igcipher)
 
Back
Top