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!

Windows 8/10 Client Support Fix

Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139
I've now tried adding the delay to the DirectInput8Create call and dinput8.dll does definitely load later on now, just before HID.dll with it having a 2 second delay, but the parameter errors still persist with no improvement. I've also tried larger delays but to no avail. Also using the modified dinput8.dll that you linked Eric

Eric - Windows 8/10 Client Support Fix - RaGEZONE Forums

Yep. See how you got Unknown error? The entire error is solely based on GetModuleFileNameW(hModule, &Filename, 3u) returning false in the dinput8 library. I can't seem to understand closely what's going wrong. I've tried reading every single operation throughout all threads of the MapleStory process, but out of the tens of thousands of calls thrown I couldn't find a unique pattern or reason behind why it fails. So, I looked further into the physical call in the KERNEL32 module.

jXFhez5 - Windows 8/10 Client Support Fix - RaGEZONE Forums


I debugged returned RESULT calls that are thrown by SetLastError and retrieved by GetLastError calls within the DLL and the process, and you'll get BUFFER_OVERFLOW results and stuff. However, the documentation states that it will reduce it to the nSize parameter given (which is 3 in this case). Also, this isn't why the function fails either. It fails because len is invalid (the length of the string).

I tried bypassing the call by jumping over it, nopping it out and all registers that use it, and by just simply modifying the 0x80070057 result to return 0 instead so it always succeeds. It works just fine upon call, but when the parameter WOULD be thrown, the client crashes now (stops responding completely). So, for some reason, the call to getting the file name (even though the file name is never used?) is required and if not called it crashes the client. I stumbled upon this post here: which I thought about. While I was debugging the process, there were several hundred returns of "DELETE_PENDING" and when I removed it and the client crashed, it would constantly spam "ERROR_ACCESS_DENIED". After scrolling down, the person states how it affects Windows 8 but running the application as administrator seems to make the issue(s) go away. However, with and without file tampering and making it run in compatibility of 7 alongside running as admin it would still crash (given it took me at least 30 client runs in order to trigger it). Soo I know the source of the error, but I'm not so sure the cause. We know it's GetModuleFileNameW, and we know it's because the function returns false; we don't know why the function is returning false. We also know that if we hardcode it to always return true even if it fails that it will work when GetModuleFileNameW returns true, but crashes if it doesnt and we say it is a success. Sleeping the current thread allows the OS to finish processing the pending deletion, but even with this in place we STILL crash a lot. If we can understand why the module filename is function in KERNEL32 is failing internally, then we can understand why all of this happens.

What I find interesting as well is that for my v90 client using dinput8 works just fine with modifications and compatibility, but v83 does not. I never seem to manage to trigger it on my v90 spamming it to death but it'll happen several times with v83. I don't understand how this makes a difference because the error is not the client, it's entirely external and deals with WINAPI. But hey, it could just be pure coincidence and everyone else gets it besides myself.

I'll try messing with it some more, but after inspecting it I can't seem to figure out why it's so random, differs upons versions 83 and 90, and why removing the call to fix the error in turn crashes the process entirely instead of continues initializing the direct input. So annoying :(
 

Attachments

You must be registered for see attachments list
Initiate Mage
Joined
Aug 28, 2012
Messages
11
Reaction score
7
Aaanyways, you can try and confirm my theory and see if that's actually the cause or not. Assuming you have the dinpu8.dll checks JMP'd in the clean client already, go to address 009F7A9B in your v83 localhost and modify the instruction to MOV EAX, 0. Save those changes and try it out again, see if it works or not.
I was wondering if you could please tell me the way to do this for a v62 client? I have no idea how to find out myself.
 
Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139
I was wondering if you could please tell me the way to do this for a v62 client? I have no idea how to find out myself.

Well v62 is vmed so it's more annoying to find the physical constant pointer, but you would change address 008276C9 to the same instruction: MOV EAX, 0. However, do note that this is only going to make the client initially run in a Window Mode setting (unless that's all you're looking for).
 
Initiate Mage
Joined
Aug 28, 2012
Messages
11
Reaction score
7
Well v62 is vmed so it's more annoying to find the physical constant pointer, but you would change address 008276C9 to the same instruction: MOV EAX, 0. However, do note that this is only going to make the client initially run in a Window Mode setting (unless that's all you're looking for).
I'm looking to start up the client in window mode, yeah. I tried this but this just makes the client not boot up at all anymore, and get stuck in task manager.
 
Junior Spellweaver
Joined
Apr 30, 2012
Messages
100
Reaction score
40
I'm looking to start up the client in window mode, yeah. I tried this but this just makes the client not boot up at all anymore, and get stuck in task manager.

A temporary alternative is to use DxWnd, but obviously the client modification would be preferred. I haven't downloaded v62 like, ever, so I'm no help for you here.
 
Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139
I'm looking to start up the client in window mode, yeah. I tried this but this just makes the client not boot up at all anymore, and get stuck in task manager.

Oh, oopsies, my bad! That's the wrong address, the actual one you need to change is 008276B2. Also, make sure that when you're modifying this address that you tick "Fill with NOPs" when you're changing the instruction to MOV EAX, 0. Otherwise, it'll create broken and inaccurate instructions in the remaining bytes.

Just to get this out there for anyone who doesn't read the information: If you're looking to enable automatic window-mode in the application, here's the addresses for the common versions that I have:

Code:
v62: 008276B2
v75: 008FC396
v83: 009F7A9B

Also, since CWvsApp is vmed in pretty much every IDB and client, here's how I find it in every version:
1) Go to WinMain and look for a dword value initialized inside of a conditional. It's commonly a pointer offset of +0x14(20).
kmDMCy - Windows 8/10 Client Support Fix - RaGEZONE Forums


2) Rename the dword to TSingleton_CConfig_::ms_pInstance, and then XREF it (right-click, Jump to XREF or click it and press X)
3) Scroll down to the very bottom of the XREFs until you find two xrefs to WinMain.
CTzgECC - Windows 8/10 Client Support Fix - RaGEZONE Forums


4) Directly below WinMain is CWvsApp::SetUp if your client is unvirtualized. If your client is still vmed (to my knowledge, everything besides v75/v90?), then the function below WinMain is CWvsApp::InitializeGr2D. This is the important function you'll need. In this example I'm using a clean unpacked v75 that's still vmed, so this means right below it is InitializeGr2D.

g125JQK - Windows 8/10 Client Support Fix - RaGEZONE Forums


5) Now go to that sub/click OK. The pointer should be 99% of the time the very first variable. The way you tell that it's InitializeGr2D is if right below the DWORD constant is a StringPool instance:

s9JwhHL - Windows 8/10 Client Support Fix - RaGEZONE Forums


Once you've confirmed that it's InitializeGr2D, rename the function to it: CWvsApp::InitializeGr2D.

6) Within the sub you'll always initially see one flag (0x4003, or the 16387). Below or near it you'll see something assigned as 3, a type for the ZComAPI. Ignore this stuff, you just want to remember it to know what to edit. Right below these two variable declarations you'll see assigned a DWORD pointer, like so:

OlBAufK - Windows 8/10 Client Support Fix - RaGEZONE Forums


This is the pointer that contains the flag for whether or not you're going to enable Window Mode. The flag is initialized in CWvsApp::SetUp but is commonly vmed, so we'll ignore changing the flag and instead just modify the only thing that matters: the value inside the EAX register itself.

7) Now that you've found the pointer, click on the DWORD so that it highlights, and then press Tab. If it shifts you into Hex View-A, simply click into the IDA View-A tab. Once you're there, we can get the address and modify the register's value to a hard-coded 0.

vZ8kYkx - Windows 8/10 Client Support Fix - RaGEZONE Forums


Note: Don't make the same silly mistake I did above ;). It'll likely jump you to the address where it moves the data from EAX register, and we don't want that. Instead, we want to modify where it moves data to the EAX register. Scroll up until you find the physical DWORD pointer:

Code:
[b]008FC396[/b]                 mov     eax, [b]dword_AB705C[/b]

There we have it. You now have the address bolded, and you replace the DWORD pointer reference with just a 0. Voila, window-moded startup on pre-bigbang clients. I found this to be extremely useful for my server :)

Alright, hopefully I didn't miss anything and everything works out this time Sandwich. Let me know how it goes~
 

Attachments

You must be registered for see attachments list
Moderator
Staff member
Moderator
Joined
Jul 30, 2012
Messages
1,102
Reaction score
432
Very appreciated bible post

May as well test it, seeing I am a v62 user :p

The first test indeed made the client no longer boot for me whatsoever, this one works completely as far as I can tell, meaning once I open the client with the modified addresses the client boots up in the top left corner of my screen windowed.

