- Joined
- Oct 25, 2008
- Messages
- 225
- Reaction score
- 319
Occasionally I find myself bored and in unpacking mood. I've also seemingly rediscovered a fondness for old MapleStory versions, so I figured why not combine the two and help out the community. Is there a particular version you've always wanted a proper client for? Request it here!
Rules:
* I can only make localhosts for versions <= GMS v111 (or equivalents for other maple regions - ca. 2012). This is because VMProtect - and later on newer Themida VM models - cannot be unvirtualized as perfectly as the old CISC-2.
* There must be full game files available (e.g. on msdl, or provided by yourself) for the version you're requesting.
You'll get a fully unprotected single exe binary file that can simply be dropped into the game folder and should run without further complications (compatibility mode settings may be required for old versions on modern Windows). All my binaries are optimized for low file size and performance (in terms of disabling security checks official clients do).
Completed works:
GMS v28 (Aug 2006):
GMS v48 (Dec 2007):
GMS v53 (Mar 2008):
GMS v62 (Nov 2008):
GMS v62 4GB:
GMS v68 (Apr 2009):
GMS v68 4GB:
GMS v83.1 (Feb 2010):
GMS v83.1 4GB:
GMS v87.1 (Jun 2010):
GMS v87.1 4GB:
GMS v92.1 (Nov 2010):
GMS v92.1 4GB:
GMS v95.1 (Jan 2011):
GMS v111.1 (May 2012):
EMS v65.1 (Oct 2010):
EMS v76.1 (Oct 2011):
EMS v87.1 (Feb 2013):
BMS v8 (Oct 2008):
BMS v19 (Nov 2009):
TMS v72 (Apr 2008):
TMS v90 (Mar 2009):
JMS v186 (Sep 2010):
VMS v23 (Oct 2008):
THMS v96.1 (Aug 2011):
Note: Unpacked clients can occasionally have false positive AV detections such as "Trojan.Win32/Mapstosteal". That is nothing to worry about and should simply be whitelisted. The signature name is pretty suspicious tbh. I sometimes wonder if Nexon submitted byte sequences to AV vendors in the past to detect unpacked clients, in order to scare people off from playing private servers...
The "4GB" variants are patched to activate the "large address space aware" (LAA) flag in the PE header. This will allow the client to use up to 4 GB of memory instead of only 2. This is required to fix sound on Wine, and on Windows it can also help prevent/lessen the so-called "GFX issues". When in doubt, you should always prefer this variant. In v93+ it is always set because Nexon activated it.
Server engineering notes
Client patching notes
Tooling
Rules:
* I can only make localhosts for versions <= GMS v111 (or equivalents for other maple regions - ca. 2012). This is because VMProtect - and later on newer Themida VM models - cannot be unvirtualized as perfectly as the old CISC-2.
* There must be full game files available (e.g. on msdl, or provided by yourself) for the version you're requesting.
You'll get a fully unprotected single exe binary file that can simply be dropped into the game folder and should run without further complications (compatibility mode settings may be required for old versions on modern Windows). All my binaries are optimized for low file size and performance (in terms of disabling security checks official clients do).
Completed works:
GMS v28 (Aug 2006):
To view the content, you need to sign in or register
GMS v48 (Dec 2007):
To view the content, you need to sign in or register
GMS v53 (Mar 2008):
To view the content, you need to sign in or register
GMS v62 (Nov 2008):
To view the content, you need to sign in or register
GMS v62 4GB:
To view the content, you need to sign in or register
GMS v68 (Apr 2009):
To view the content, you need to sign in or register
GMS v68 4GB:
To view the content, you need to sign in or register
GMS v83.1 (Feb 2010):
To view the content, you need to sign in or register
GMS v83.1 4GB:
To view the content, you need to sign in or register
GMS v87.1 (Jun 2010):
To view the content, you need to sign in or register
GMS v87.1 4GB:
To view the content, you need to sign in or register
GMS v92.1 (Nov 2010):
To view the content, you need to sign in or register
GMS v92.1 4GB:
To view the content, you need to sign in or register
GMS v95.1 (Jan 2011):
To view the content, you need to sign in or register
GMS v111.1 (May 2012):
To view the content, you need to sign in or register
EMS v65.1 (Oct 2010):
To view the content, you need to sign in or register
EMS v76.1 (Oct 2011):
To view the content, you need to sign in or register
EMS v87.1 (Feb 2013):
To view the content, you need to sign in or register
BMS v8 (Oct 2008):
To view the content, you need to sign in or register
BMS v19 (Nov 2009):
To view the content, you need to sign in or register
TMS v72 (Apr 2008):
To view the content, you need to sign in or register
TMS v90 (Mar 2009):
To view the content, you need to sign in or register
JMS v186 (Sep 2010):
To view the content, you need to sign in or register
VMS v23 (Oct 2008):
To view the content, you need to sign in or register
THMS v96.1 (Aug 2011):
To view the content, you need to sign in or register
Note: Unpacked clients can occasionally have false positive AV detections such as "Trojan.Win32/Mapstosteal". That is nothing to worry about and should simply be whitelisted. The signature name is pretty suspicious tbh. I sometimes wonder if Nexon submitted byte sequences to AV vendors in the past to detect unpacked clients, in order to scare people off from playing private servers...
The "4GB" variants are patched to activate the "large address space aware" (LAA) flag in the PE header. This will allow the client to use up to 4 GB of memory instead of only 2. This is required to fix sound on Wine, and on Windows it can also help prevent/lessen the so-called "GFX issues". When in doubt, you should always prefer this variant. In v93+ it is always set because Nexon activated it.
Server engineering notes
GMS v87: In this version, the client will send you XOffset/YOffset shorts after the foothold in absolute movement elements (CMovePath::Encode), but it does not read them back when processing packets from the server (CMovePath:
ecode). This means if your source simply copies packet contents for NPC animation packets, that won't work. You have to parse the packet and then serialize it again the way the client expects it.
GMS v88~v98: These versions had a bug where the melee attack packet contained one more byte at the beginning when hitting a reactor (as opposed to hitting the air or a mob). There's no way to differentiate this other than doing a check such as this:
EMS v87: This version is more or less equivalent to GMS v125. I patched out the login RSA crypto for simplicity's sake. Note that the authentication packet structure is different from GMS regardless; the username and password strings are somewhere in the middle of the packet.
This EMS version requires you to explicitly set the MapLogin img for the login screen by sending 1B 00 08 00 4D 61 70 4C 6F 67 69 6E (this is MapLogin; MapLogin1 also works to show Angelic Buster). A good point to send it would be upon receiving the 0x36 packet (LoginCreated) from the client.
EMS v76: RSA crypto patched out; send 16 00 08 00 4D 61 70 4C 6F 67 69 6E upon receiving 1F 00.
JMS v186: Send packet 18 00 08 00 4D 61 70 4C 6F 67 69 6E when receiving 0x1A (see EMS v87 for explanation).

