Client: Using decrypted server.dat

1
introduction

before we start, I must say that these methods described here are results of my study and some testing/failing process I came up with. it was intended to be used in my Koga project, that is still coming alive next year (maybe). so, none of this was released before, and this is the first place I'm sharing this, and hope you enjoy.

I'm assuming you are familiar to CO2 client files, ollydbg and the basic assembly instructions (JMP, JNZ, JGE, CMP, PUSH, MOV, etc)...
this was not supposed to work with CO3 (Conquer 3) clients, but should work fine with any CO2 client that uses the encrypted "Server.dat".

btw, this walkthrough was made over the v5967 client. but following these steps you might be able to do it on any client. anyway, for other versions specific modifications, see the other versions topic.


the guide consists in some steps in order to make it from a clean client without modifications:
  1. replace TQAnp and TQPlat
  2. bypass the "blacknull" verification (video)
  3. loading decrypted Server.dat (video)
  4. "gzipping" the decrypted Server.dat
  5. other versions
  6. final considerations

*you are permitted to share this anywhere you want, but only if the credits are going together.*



1 - replace TQAnp and TQPlat

replace TQAnp and TQPlat dlls with nulled ones (backup your originals).
this must be done, so you will be able to debug the client with ollydbg. the credits goes to "Ultimation" from Epvpers.

TQAnp+TQPlat.dll.zip
(87.46 KiB) Downloaded 10 times


2- bypass the "blacknull" verification (video)

this must be done, so we can continue to debug from the start of the process in the ollydbg.

run "Conquer.exe" from ollydbg and keep resuming any stop until you see the "Please run Play.exe file." alert.
Image
press pause in ollydbg and search all referenced strings. search for "blacknull" string and create a breakpoint. (in my case 00602B97)
note: make sure you are searching from the top of the strings window, otherwise you may not find the "blacknull" string.

double click the "blacknull" string and you will get into the address on the modules window. scroll a little to top, and you will see something like this:
Image
seek upward till you find the "CMP" instruction, and right below, the MOV and the JGE instructions.
select "JGE" instruction (in my case 00602B5C) and press space (assemble shortcut), and change "JGE" to "JMP". this will follow that address every time (JMP) and not only if after the comparison the value in the memory is greater or equal (JGE).

next step, back to the "blacknull" string, go down till you see "JNZ" instruction. select "JNZ" instruction (in my case 00602BA7) and press space, and change "JNZ" to "JE". you may get something like this:
Image
now, save all modifications to a new executable. right click in modules window, select "Copy to executable", then select "All modifications", select "Copy all".
in the new "Conquer.exe" window, right click and select "Save file". don't forget to save with a different name, like "Conquer-Play-Bypass.exe", to keep the original file as backup.

you can see the video walkthrough below:

Code: Select all

https://www.youtube.com/watch?v=00tYpUcmDpc


3- loading decrypted Server.dat (video)

note: remember to open the "play-bypass Conquer.exe" in ollydbg for this step, otherwise you will may not be able to debug from the very beginning of the process, where the server.dat is actually decrypted to be used by the client.

rename your client's "Server.dat" to "Server2.dat" or anything else, to make the client not find your "Server.dat". you will see the login screen like this:
Image


go to the client's folder, enter the debug folder and search for the last modified file, you will see a message in the log file, saying something like this:
Image


close the client and re-rename the file to "Server.dat".

run "Conquer.exe" from ollydbg, wait for it to load, but do not touch the play button. change to "Conquer" module if needed (right click, then select "View", then select "Conquer" module, and search all referenced strings.
search for the start of the message we got when client did not found the "Server.dat". like "Error in Decrypt file" and set a breakpoint at that string.
look upward until you see an ASCII string ".dat" (in my case, 007CEC7B) and set a breakpoint here.

from this breakpoint, you can restart debug from ollydbg and debug by yourself to get the addresses and see how the client does handle the "Server.dat". I will skip this for you and give you a resume:
1. "Server.dat" is loaded into memory.
2. it is decrypted by the client and saved into a 4 char name temp file, like "s***".
3. client unzip the file (it's gzip compression) and loads outenserver.xml into memory.
4. client uses the data loaded to create login screen and the other stuff.


so, from this point, all we have to do is to make the client load the file we want in the place of temp "s***" file. to do this, we search for referenced strings and the look for a file path that we want to use (our hidden "Server.dat" will be this file).
I will take "ini/quickpay.dat" as my decrypted "Server.dat".
Image


save the dump address (it's the address after the "PUSH" instruction, 00912F18 in my case), we will use it later.
now, go back to the last breakpoint set (that ".dat" ASCII string), and look up until you see a "MSVCR90.tmpnam" call, like this one:
Image


note: you can also right click and select "Search for", and select "All intermodular calls", and search for "MSVCR90.tmpnam", and don't worry, there is only one (at least at this version of mine, but there should be only one), and set a breakpoint here.

here is the tricky part: how to change the file path that it will load decrypted gzip file.
below the "tmpnam" breakpoint, scrolling down, you may see a "KERNEL32.DeleteFileA" call, set a breakpoint in the "CALL" instruction above this:
Image


run until stop at this breakpoint. step into this call. scroll down and get to the first "MSVCR90.fopen" call (screenshot) and set a breakpoint here and also in the "PUSH ECX" instruction above.
Image


note: see the "PUSH EDX" instruction above the "fopen" call? it's the path parameter of the "open" function call. it pushes the value in memory at "EDX" address to be used in the read file function.

right below the "PUSH ECX" instruction, you will see a "JGE" instruction.
change the "JGE" into "JMP" instruction, maintaining the address where it will go to (008525C8 in my case).
go to that address and assemble to "MOV EDX,[PUT THE ADDRESS OF THE FILE YOU CHOSE HERE]", in my case it will be "MOV EDX,00912F18".
on the "NOP" line below, we jump back to that "PUSH EDX" where it loads the path of the "fopen" function, so we assemble to "JMP 008525BF" in my case.
it will end like this:
Image


now, save all modifications to a new executable. right click in modules window, select "Copy to executable", then select "All modifications", select "Copy all".
in the new "Conquer.exe" window, right click and select "Save file". don't forget to save with a different name, like "Conquer-Server.dat-Bypass.exe", to keep the original file as backup.

you can see the video walkthrough below:

Code: Select all

https://www.youtube.com/watch?v=n_xVi2lYej8


4- "gzipping" the decrypted Server.dat

if you open the new executable we created you will see that no server will be shown in the login screen. that's because that file we have selected to replace our decrypted "Server.dat" does not exist (yet).
grab the "outenserver.xml" (attached to the post), and use 7-Zip to create a gzip file:
right click the file, select "7-Zip", select "Add to the file..." And you will see the 7-Zip options window.

you must use this settings in order the client can read the file correctly:
format: gzip
compression level: Ultra
compression method: Deflate
dictionary size: 32KB
word size: 64

note: don't forget to rename the gzip file to "quickpay.dat" or whatever file name you chose.

Place the file in "ini" folder (or the correct folder according to the file path you chose) and start the game again from the new executable.

outenserver.xml.zip
(3.54 KiB) Downloaded 10 times




5- other versions


for other versions, I'll be updating this section with specific modifications needed to got it working on other clients. if you have found anything you want to share, let me know.

v5517 (thanks to @Mugaru)
Mugaru wrote: Wed Jan 06, 2021 1:37 pm Here are my findings for the 5517 client.

Code: Select all

00764CE7 = tmpnam 
00764D9A = DeleteFileA (Call)
007B714F = Push EDX
007B7150 = FOPEN 
007B7149 = Should be changed from JGE to JMP. 
After that 
007B7158 = MOV EDX [FILE THAT WILL BECOME THE SERVER.DAT] (i used:  MOV EDX, 00940450 // ini/ItemtypeSub.dat ) 
007B715E = JMP 007B714F
00765716 = JE Conquer-.007657A0 > This JE should be changed to JNZ
#Update
I added the last OPCode in the code tags of this post which should be changed to make it work.
After i changed that last one, i was able to load my own serverlist.



6- final considerations

this method allows you not only modifying the servers info and changing the IP, name and icon to yours without using any hooks or dll injections, but also to keep your file in secret as "Server.dat" is still needed by the client to do the decrypt or the client will fail.

enjoy your decrypted (+hidden) "Server.dat".
don't forget to leave a feedback.
Last edited by adrian on Mon Jan 11, 2021 11:31 am, edited 1 time in total.
sincerely,
adrian
software engineer

Re: Client: Using decrypted server.dat

3
Spirited wrote: Mon Dec 28, 2020 9:22 pm Great job on typing this all out and documenting the process. I'd be curious to know what steps are required in creating nulled TQAnp and TQPlat dlls, but everything is super detailed beyond that. I'm excited to give this a try when I have time. Thanks. :blushhappy:
thank you. :)

the first time I was studying and trying to do this, i took almost one week to figure it out how it works and make things right. but this time, i took one afternoon to repeat and write all the process... also, I decide to leave it registered so myself could do it at any client in the future and not start from scratch again...
sincerely,
adrian
software engineer

Re: Client: Using decrypted server.dat

4
adrian wrote: Mon Dec 28, 2020 9:38 pm
Spirited wrote: Mon Dec 28, 2020 9:22 pm Great job on typing this all out and documenting the process. I'd be curious to know what steps are required in creating nulled TQAnp and TQPlat dlls, but everything is super detailed beyond that. I'm excited to give this a try when I have time. Thanks. :blushhappy:
thank you. :)

the first time I was studying and trying to do this, i took almost one week to figure it out how it works and make things right. but this time, i took one afternoon to repeat and write all the process... also, I decide to leave it registered so myself could do it at any client in the future and not start from scratch again...
Yep! I totally feel you on that. That was my reasoning to starting a wiki for encryption and packet structures again after the old one went down. Loosing all of that information was rough. I've been doing the same with 3D modeling and Unity in a Google Doc because there's just so many steps to the process. It's easy to forget something and then have dynamic bones not working, or animations stuck. Lol

Re: Client: Using decrypted server.dat

6
Spirited wrote: Mon Dec 28, 2020 9:42 pm Yep! I totally feel you on that. That was my reasoning to starting a wiki for encryption and packet structures again after the old one went down. Loosing all of that information was rough. I've been doing the same with 3D modeling and Unity in a Google Doc because there's just so many steps to the process. It's easy to forget something and then have dynamic bones not working, or animations stuck. Lol
Would you be interested in share basic start steps into encryption reversering? I would like to try it soon by myself, but have no idea how to start...
OELABOELA wrote: Is the same process used for other .dat files? I'm actually working on that part as we speak and I could use a hint or two!
not the whole process, not every ".dat" file is decrypted into a temp file as "server.dat". for other files you just need to jump over the decryption and make sure the decrypted data is in the right place when the client will use it. there is a little hacky way to copy memory from address A to B in the memory if needed, I can tell you if you are interested.
sincerely,
adrian
software engineer

Re: Client: Using decrypted server.dat

7
adrian wrote: Thu Dec 31, 2020 1:16 pm Would you be interested in share basic start steps into encryption reversering? I would like to try it soon by myself, but have no idea how to start...

not the whole process, not every ".dat" file is decrypted into a temp file as "server.dat". for other files you just need to jump over the decryption and make sure the decrypted data is in the right place when the client will use it. there is a little hacky way to copy memory from address A to B in the memory if needed, I can tell you if you are interested.
I will share a few things with you. This is on the lastest patch of Conquer btw. I have been trying to decrypt the ItemType.dat.

It seems they are still using some kind of 'key' to encrypt the data. The function can be found at

Code: Select all

sub_88C16D
the key used is

Code: Select all

0x2537
. This function has 2 args, 1 is ecx (thisPtr to something I haven't been able to relate yet) and the other is the key.

After the key has been set up, it calls the decrypt function, found at

Code: Select all

0088C1CC
. This function has 2 args, again the thisPtr and the path to the ini file.

I have tried calling the TQPlat functions myself from within the process but I'm stuck at the this ptr. It seems to be retrieved from the stack, I tried putting a watchdog on it to see when it changes, but it is totally unrelated when it changes. To find out the args I hooked the setup and decrypt functions and printed them to the console:

Code: Select all

ECX: 1701844, Key: 9527
ECX: 1701844, a1: 1702584
54 6D EB 0 0 0 0 0 0 0
69 6E 69 2F 4D 61 70 44 65 73
ECX: 1702296, Key: 9527
ECX: 1702296, a1: 15500188
54 6D EB 0 0 0 0 0 0 0
69 6E 69 2F 72 75 6E 65 65 66
ECX: 1701272, Key: 9527
ECX: 1701272, a1: 15500344
54 6D EB 0 0 0 0 0 0 0
69 6E 69 2F 72 75 6E 65 5F 73
ECX: 1700508, Key: 9527
ECX: 1700508, a1: 368247984
54 6D EB 0 0 0 0 0 0 0
69 6E 69 2F 6D 61 67 69 63 74
ECX: 1700460, Key: 9527
ECX: 1700460, a1: 15346276
54 6D EB 0 0 0 0 0 0 0
69 6E 69 2F 78 75 61 6E 62 61
Top hex line is the ECX value, bottom hex line is the path. As you can see it starts with 69 6E 69 "ini".

Re: Client: Using decrypted server.dat

10
Diab wrote: Fri Jan 01, 2021 2:46 am In the latest patch tq uses Threeway to encrypt and decrypt most of their client ini files , the 2537 is the seed for the old crypto but it's not used anymore.
I will look into it. Any other hints you can give me on reversing tqplat? The dll seems scattered or obfuscated.
adrian wrote: Thu Dec 31, 2020 4:30 pm I didn't have time to take a look on latest patch files. it's a bit confusing how TQ is handling these files encryption. but is it all that you want: "decrypt the ItemType.dat" ?
For now only itemtype.dat. In the future I might need other files though.
cron