Cool stuff, very helpful for my tespia server actually where countless client bootups are made.

Cheers as usual Eric. You know by now how much we love you :)
 
Junior Spellweaver
Joined
Jun 3, 2010
Messages
164
Reaction score
41
Another way to find CWvsApp::InitializeGr2D. (Tested in v62/83)
1. Open STREDIT and load localhost.
2. Find Gr2D_DX8 and get the ID of string. Eg: 2298 in v83.
3. Open IDA with loaded idb and press Alt + I and search the id you found in step 2. (should tick Find all occurrences)
There should be only one occurrence and that is CWvsApp::InitializeGr2D.
 
Skilled Illusionist
Joined
Apr 26, 2015
Messages
302
Reaction score
77
Read the bottom of my post. It's not really a "hack", just a flag that makes the application run in Window Mode instead of a Full Screen like GMS does. You can look into the client/Gr2D/DirectX on that, but it's just changing the 0x10 flag to 0x0.

Also @PrinceReborn at least on my Windows 10 x64 Alienware with Chrome open and running, Skype all active, CE and all kinds of other apps in the background, I still have yet to get a parameter error using your client. I guess it just really depends on the computer because my friends and I don't seem to run into issues. However, like you said, it'll for sure happen if you run the client so many times it triggers it. I believe on a normal basis of running the client it should work every time, and involves much less client editing in the long run.

One other thing I'm not sure I have mentioned about the other workaround is that it can cause an exception in the client where it doesn't execute CoInitialize and will throw that error instead of parameter. I've noticed this when testing it out with both my fix AND the code-cave in the client, and it goes away when I only use the dinput8.dll trick.

It works Eric, I was able to initialize the variable with the window mode value.

For sake of curiosity, If you force the return value of get_width() and get_heigth() to, lets say, 1366 x 768, respectively
The game will initialize in full widescreen mode(at least for my laptop). However, the icons would still be 800x600.
I wonder If we could do a bit more of hacking and position the icons correctly accoriding to the resolution.
For example, we could have a DLL to detect the screen resolution and then patch the get_width and get_height with it's values and also the position of the icons.


Do you know the positions of the icons(menu bar, etc) are set Eric?
 
Initiate Mage
Joined
Sep 30, 2016
Messages
22
Reaction score
30
Alright, so down to the fix. First, you might as well download dinput8.dll to place into your MapleStory folder. You can download it Next, we're going to need to do some client editing. One thing I can say is that the client modification done here is extremely simple and anyone can do it.

Finding the function is easy but I'll provide addys for the common versions anyways.

Code:
v62 -> 00672F10 (JE to JMP)
v75 -> 006DF82D (JE to JMP)
v83 -> 00796357 (JE to JMP)
v111 -> 0085EC08 (JMP 0085EE88)

How to find it? Using IDA, open the Strings window and sort it by String. Go to the very bottom and you'll find the following string:
LmVmCwT - Windows 8/10 Client Support Fix - RaGEZONE Forums


Double-click on it to go to the dword value in IDA-View:
HD0Re2M - Windows 8/10 Client Support Fix - RaGEZONE Forums


Notice on the right there's a DATA XREF that says ZAPILoader? For you it'll be sub_XXXXXX, but double-click on it. It'll lead you to the ZAPILoader function with the checks. I would've included v117, but the sub is virtualized so you won't have any XREF's available to find it. If you want it anyways, the address of the function in v117 is 0089ECA0. You'll have to debug and find the address to jump yourself for that one :p

aaand that's it! Simply put, we add the working non-deprecated dinput8.dll into our MapleStory folder and bypass the client checks that prevent it.

Enjoy!

- Eric

Here's a clearer instruction:


AOB:
6A00
68 ?? ?? ?? ??
68 ?? ?? ?? ??
6A 00
FF 15 ?? ?? ?? ??
6A 00
E8 ?? ?? ?? ??
CC
CC
CC
CC
CC
Sample client address: 0x77E8C0