GMS v88~v98: These versions had a bug where the melee attack packet contained one more byte at the beginning when hitting a reactor (as opposed to hitting the air or a mob). There's no way to differentiate this other than doing a check such as this:
Code:
// Start of attack parsing
lea.readByte(); // current field key
if (type == AttackType.MELEE && lea.available() == 55) {
lea.readByte(); // skip surplus byte when hitting reactor
}
EMS v87: This version is more or less equivalent to GMS v125. I patched out the login RSA crypto for simplicity's sake. Note that the authentication packet structure is different from GMS regardless; the username and password strings are somewhere in the middle of the packet.
This EMS version requires you to explicitly set the MapLogin img for the login screen by sending 1B 00 08 00 4D 61 70 4C 6F 67 69 6E (this is MapLogin; MapLogin1 also works to show Angelic Buster). A good point to send it would be upon receiving the 0x36 packet (LoginCreated) from the client.
EMS v76: RSA crypto patched out; send 16 00 08 00 4D 61 70 4C 6F 67 69 6E upon receiving 1F 00.
JMS v186: Send packet 18 00 08 00 4D 61 70 4C 6F 67 69 6E when receiving 0x1A (see EMS v87 for explanation).
Client patching notes
These are for when you're unpacking a client yourself. Many of these only apply to v67+.
* WinMain: nop ShowStartUpWndModal
* WinMain: jz->jmp for ShowADBalloon code (pretty much at the end of method, above push with small number)
* CWvsApp::CWvsApp: Find mov ecx, ...; mov dword ptr ..., 2; jmp. Higher up in the method, change jnz below ZXString<char>::IsEmpty to jmp <addr of mov ecx>
* CWvsApp::SetUp: Change short jmp at the beginning to long jmp that skips all the crap
* CWvsApp::SetUp: Patch short jz above CSecurityClient::InitModule and ::StartModule to short jmp
* CWvsApp::SetUp: nop MSLoop_Remove (if present, v91+)
* CWvsApp::SetUp: Place another long jmp after CWvsApp::ConnectLogin that skips all the crap (until CreateInstance calls)
* CWvsApp::SetUp: Change short jmp before HShield mutex stuff to long jmp. Jump to push 104h further down the method
* CClientSocket::Connect: Skip IP checks by changing short jmp at beginning of the method to long jmp that goes to the client socket code
* CWvsApp::InitializeInput: Skip crap after CInputSystem::Init, jump to method epilogue
* CWvsApp::Run: After CClientSocket::ManipulatePacket, long jmp to "push 0FFh push 0 push 0"
* CWvsApp::Run: nop call to CSecurityClient::Update while we're at it
* CWvsApp::Run: Below IWzGr2D::RenderFrame (where it does 0-100 rand stuff), place long jmp to push 1; call Sleep way down in the method
* CWvsApp::Run: At the end of the method, there's a call to _free, followed by add esp, 4, followed by a cmp ..., 12h. Skip the free by jmping straight to the cmp.
* CWvsApp::CallUpdate: Near the beginning of the method there's a jle below a test. Change this jle offset to the end of the method where it does some relevant things (GR and ActionMan stuff)
* CActionMan::SweepCache: It has some crap in a virtualized chunk at the top that may be doing more or less shady things depending on your version. Skip it if it looks like it could cause trouble (a couple incs/decs/xors are harmless)
* DR_check: xor eax, eax; ret (33 C0 C3)
* CClientSocket::OnAliveReq: If your version has a virtualized chunk here, skip the entire chunk (short jmp -> long jmp)
* CWvsContext::OnEnterField: Skip virtualized chunk at the top (short jmp -> long jmp). If your version has a check (recognizable by lots of xors) at the end, best to skip that as well by jnz -> jmp
* CLogin::SendCheckPasswordPacket: At the start of the sequence of pushes that contains 0C9h, place a long jmp to further down in the method to the SystemInfo basic block. Do auth patches for encoding the correct strings (user/pw)
* WinMain: nop ShowStartUpWndModal
* WinMain: jz->jmp for ShowADBalloon code (pretty much at the end of method, above push with small number)
* CWvsApp::CWvsApp: Find mov ecx, ...; mov dword ptr ..., 2; jmp. Higher up in the method, change jnz below ZXString<char>::IsEmpty to jmp <addr of mov ecx>
* CWvsApp::SetUp: Change short jmp at the beginning to long jmp that skips all the crap
* CWvsApp::SetUp: Patch short jz above CSecurityClient::InitModule and ::StartModule to short jmp
* CWvsApp::SetUp: nop MSLoop_Remove (if present, v91+)
* CWvsApp::SetUp: Place another long jmp after CWvsApp::ConnectLogin that skips all the crap (until CreateInstance calls)
* CWvsApp::SetUp: Change short jmp before HShield mutex stuff to long jmp. Jump to push 104h further down the method
* CClientSocket::Connect: Skip IP checks by changing short jmp at beginning of the method to long jmp that goes to the client socket code
* CWvsApp::InitializeInput: Skip crap after CInputSystem::Init, jump to method epilogue
* CWvsApp::Run: After CClientSocket::ManipulatePacket, long jmp to "push 0FFh push 0 push 0"
* CWvsApp::Run: nop call to CSecurityClient::Update while we're at it
* CWvsApp::Run: Below IWzGr2D::RenderFrame (where it does 0-100 rand stuff), place long jmp to push 1; call Sleep way down in the method
* CWvsApp::Run: At the end of the method, there's a call to _free, followed by add esp, 4, followed by a cmp ..., 12h. Skip the free by jmping straight to the cmp.
* CWvsApp::CallUpdate: Near the beginning of the method there's a jle below a test. Change this jle offset to the end of the method where it does some relevant things (GR and ActionMan stuff)
* CActionMan::SweepCache: It has some crap in a virtualized chunk at the top that may be doing more or less shady things depending on your version. Skip it if it looks like it could cause trouble (a couple incs/decs/xors are harmless)
* DR_check: xor eax, eax; ret (33 C0 C3)
* CClientSocket::OnAliveReq: If your version has a virtualized chunk here, skip the entire chunk (short jmp -> long jmp)
* CWvsContext::OnEnterField: Skip virtualized chunk at the top (short jmp -> long jmp). If your version has a check (recognizable by lots of xors) at the end, best to skip that as well by jnz -> jmp
* CLogin::SendCheckPasswordPacket: At the start of the sequence of pushes that contains 0C9h, place a long jmp to further down in the method to the SystemInfo basic block. Do auth patches for encoding the correct strings (user/pw)
Tooling
Magicmida:
To view the content, you need to sign in or register
Last edited: