Client: How to disassemble Conquer for reverse engineering

1
Introduction

Unlike the Windows client of Conquer Online, the macOS client contains debug symbols that make it easier to reverse engineer. This guide will help you disassemble Conquer for the first time using Hopper Disassembler, which is a reverse engineering tool I use to translate compiler machine languages into higher-level assembly language. Hopper is a paid program; therefore, I will not be providing a copy through this thread. I recommend looking around for a copy. You can also use the free demo version (which is unable to save) with a pre-analyzed binary.

Getting Started

Before you start, it's important that you understand the basics of assembly. For a tutorial on Assembly Languages, check out Tutorials Point. They cover the basics pretty well. Once you're caught up, you'll need to set up an environment for Hopper since it can only be installed on Linux and macOS. I chose Linux for my environment. For simplicity, I recommend using either Oracle VirtualBox or VMWare Workstation Player with Ubuntu 18.04. If you need a tutorial, check out this video. Once your VM is set up, install Hopper Disassembler and you're ready to go.

With your environment set up, download the macOS client for Conquer. All you need is the dmg file (you don't need to install it). After downloading the file, open it as an archive and navigate to "Conquer\Conquer.app\Contents\ConquerGameExe.app\Contents\MacOS". This path might be different depending on the client version you downloaded. Extract the ConquerGameExe file and open it in Hopper. Hopper will automatically detect the compiler, so don't change any of its analysis settings. After a few minutes, you should have analyzed assembly. Save at this point so you don't have to re-analyze the executable; then, you're ready to get started with reverse engineering.

If you're interested in decompiling the Android version of Conquer Online, Hopper can also disassemble that. Simply unpack the APK using 7-zip or another archive manager and navigate to "lib/armeabi". Open libCQ2Client.so in Hopper using default settings.
Image
Reverse Engineering Packets

One advantage of having debug symbols in the macOS client is that packets are easy to reverse engineer. Packet classes in Conquer are prefixed with "CMsg" and extend CNetMsg. CNetMsg initializes a buffer on the EBX register at offset 0x404. When reading packet definitions which extend CNetMsg, you'll see MOV operations to offsets from EBX+0x404. Packets created by the client define a Create method which writes the packet length and ID to offsets EBX+0x404 and EBX+0x404+2. Packets processed from the server define a Process method which reads at offsets from EBX+0x404.

Let's look at MsgPCNum, a simple packet sent to the server from the client which includes the client's MAC address. Look up "CMsgPCNum::Create" and change the view to Pseudocode (Alt+Enter). You'll see the following instructions below in C-like assembly:
Image
The client first writes the TQ packet header to the CNetMsg buffer, then writes the account id and mac address to offsets 4 and 8. See the code below for comments.

Code: Select all

*(int16_t *)*(ebx + 0x404) = 0x34; // Length
*(int16_t *)(*(ebx + 0x404) + 0x2) = 0x44c; // Packet ID
*(*(ebx + 0x404) + 0x4) = arg_4; // Account ID
if (GetMacAddr(*(ebx + 0x404) + 0x8) != 0x0) { // Mac Address
In some other examples, the result of Create is referenced by a secondary Send method, so be sure to check your reverences when reversing a packet. MsgWalk is a good example of a packet with a Send method. CMsgWalk::Send sets the timestamp in the packet and adds the movement to the stack of expected responses from the server before sending. MsgWalk is also a good example of a packet which is both sent and received by the client. See the screenshot below.
Image
In this example, the packet handling splits on the type of movement at offset 0xC. If the movement type is 0x9 (riding a horse), then additional directions are taken into account. You can also see how the client processes the packet: it checks the timestamp, sends a MsgAction packet for querying the location on movement failure, decrypts the position using XTEA.

Contributing

If you're using this tutorial to reverse engineer packet structures, then please consider contributing to the wiki:
Conquer Online Development Wiki

Thanks!
Interested in my work?

If you wanna learn more about me and my projects: visit my portfolio website. There, you can find my free, open-source work and articles about game development. Due to contractual restrictions: I am not available for job requests or volunteer work.

About Me | GitLab Profile | Website

Client: How to disassemble Conquer for reverse engineering

3
adrian wrote: Thu Dec 24, 2020 1:00 am that's something I was looking for. I've modified the windows client for using decrypted 'server.dat' and sending decrypted password in login packet, but I'm mac user, and have been using parallel's desktop to use the client... hopefully I can make the mac client connect to my server.

big thanks.
I never got around to learning how to get the client to use a decrypted server.dat file. Maybe you could write some tutorials here on the subjects? I'd be curious to learn because once you know how to bypass it, you can re-encrypt it and write your own hook for that.
Interested in my work?

If you wanna learn more about me and my projects: visit my portfolio website. There, you can find my free, open-source work and articles about game development. Due to contractual restrictions: I am not available for job requests or volunteer work.

About Me | GitLab Profile | Website

Client: How to disassemble Conquer for reverse engineering

4
Spirited wrote: Thu Dec 24, 2020 9:54 am
adrian wrote: Thu Dec 24, 2020 1:00 am that's something I was looking for. I've modified the windows client for using decrypted 'server.dat' and sending decrypted password in login packet, but I'm mac user, and have been using parallel's desktop to use the client... hopefully I can make the mac client connect to my server.

big thanks.
I never got around to learning how to get the client to use a decrypted server.dat file. Maybe you could write some tutorials here on the subjects? I'd be curious to learn because once you know how to bypass it, you can re-encrypt it and write your own hook for that.
not sure if the method I used will allow you to apply your own crypto, but check my latest post to se how I made it:
tutorials-f13/guide-using-decrypted-ser ... s-t23.html

*also, if you could approve my last edits... the images was in low resolution, so i put the high urls.
sincerely,
adrian
software engineer