- 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
On the fix I did for v90 I added 5 seconds delay in order to prevent the errors.
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.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.
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.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.
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.
v62: 008276B2
v75: 008FC396
v83: 009F7A9B
[b]008FC396[/b] mov eax, [b]dword_AB705C[/b]
Very appreciated bible post
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.
Alright, so down to the fix. First, you might as well download dinput8.dll to place into your MapleStory folder. You can download itYou must be registered to see linksNext, 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:
Double-click on it to go to the dword value in IDA-View:
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
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
void __noreturn sub_77E8C0()
{
MessageBoxA(0, &loc_CB8630, "Error Message", 0);
exit(0);
}
Taken from an other server, but should be same thing:
You must be registered to see links
mov ecx, esi
foreach (file in maplestory_folder)
{
if (name_of_Nth_element_in_game_folder == "dinput8.dll")
show_error_window_and_terminate_program();
}
Code:v62 -> 00672F10 (JE to JMP) v75 -> 006DF82D (JE to JMP) v83 -> 00796357 (JE to JMP) v111 -> 0085EC08 (JMP 0085EE88)
JE 007964ED
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 theYou must be registered to see links.
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:
you're going to have the content of the register esi moved on the register ecx (first the destination, then the source).Code:mov ecx, esi
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: View attachment 162221
That had me a bit concerned, but after doing some research, I found evidently thatYou must be registered to see links.
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!