Sample Function:
Code:
void __noreturn sub_77E8C0()
{
  MessageBoxA(0, &loc_CB8630, "Error Message", 0);
  exit(0);
}
KWus19u - Windows 8/10 Client Support Fix - RaGEZONE Forums



  1. Search for the string “Error Message” and click on the first result.
  2. Move d8input.dll to the MapleStory directory [DX9 W8]
    vDUq9RA - Windows 8/10 Client Support Fix - RaGEZONE Forums
  3. Set a breakpoint at the first instruction, and run the game.
  4. You should land on the following code:
    XJtV7zO - Windows 8/10 Client Support Fix - RaGEZONE Forums
  5. Replace the first instance of ‘JMP SHORT 7801D0” at the start of the function with “JMP 00780448”.
    Sc9ERK2 - Windows 8/10 Client Support Fix - RaGEZONE Forums


  6. Jl4qFw0 - Windows 8/10 Client Support Fix - RaGEZONE Forums
 

Attachments

You must be registered for see attachments list
Initiate Mage
Joined
Jan 22, 2009
Messages
72
Reaction score
0
Anyone can release v62 localhost client for me with this fix , I've spent over 10 hours an didn't succeed on fixing this please.
 
Joined
Jan 9, 2009
Messages
29
Reaction score
1
Eric my friend,

thank you for the great fix. Unfortunately your dinput8.dll download link is no longer working. Do you think you could shoot me a fresh DL link?
 
Joined
Jan 9, 2009
Messages
29
Reaction score
1
Taken from an other server, but should be same thing:

Thanks so much Kim. :)



So on further research of this topic, I've come to find that this is far beyond my knowledge of computers haha. Even with the further explanation from Satoshinakamoto, I am oh so lost.
Let me explain what I have done so far:
First and foremost, I put the dinput8.dll file in to my Maplestory folder. That seems to be the easy part.
I then did some research on the so called "IDA". I believe what you all were talking about is .
So, I downloaded it and installed.
Afterwards I opened up my localhost.exe within "IDA".
At this point, I get totally lost. I see a bunch of code and instructions that I simply do not understand. If someone can walk me through this in language that can be understood by a beginner then it will be very much appreciated. I have to start learning somewhere, and I guess that is here.

Thanks so much.

Problem5 - Windows 8/10 Client Support Fix - RaGEZONE Forums

-Slasher86
 

Attachments

You must be registered for see attachments list
Joined
Jan 9, 2009
Messages
29
Reaction score
1
Ok so updating my progress a tad here. I've played around with it and I'm getting a little more familiar. I have entered the 00000011 type C string. The string is under "InternetConnectA". I doubled clicked on the "Sub_[xxxxxx]". I am then brought to this.
Problem6 - Windows 8/10 Client Support Fix - RaGEZONE Forums
In any case, I figured this probably wasn't the place to be so I searched for the "Error Message" string that was mentioned in the post above by Sato. I found it. But Satos next instruction doesn't make sense to me: "Set a breakpoint at the first instruction, and run the game."
By break point does one mean space? And what does one mean by instruction?
Here is another photo for reference: Problem7 - Windows 8/10 Client Support Fix - RaGEZONE Forums
I guess my biggest confusion is what the hell am I editing here?
 

Attachments

