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!
Quite curious about how you're doing this. I've been writing an emulator for another game yet I've always used packet logs to reverse packet structures. A brief explanation would be much appreciated. Great work either way.
@tofuman
I found only this client for PC, but he v.1.01.00
You can upload v.2.00.03?
---upd---
as i can see, *.dat files (S,P...) -> blowfish encrypted
For reversing the network protocol first look for the WinSock recv function in Ida. Then using a debugger trace the function and send the client a packet. See where it goes. Usually a client will have a function pointer table. Sbol was slightly different the way it looked up to get the function for the pointer type but essentially worked like this. Once you have this function table you know what packets are processed by the client. So send a packet using a valid packet type it'll then jump to a function to process the packet. There you'll see the subtypes of each packet so again work your way through these and you'll see the client moving byte/short/int/string/arrays to either the stack to use against another function or move to global values. If mov'd to global values use a debugger to find out what reads them or alter them to see what changes. I also make educated guesses on what the structure does. For instance select a car and when a packet is needed that has arrays of bytes it'll usually be the stats of the car and configuration and other client data such as team membership. The process is time consuming but gets easier when you work your way through the packets.
Also I've found mentions of a client version 2.08.00 which has had quite a few improvements. Unfortunately I can't find a download for this.
For reversing the network protocol first look for the WinSock recv function in Ida. Then using a debugger trace the function and send the client a packet. See where it goes. Usually a client will have a function pointer table. Sbol was slightly different the way it looked up to get the function for the pointer type but essentially worked like this. Once you have this function table you know what packets are processed by the client. So send a packet using a valid packet type it'll then jump to a function to process the packet. There you'll see the subtypes of each packet so again work your way through these and you'll see the client moving byte/short/int/string/arrays to either the stack to use against another function or move to global values. If mov'd to global values use a debugger to find out what reads them or alter them to see what changes. I also make educated guesses on what the structure does. For instance select a car and when a packet is needed that has arrays of bytes it'll usually be the stats of the car and configuration and other client data such as team membership. The process is time consuming but gets easier when you work your way through the packets.
I managed to get through the part where you figure out which packet is handled in which function but couldn't make any sense of what client was doing with the packet data. Much appreciated for the detailed answer.
I don't know anything about this game but I'm working on an emulator for a very similar one.
For this you probably want to compare function calls and field accesses in packet handlers with similar functionality. You'll see packets that have to do with car/player information accessing the same data like getting car or player by ID or something, which helps you narrow down what the calls are for. Combine this with the knowledge of packet contents and you can just follow where the data from the packet is being copied.
It's especially helpful to use IDA for this, because the more structures you define and unknown functions/locals you name, the easier it becomes.
I found a screenshot of it on a cached version of their site. archive.org doesn't have the latest unfortunately but someone took a snapshot here: 首都高バトルOnline and the image in question is on this page: 首都高バトルOnline
The in game HUD does look different too from the version I have. I had made contact with Genki years ago when I first wanted to attempt this. They actually replied but said the service is terminated and not much more. I've attempted to contact them again this time round and got no reply.
AcarX, I use a mixture of utils while working on the game. IDA is very good at giving me graphical version of the code flow. As I said with global values you'll see mov's to around 0x6cXXXX - 0x6dXXXX. Using Cheat engine for example check for what accesses the value and you'll gradually work out what the packet does. But most will initially move the packet data to stack for either a structure loop or conditional sub packet commands. Like the initial car list in packet 0xe80. A short specifies the amount and ints need to follow as many as specified in the short. the int is the TXR car value. It actually matches TXR0. Other packets may use strlen and strcpy which are displayed in IDA which is an indicator that it's a string and could be team name, player name and so on. Most things come with experience not only in reversing clients in general but in the experience you gain in the particular game. After some time you get familiar with the client and it becomes much easier to follow and make educated guesses with structures.
Its no where near complete but the wiki I started is HERE. It'll have the packet structures documented eventually.
Here is the progress so far for everyone to test out: DOWNLOAD
I've included the client I've partially translated to English. It is nowhere near done but will get you through the menus.
Also remember you can run the client with -w switch to run in windowed and -skipwarning
to load straight to login screen. Enter any username and password and then handle. This is not saved yet. You can choose from all available cars in the game.
I've found the client slightly buggy. It can crash after selecting a car. It'll generally be okay when retried.
I've been busy with work over the past week so not been able to spend too much time. Still working on the packet structures. I'm pretty much done with the packets I have logged. There are still packets that handle initiating racing (seems to be packet 0x0700 which also has the movement/position commands). I'm focusing on the garage packet structure so that I will be able to login with an existing account (im assuming that when logging into an existing account the player was taken to their garage instead of straight to the highway like when a new account is created). Then I can work on having players join the server. Initiating the race and so on may come easy once I have clients able to interact with one another.
I lost motivation back in 2016. But have picked this up again recently I've worked out packets for logging in and loading up your saved car data. Also a few more menus worked out so creating a team is possible, entering car shop and part shop.
Now that I have the server at a stage where I can log in I'll be rewriting the server and currently coding a management server which handles the database and global management of the game servers.
I also couldn't stand the awful 640x480. So adjusted the client exe to load my dll and the dll dynamically updates the exe including translations.
Some shots of the widescreen changes
I uploaded the old code I had to github but its not worth using it as I'm yet to upload the latest. I did also create a wiki for preservation purposes
The Management server is coded. This handles all DB access. Currently supports SQLite and MySQL. can be installed as a service or run as a console application. I plan to add a management HTTP interface so the servers can be centrally managed by it.
The Game server now loads a players data via the management server. The garage packets were holding up most progress but have those figured out now so can now store upto 4 cars in the garage.
I started working on the shop packets which I have mostly worked out and lead me to working with the H.DAT, P.DAT and S.DAT files as these are used to populate the shop data and retrieve the car details. Which are indeed (as someone already mentioned) protected with Blowfish. So using the ASM code from the client I've been able to get the unprotected versions although I'll probably write code to load the protected files directly (although I may be lazy and just leave the function wrapped in __asm{}). The client gets the car details and shop prices from S.DAT and P.DAT. I'll load these on the server so that values sent from the client are ignored and the server will know if a user alters the packets. (I may even scrap these files from the client data and have the server send a custom packet with this data instead).
I'm working out the structure of the P/S.DAT files. S contains the car spec, model file name, P contains the parts available and price.
The H.DAT is simple. It's essentially the smut filter for when creating handles. Why this is local I don't know. As the server can also send a packet that informs the client the handle can't be used. This is a plain text file (once deciphered) with the strings seperated either by nulls or \r\n (no idea why they don't just stick with 1 terminator). Again I may just scrap this file and have the server handle this.
There was a bug with the client where if you didn't end the client by the GUI the main thread wouldn't end and would fill up the log files (my development client had over 30GB of logs). This was caused by the thread only checking for WM_QUIT and not WM_CLOSE as well. Although this still didn't end the thread in all cases. If you close the window some times the message would hang on WM_NCMBUTTONDOWN and fill up the logs. So fixed that also.
I'm hoping to have a test server up in a few weeks. It's taking a little longer than expected.
I still need to make the menus widescreen but focusing on the game itself at the moment.