Some little tuts about coding in MUOnline for ASM lang (MASM32 compiler) if somebody wants to pass the tutorial to delphi, C++ or C# you welcome.
For follow this and others tutorial youll have to get a little notion about what is MASM32:
Now that you know this we ready to start, if you dont know wtf is ASM lang then you should probably read a tutorial from iczelion a good ASM coder:Code:- MASM32 is a microsoft compiler, in case you didnt know this... That means that it belongs to microsoft copyrigth, but it got a special licence that allows you to use MASM32 for make any project profit or non profit, the only thing that MASM32 doenst allow is to reedistrubute the compiler has your own.
http://win32assembly.online.fr/
Finally if you dont have time to learn much abouut ASM that isnt mch of a problem, since coding for MuOnline and for any general game that involves hooking and dissamble its pretty much easy...
Lets start !
Tools: Ollydbg, NotePad, Brain (most important)
Lesson 1: Hooking your own DLL
Theory:
The theory its ofcourse that if we want to mod any game or any application itself we need to hook our own code in order to make changes into the target, this is well knowed has "Hooking" and its the basis of everything youll do. Hooking can be from simple methods has using API to very complex methods has API Hooking, Kernel Hooking, Injecting code, etc, etc.
For MuOnline the changes we want to do are in server side and of course has you already think, we need to hook in GameServer.exe wich is the server side client.
Now that you are thinking a little more, lets pass into how we should hook into GameServer. We name several methods, but lets use the most simple one, via API and writting our code into GameServer.
In order to do this lest find a veryusefull API (if you dont know what a API is then this tutorial isnt for you).
The API LoadLibrary its perfect for our job, lets say what MSDN have to say about it:
http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx
Ok smartass has you figure out by now isnt a great challenge, but lets keep on the theory. The LoadLibrary API use 1 argumment that is only the DLL name that we want to load and the returned value is the Handler to our DLL.Code:C++
HMODULE WINAPI LoadLibrary(
__in LPCTSTR lpFileName
);
MASM32:
.data
lpFileName db "MyDLL.dll", 0 ;<--- This is a string
Invoke LoadLibrary, Addr lpFileName <--- We call our API with the argumment of the DLL name
Pure ASM:
push Offset lpFileName ;<--- This is the string
call LoadLibrary ;We call LoadLibrary
But this isnt enough caused LoadLibrary doesnt actually call the DLL (excuse me coders i know in fact it calls it but i put here has it doesnt) it just load it and return the Handler. So we need some way to call a procedure or fuction of our DLL.
If we look closer to our API list we will find this cool thing:
Now that you look this API, you wondering wtf is that, well ill explain it a little fast:Code:C++
FARPROC WINAPI GetProcAddress(
__in HMODULE hModule,
__in LPCSTR lpProcName
);
MASM32:
.Data ?
hModule DD ? ;Handler of the DLL
.Data
lpProcName DB "OurProcName", 0
Invoke GetProcAddress, hModule, lpProcName
Pure ASM:
push lpProcName ;<-- String "OurProcName"
push hModule ;<-- Handler of the DLL
call GetProcAddress
GetProcAddress took the Address Or Offset of a procedure in a specific module, this means in our case that with help of the returned Handler from LoadLibrary we can return the Address of any Procedure of our DLL that we want.
Example if we have our procedure called "Start" then we can get its address thanks to this API, we just need the handler has first param (of DLL) and the proc name ("Start") in this case.
Finally if you come to this place you ready then for leave the theory behind.
In Work:
Now that we are ready to apply what we learn, you guys will follow it into steps.
1.- Open Ollydbg and open GameServer.exe (a fresh one not hooked)
2.- Ollydbg will load GameServer in this place (at least in my fresh GS version):
How we know isnt hooked? caused we dont see any LoadLibrary call at the start and we see in the end a call to GetVersion (indicate that is the real Entry Point of this GameServer).Code:005828E5 > 55 PUSH EBP
005828E6 . 8BEC MOV EBP,ESP
005828E8 . 6A FF PUSH -1
005828EA . 68 58A56A00 PUSH IAT-Game.006AA558
005828EF . 68 C8015800 PUSH IAT-Game.005801C8 ; SE handler installation
005828F4 . 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
005828FA . 50 PUSH EAX
005828FB . 64:8925 000000>MOV DWORD PTR FS:[0],ESP
00582902 . 83EC 58 SUB ESP,58
00582905 . 53 PUSH EBX
00582906 . 56 PUSH ESI
00582907 . 57 PUSH EDI
00582908 . 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
0058290B . FF15 50CD650C CALL DWORD PTR DS:[<&KERNEL32.GetVersion>; kernel32.GetVersion
3.- We can see that GameServer has plenty of empty space lets choose one offset for set our hook, in this case i choose:
4.- Now we have our empty space lets apply what we learn, first we need to call LoadLibrary and make sure you have written the DLL name in a empty offset (if you dont know how read a Ollydbg Guide).Code:00525063 > $ CC INT3
Has you can see we PUSH the first argumment that is the address that holds our string, in this case "00525040" and later we call LoadLibrary. But how do we find LoadLibrary API address?. Well that is simple lets press CONTROL+N in Ollydbg and we will see a window with a reference from all APIs that GameServer uses, now we will writte "LoadLibrary" (just writte it dont do anything else) and you will see this:Code:00525064 . 68 40505200 PUSH IAT-Game.00525040 ; /FileName = "GsPlugin.dll"
00525069 . FF15 04CD650C CALL DWORD PTR DS:[<&KERNEL32.LoadLibrar>; \LoadLibraryA
So we can see the Address of LoadLibrary is "0C65CD04" and thats the address we use for writte:Code:Names in IAT-Game, item 250
Address=0C65CD04
Section=.idata
Type=Import (Known)
Name=KERNEL32.LoadLibraryA
5.- Now lets writte GetProcAddress, we will obtain the address of GetProc by the same way we obtain LoadLibrary (CONTROL+N and writte API name):Code:Call Dword ptr ds:[0C65CD04] -> LoadLibrary
You meaby get confused here, what we do is first PUSH the last argument, but why?Code:0052506F . 68 4D505200 PUSH IAT-Game.0052504D ; /ProcNameOrOrdinal = "MyProcedure"
00525074 . 50 PUSH EAX ; |hModule
00525075 . FF15 00CD650C CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; \GetProcAddress
Caused the way you call arguments in pure ASM its inverted piramidal, this means that you push the last argument first and continue to the first. (If you dont get this part i explain better in Lesson Review)
Now that you get that part, we can push the first argument, but wait... What is push eax?
Well since we call LoadLibrary then the returned value its stored in EAX regist (all APIs return their values in EAX regist) so we just push the value that EAX holds (this means our Handler to the DLL).
And finally call GetProcAddress, easy isnt?.
6.- Well you done fine till this part, once we got our address to our procedure (of course returned in EAX regist) then we just need to CALL EAX, so we can enter into our procedure just like this:
7.- But has you can realise when we start our GameServer we will start in the Entry Point "005828E5" and not in the address where we load our DLL, how we can fix this, very simple lets go to the our Entry Point by pressing CONTROL+G and paste the address "005828E5". Now that we are there we will do a JMP to our DLL space, in my case will be just like this:Code:0052509A . FFD0 CALL EAX
This will make when you load GameServer the Entry Points reedirect the flow of execution to first load your DLL.Code:005828E5 ^E9 7A27FAFF JMP IAT-Game.00525064
8.- We arent ready yet, just a little more. We need to now restore has you can see the instructions that were deleted when you place the JMP to your DLL space load, that instructions where:
So we will go to our DLL address space and after the CALL EAX we will add this INSTRUCTIONS like this:Code:005828E5 55 PUSH EBP
005828E6 8BEC MOV EBP,ESP
005828E8 6A FF PUSH -1
9.- Finally we can end this, but we need to return the execution flow back to where GameServer start.Code:0052509A . FFD0 CALL EAX
0052509C 55 PUSH EBP
0052509D 8BEC MOV EBP,ESP
0052509F 6A FF PUSH -1
But if you smart enough you will realise if we return the flow execution back to the Entry Point, the JMP we put there will make our DLL load eternal times, so yeah smart boy we need to put a JMP to the INSTRUCTION down of our JMP in the Entry Point wich is this:
So the address is 005828EA, and we do the JMP to that address in our DLL space code like this:Code:005828EA . 68 58A56A00 PUSH IAT-Game.006AA558
This will make that after you got done by calling your Procedure, it will jump to the EntryPoint for continue the execution flow and make GameServer start like nothing happens.Code:005250A1 E9 44D80500 JMP IAT-Game.005828EA
10.- Lets save all the changes, lets press Secondary Buttom>Copy to Executable > All modifications. And in the new window Secondary Buttom > Save to File.
11.- Voila you finally done with hooking your DLL ! =) .
Lesson Review:
Here is the full code divided by Entry Point space and DLL space:
[Entry Point]:
[DLL Space]:Code:005828E5 ^E9 7A27FAFF JMP IAT-Game.00525064
Has we can see isnt that hard, its very simple once you get used to coding and ASM.Code:00525083 . 68 A4505200 PUSH IAT-Game.005250A4 ; /FileName = "GsPlugin.dll"
00525088 . FF15 04CD650C CALL DWORD PTR DS:[<&KERNEL32.LoadLibrar>; \LoadLibraryA
0052508E . 68 B3505200 PUSH IAT-Game.005250B3 ; /ProcNameOrOrdinal = "MyProcedure"
00525093 . 50 PUSH EAX ; Push Handler of DLL loaded
00525094 . FF15 00CD650C CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; \GetProcAddress
0052509A . FFD0 CALL EAX ;Call our Procedure
0052509C 55 PUSH EBP ;Restore EntryPoint Instruction
0052509D 8BEC MOV EBP,ESP ;Restore EntryPoint Instruction
0052509F 6A FF PUSH -1 ;Restore EntryPoint Instruction
005250A1 E9 44D80500 JMP IAT-Game.005828EA ;Execution back to EntryPoint instruction after JMP
I must admit that the piramidal system of pushing arguments its a little complex to understand but this is how ASM works and also how all langs converted to ASM of course will work.
Inverted Piramidal System can be resumed has this:
The rest its pretty simple to understand.Code:Push 4Argument ;Last Argument
Push 3Argument
Push 2Argument
Push 1Argument ;First Argument
Call Fuction
Special Notes:
1 .- I know the way of reedirection from Entry Point to DLL space its pretty noob (the JMP thing) but its a very simple way for starters to learn. If you want to do a more PRO way you can always use LordPE or any PE editor and change the address of DLL space has the Entry Point and dont do any JMP from EntryPoint to DLL space.
2 .- If you plan to make the DLL in MASM32 youll have to know that you need to make a .def file, the .def file must contain inside this kind of format:
So the EXPORT procedure you put in that file can be called by GetProcAddress.Code:LIBRARY TEST ;NAME OF DLL
EXPORTS MyProcedure ;NAME OF PROCEDURE TO EXPORT
3.- Sorry for the lack of images i dont have much time.
4.- Sorry for the lack of lang, english is not my natal lang.
5.- If you want to make a resume yourself or explain it in another way (lang, theory, etc) you welcome. The same if you want to change the visual style of the lesson (caused i suck on the visual thing. Just send me a PM).
6.- Ill only answer questions about the lesson, same has questions about ASM, General coding & MuOnline coding (I mean real questions, not like: "Please can i know how code S5?")
Credits: [INDG]FeN$x