You must be registered for see attachments list
Last edited:
Junior Spellweaver
Joined
Sep 16, 2017
Messages
156
Reaction score
36
Mmm, since you're working on v75, I would follow Eric's method (you don't have to find the address manually).

First of all, though, you should get a bit more familiar with the .
Since we do not have the source code of the game, our best (only?) shot at improving, and often actually correcting, game mechanics that depend on the client, is modifying the already-compiled executable, by operating at an Assembly level.

Follows an extremely quick and basic explanation on a few assembly concepts, please do make sure you seek for much more complete reads if you're gonna explore client editing more in-depth. I'd suggest browsing the Tutorials section, for that.
Each line of code you see in your screenshots (apart from the first, that's actually the description made by IDA of the file it just disassembled, aka the executable) is an instruction.
To make it simple, an instruction is an operation that your computer will have to perform. Most instructions require registers (consider them as "data storages").
For example, in the second screenshot you sent, with the instruction:
Code:
mov ecx, esi
you're going to have the content of the register esi moved on the register ecx (first the destination, then the source).

Each instruction is written at a specific location in your program; in IDA, this location (aka "address") is written in the left. In your first screenshot, you're at position 00401000 (remember that positions are hexadecimal values).

An instruction is a series of bytes (in the form of opcode + data); if you open your program in a hex editor, like HxD, you'll notice that everything you saw as instructions in IDA is instead "translated" into a list of bytes.

The address of the next instruction will be determined by the address of the current instruction you're looking at, plus the amount of bytes the current instruction occupies.

Also, to answer your question, setting a "breakpoint" means telling the program to pause itself when it reaches a specific code line. It's useful for debugging, since it allows you to check variables at that specific moment, for example.
To set a breakpoint, press F2 while having your cursor focusing the line you wanna pause the program at.

Now, for your question.

Let's first make sure you understand the matter at hand: while Maple would gladly load the dinput8.dll that's inside its folder, rather than the default Windows one, there's an in-client check against that very file (along with others), to prevent an edited version from being used by players.

I'm not sure about your coding level, but, the check we're talking about (excluding all the checks for other files, for the sake of the explanation) is something along the lines of:
PHP:
foreach (file in maplestory_folder)
{
   if (name_of_Nth_element_in_game_folder == "dinput8.dll")
      show_error_window_and_terminate_program();
}

This means that the client scans each element (files, subfolders) present in your folder, and if it finds a file called "dinput8.dll", it shows you that error window, while closing the game.
But unfortunately for us, not having the client source, we can't operate at that code level, and we have to resort to assembly instead.

In assembly code, conditions are resolved via jumps; a jump instruction does exactly what you expect it to do, it forces the next executed line to be the one at the address passed as argument of the jump.
With this in mind, we can elaborate more on that code.
"foreach" means that we're going to be in that cycle until all the elements have been scanned once. So, we can assume that, internally, there will be a check to see if we've reached the last file: if it's true, exit the foreach cycle, instead of repeating it again.
This is exactly what we're going to modify, following Eric's solution. We're gonna make the foreach cycle interrupt at the first occurrence (that will never be dinput8.dll - files and folders are checked alphabetically).

To do that, we need to find the exact address where the "last element in foreach" is checked against. Eric did it already for us:
Code:
v62 -> 00672F10 (JE to JMP)
v75 -> 006DF82D (JE to JMP)
v83 -> 00796357 (JE to JMP)
v111 -> 0085EC08 (JMP 0085EE88)

So, in IDA, press G (or go to "Jump" > "Jump to Address..." menu) and type the address that corresponds to your game version (if you're on v75, for example, you'll want to jump to address 006DF82D).
In there, you will find something like this (example refers to v83 maplestory client - your address written there will be different, but it doesn't matter):
Code:
JE 007964ED

"JE" is "Jump if equals". This conditional jump is taken only if the last-performed comparison (usually via an instruction like TEST arg1, arg2) is true (aka, if arg1 = arg2; in this case, the TEST will return 0, value that triggers the JE).
By changing it, from JE to JMP (JMP = "jump", without conditions - it cannot be skipped), we force the client to leave the files verification as soon as it checks the first element, effectively preventing dinput8.dll from being tested.

I guess this should pretty much explain it all, let me know if something's unclear.
 
Joined
Jan 9, 2009
Messages
29
Reaction score
1
Mmm, since you're working on v75, I would follow Eric's method (you don't have to find the address manually).

First of all, though, you should get a bit more familiar with the .
Since we do not have the source code of the game, our best (only?) shot at improving, and often actually correcting, game mechanics that depend on the client, is modifying the already-compiled executable, by operating at an Assembly level.

Follows an extremely quick and basic explanation on a few assembly concepts, please do make sure you seek for much more complete reads if you're gonna explore client editing more in-depth. I'd suggest browsing the Tutorials section, for that.
Each line of code you see in your screenshots (apart from the first, that's actually the description made by IDA of the file it just disassembled, aka the executable) is an instruction.
To make it simple, an instruction is an operation that your computer will have to perform. Most instructions require registers (consider them as "data storages").
For example, in the second screenshot you sent, with the instruction:
Code:
mov ecx, esi
you're going to have the content of the register esi moved on the register ecx (first the destination, then the source).

Each instruction is written at a specific location in your program; in IDA, this location (aka "address") is written in the left. In your first screenshot, you're at position 00401000 (remember that positions are hexadecimal values).

An instruction is a series of bytes (in the form of opcode + data); if you open your program in a hex editor, like HxD, you'll notice that everything you saw as instructions in IDA is instead "translated" into a list of bytes.

The address of the next instruction will be determined by the address of the current instruction you're looking at, plus the amount of bytes the current instruction occupies.

Also, to answer your question, setting a "breakpoint" means telling the program to pause itself when it reaches a specific code line. It's useful for debugging, since it allows you to check variables at that specific moment, for example.
To set a breakpoint, press F2 while having your cursor focusing the line you wanna pause the program at.

Now, for your question.

Let's first make sure you understand the matter at hand: while Maple would gladly load the dinput8.dll that's inside its folder, rather than the default Windows one, there's an in-client check against that very file (along with others), to prevent an edited version from being used by players.

I'm not sure about your coding level, but, the check we're talking about (excluding all the checks for other files, for the sake of the explanation) is something along the lines of:
PHP:
foreach (file in maplestory_folder)
{
   if (name_of_Nth_element_in_game_folder == "dinput8.dll")
      show_error_window_and_terminate_program();
}

This means that the client scans each element (files, subfolders) present in your folder, and if it finds a file called "dinput8.dll", it shows you that error window, while closing the game.
But unfortunately for us, not having the client source, we can't operate at that code level, and we have to resort to assembly instead.

In assembly code, conditions are resolved via jumps; a jump instruction does exactly what you expect it to do, it forces the next executed line to be the one at the address passed as argument of the jump.
With this in mind, we can elaborate more on that code.
"foreach" means that we're going to be in that cycle until all the elements have been scanned once. So, we can assume that, internally, there will be a check to see if we've reached the last file: if it's true, exit the foreach cycle, instead of repeating it again.
This is exactly what we're going to modify, following Eric's solution. We're gonna make the foreach cycle interrupt at the first occurrence (that will never be dinput8.dll - files and folders are checked alphabetically).

To do that, we need to find the exact address where the "last element in foreach" is checked against. Eric did it already for us:


So, in IDA, press G (or go to "Jump" > "Jump to Address..." menu) and type the address that corresponds to your game version (if you're on v75, for example, you'll want to jump to address 006DF82D).
In there, you will find something like this (example refers to v83 maplestory client - your address written there will be different, but it doesn't matter):
Code:
JE 007964ED

"JE" is "Jump if equals". This conditional jump is taken only if the last-performed comparison (usually via an instruction like TEST arg1, arg2) is true (aka, if arg1 = arg2; in this case, the TEST will return 0, value that triggers the JE).
By changing it, from JE to JMP (JMP = "jump", without conditions - it cannot be skipped), we force the client to leave the files verification as soon as it checks the first element, effectively preventing dinput8.dll from being tested.

I guess this should pretty much explain it all, let me know if something's unclear.

Wow! You are a lifesaver! Thank you so so so much. If I could give you 100 likes I would. The whole thing is much clearer now, and it was a good first lesson in to the "assembly language". I'm still chewing on a lot of the information, but I love the learning experience. I suppose as a side question, I am curious about the point you made about us not having the source code of the game. If we don't have the source code of the game, then what exactly are the "sources" for the various versions of Maplestory people have available here on Ragezone? The ones with the server files in them. And how exactly does that interact with the official Maplestory folder that you put the localhost.exe into?

Now on to the main topic. I've located the correct address, however the instruction is not of the JE type, but of the JZ type (no not the rapper!). Take a look: Problem8 - Windows 8/10 Client Support Fix - RaGEZONE Forums
That had me a bit concerned, but after doing some research, I found evidently that .
I've been playing around with this program ever since last night trying to figure out how to change this to JMP, but to no avail. I'm going to assume it's not as simple as typing in "JMP" as I can't find that option anywhere. I double click in to the "Loc_6DF9C3" function, but it leads me to this: Problem9 - Windows 8/10 Client Support Fix - RaGEZONE Forums
And of course double clicking on the CODE XREF leads you back to where you started. How in the world does one change this from JV to JMP? I have the day free, so I'm determined to get this server up and running by days end. I'll keep fiddling with it, but I'm eagerly awaiting a reply.

Thanks again in advance!
 

Attachments

You must be registered for see attachments list
Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139
Wow! You are a lifesaver! Thank you so so so much. If I could give you 100 likes I would. The whole thing is much clearer now, and it was a good first lesson in to the "assembly language". I'm still chewing on a lot of the information, but I love the learning experience. I suppose as a side question, I am curious about the point you made about us not having the source code of the game. If we don't have the source code of the game, then what exactly are the "sources" for the various versions of Maplestory people have available here on Ragezone? The ones with the server files in them. And how exactly does that interact with the official Maplestory folder that you put the localhost.exe into?

Now on to the main topic. I've located the correct address, however the instruction is not of the JE type, but of the JZ type (no not the rapper!). Take a look: View attachment 162221
That had me a bit concerned, but after doing some research, I found evidently that .
I've been playing around with this program ever since last night trying to figure out how to change this to JMP, but to no avail. I'm going to assume it's not as simple as typing in "JMP" as I can't find that option anywhere. I double click in to the "Loc_6DF9C3" function, but it leads me to this: View attachment 162222
And of course double clicking on the CODE XREF leads you back to where you started. How in the world does one change this from JV to JMP? I have the day free, so I'm determined to get this server up and running by days end. I'll keep fiddling with it, but I'm eagerly awaiting a reply.

Thanks again in advance!

For starters, the sources here on RZ are referred to as Emulators. They aren't the physical source code of MapleStory, but instead they emulate what the game is supposed to do. If these were actually MapleStory source code, then the bugs and issues in these sources wouldn't exist. These emulators are the server-backend that intercepts packets from the game clients that connect to it and handle them accordingly. They implemented a majority of the game by now, especially over the span of a decade since the initial release of OdinMS. The Localhost.exe game client is the game itself, it controls all of the 1st person visual aspects and controls, as well as all of the physics and formulas used. The server sends a packet to the client, and the client will do the rest for us - no math or advanced calculations involved. The game client connects to the server's IP at a specific port which is where the Login server comes into play, and then in the packets of the login server are the remote IP and Ports of the game servers for each world that you can connect to. The sources simply run an acceptor that listens for incoming connections, accepts them, and logs you into the game. The rest is all just communication of packets between the client and server to make yourself and others move, talk, change maps, attack, etc.

As far as the "source code" of the game goes, we have unpacked and unvirtualized clients that have been leaked because Nexon loves to make mistakes. In addition to these, we also have PDBs (aka a Program Database) which contain the debug information that link to the IDBs (Information Databases) which are generated through IDA once you analyze a program. If you've ever checked the functions table with all of the 'sub_XXX' functions, they are what the compiler has determined to be a function within the client. However, nobody knows the name of the function or the variables or even what they do. A PDB is what will confirm the sections and make sure all of the functions are correct, it will name them and their arguments, and it will even import any enumerations or classes that were used in the client. This lets us convert all of these assembly instructions into real functions and know a bit better what Nexon is doing when and where -- basically this is their source code, but in a compiled binary. We have BMS which is the only leaked server-end binaries of MapleStory, and then we have KMST v330/v1029 as well as GMS v95 client-end binaries. These help us understand the client more so that we aren't going in completely blind on any client edits and such, as well as provide us the actual packet structures for every packet in the game. Before, we had to sniff packets off of GMS and assume their structure off of trial and error, but now we just refer to IDA to know the proper structures.

As for the instruction being JE and not JZ, yeah they're the same thing. The JE instruction means Jump Equal, and the JZ instruction means Jump Zero. If the two values subtracted equal zero then they are equal values, and if the two registers are equal value then it must be equal as well. Now, to modify the instruction you don't use IDA, instead this is where OllyDbg comes in to play. You'll open your localhost in Olly, go to the address you found in IDA by using CTRL+G, press Space to change the instruction, and then change the JZ/JE to JMP and click Apply. You can follow a quick Olly guide here in the tutorial sections since there's quite a few that explain how to use it for client edits.

I thought I'd mention even though you've already got this far that there's a v75 localhost with the other sleep interval workaround in it here: http://forum.ragezone.com/f921/release-unvirtualized-windows-10-support-1119088/ (can't guarantee it'll be perfect or not since it's only a workaround, but feel free to try it).
 
Skilled Illusionist
Joined
Apr 26, 2015
Messages
302
Reaction score
77
Just an easy way to bypass the client checks:

1 - Open your client on a hex editor.
2 - Search for the binary string "dinput8"
3 - Change the string to "dinput9"

Put the dll that eric provided in ms folder with the name "dinput9.dll"

Profit.

Works for all localhost that are not packed.
 
Joined
Jan 9, 2009
Messages
29
Reaction score
1
Thank you all for the help! It works! My goodness what a relief! Problem10 - Windows 8/10 Client Support Fix - RaGEZONE Forums
Yet the problems persist in yet another topic. Take a look here.
 

Attachments

You must be registered for see attachments list
Last edited:
Back
Top