- Joined
- May 26, 2007
- Messages
- 5,545
- Reaction score
- 1,315
Changing the Encryption / Protocol
Contents
Introduction
Part 1. Server Side
Downloads
Part 2. Client Side
Credits
IntroductionPart 1. Server Side
Downloads
Part 2. Client Side
Credits
Many people have spoken about using the "Encryption" to prevent people connecting to your server with a different client. I'm not convinced "Encryption" is the right word, but I may be being pedantic. I don't consider a simple 1 byte Binary Exclusive Or to be an "Encryption", though it does serve as a simple plain text obfuscater. (i.e. it makes unencrypted plain text packets look much less like unencrypted plain text packets)
As far as I can tell, this is the only security on packets between your client and your server in PT however. Because if it's wrong the client and server cannot communicate at all, I refer to it as a "Protocol". Call it what you will, this is the primary differentiation between a Korean, Japanese or Chinese server, and the reason why (aside from the IP address and port) you cannot connect a client from one to a server for another... and even with 1 byte as your "key" there are still 253 more keys to choose from.
If you choose the "key" 0, however, then anything anybody says in global, private or whisper (PM) is broadcast over the internet in plain 8-bit ASCII... you can read it with a packet sniffer without any translation at all. Something to look out for, is that the GM authentication is sent to the server as a whisper. Additionally, most of the clients I've tried keep the line of text spoken in a fixed size buffer, and do not zero it between lines, so if you say a long line (complex GM authentication) and then a short one. "@Hi" then every character over and above those posted in the second message is sent out in the next packet. Not very secure at all... but then, it's only a game, right?
Part 1. Server Side
This is actually the easy half of the job. The original KPT server release (a modified jPT server) had 3 routines patched out of it. These three routines, I have turned back into assembler source code that will build as a DLL for use in the ModPT (Modular Priston Tale) project that I'm working on. It should work natively there, but I'm going to tell you how you can use this DLL in your own server.
I've provided the source code of the DLL, as well as an example English / Japanese Test build binary executable. The source code contains an EQUate statement that will match any location the protocol key is required, so that you can simply replace the value assigned to that Equate in order to change the protocol your server works on. But if you are no good at building DLLs from source, or just CBA to download the DLL Build Environment I posted in an earlier tutorial, you can just Olly the pre-built .dll file instead.
Downloads
New V2 (all 4 routines):-
The built DLL exports the functions Protocol1(), Protocol2(), Protocol3() and Protocol4()... I haven't yet found a better way to distinguish the purpose of each. I know how many arguments are passed to each one, but I've not even deciphered which one does what, or what it's true datatype is as yet, and the final "Protocol.dll" will probably have the Port number in it one way or another too.View attachment Protocol_V2.rar
[strike]
Original v1:-[strike]
You must be registered to see links
You must be registered to see links
You must be registered to see links
You must be registered to see links
You must be registered to see links
You must be registered to see links
You must be registered to see links
You must be registered to see links
You must be registered to see links
NG
You must be registered to see links
You must be registered to see links
[/strike]In any event, they relate to the 3 functions that are patched in KPT, ET2.2 and every other PT server I have seen... though I have seen some that have patched the patches. :s That's a lot easier to do if you have this in a DLL which you have the source code for.
Right, so if you put the .dll file (either the one provided or one you built from the source I've given here) in your server folder, you can add it, and it's 3 functions to the import tables of your server following the guide I posted about adding code to your server with DLLs. (that's the one that has my
You must be registered to see links
in it)Once you have done that, you need to update the calls in your server, you should find them at the following locations:-
Protocol1() is called from
00451FC3 call 004513E0
Protocol2() is called from
All of which is noted in the source code. The other mentioned address is where these routines are found in the GFantasy section created by the Global Fantasy team whom, I presume, the original KPT server came from in the first place. That's the big blob of extra section in the server that Shagpub, QuantumFusion, Sandurr and the rest of SGPT / Frogg / rPT etc old guard have always put any patches they wanted to add.0056F47E call 004515A0
Protocol3() is called from
00451F06 call 00451500
Protocol4() is called from
0056F45A call 00451470
0058848A call 00451470
0058848A call 00451470
I believe Xternal and Xtreme PT still work this way, presume Frogg still do, but know that whom ever StrangeFay works with have moved on from this method at least once, and are (at least aiming to) work from DLLs. They may use the LoadLibrary()... GetProcAddress() method which is popular with cheater / trainer / hacker RCEs because a) it can be loaded at a known point in the programs execution and b) you can get your DllMain() function run at the right point to dynamically patch the executable at run time for DLL injection... As I've said, I don't rate that method for what we are doing, because we don't want to patch anything at runtime... we want a nice stable server with minimal messy tampering. So LoadLibrary() is fine if you want a plugin / optional patch which will automatically revert back to normal operation if the DLL isn't found, but otherwise, lets let the kernel load, map, link and initialise our library for us. In fact, if you want to enable your server to "optionally" load an extra encryption library which should be run at these points only if the DLL exists in the server folder, or some other specified location, you can add LoadLibrary() code to your DLL at in these functions. You could then use optional non-public encryption for "test days" when normal users should be banned from the server, and only "testers" with a non-public client should be able to log in. Then again, I would just swap out the Protocol.dll with a different one, renaming the original to Protocol.normal before installing the "test" Protocol.dll.
Of course, you could just build this assembler into your own extended section, or if you have the usual GFantasy section, it should have them in, and you can change the "key" where it is marked in my source listing.
The other thing to watch out for, is that the Global Fantasy team made the normal CALL operations, and then JMPout to the GFantasy section replacements... that wastes CPU time (a tiny bit, but quite often under heavy server load) and is not very "clean" however, it is safer than patching the root CALL, and if the CALL was a JMP SHORT I would agree with their choice utterly. You could JMP out to your DLL where they did to their new section, but it's not normal to JMP into DLL exports, as they shouldn't know where to JMP back in... these routines don't either, they RETurn to the address the CALL PUSHed onto the stack before it JuMPed the instruction pointer out to your routine.
The CALL instruction is essentially a shorthand for:-
You may find that you have to JMP out to the new section to make the call indirect, as an indirect call takes up more bytes than a direct one, or you may find a cave or some other solution. PUSH EIP
JMP <destination>
and RET / RETN is essentially a:-JMP <destination>
POP EIP
I will mention that from this source, provided you process only the same memory buffer as this code does, and match your encoding and decoding code at both the server and the client, you should be able to implement any kind of encoding you like. Compression, RSA / PGP encryption or SSL/TLS... anything. You don't have to use Assembler either.
You can build your DLL in C or C++ if you want to, so long as you build an x86 Win32 PE, not a MSIL CLR DLL or an x64 DLL or an IA64 DLL or anything, and follow the arguements as passed on the stack by the server (
You must be registered to see links
or
You must be registered to see links
) you should be fine.I only use Assembler because I want to exactly mimic the existing operation of the original server and be sure that it will use a DLL exactly like the original code, with no deviation in operation down to the very last instruction... you can't do that in higher level languages... but once you are happy that everything works 100% as normal with the exported original code, then any problems presented with a DLL written in a higher level language are entirely down to your code, or the way your compiler linked the DLL.
That might sound rude, but if it was my C/C++ built DLL, I would want to be absolutely sure of that, so I hope you do to. To clarify... I know that if my high level DLL doesn't work as expected, it's the fault of my DLL, it's not because I haven't linked it to the main program properly, it can't be, because the Assembler DLL, identical to the original server code but built as an external library, works just fine. So my high level source, or the project file, or compiler switches or something in that high level build process is at fault... I don't have to waste time looking again at my edits to the server EXE, I already know that that half of the job is all good.
Attachments
You must be registered for see attachments list
Last edited: