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.
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:
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 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!