I'm having quite some trouble decompressing/parsing .dat files of Hi-Rez's custom modified UE3 engine which powers SMITE, Paladins and Realm Royale, so I decided to open a generalized thread to handle this kind of files.
Based on my research, the two most important files for those games are:
Lang_INT.dat - localization file, located in %game_folder%\Localization\INT
assembly.dat - core file putting everything together %game_folder%\CookedPCConsole
There have been previous threads which discussed the localization file, I will now combine what I've learned from those and what I have discovered on my own.
Let's learn a bit about the files (take note those are my findings and could be completely wrong, I am not an expert, nor average at reversing unknown files). I'll also be quoting Laooo, which is known in the UC community.
Hi-Rez uses the same format to store and transmit data. They call it "Marshal" - marshalling means transforming any object to data that can be stored to the disk (file) or sent over the wire (game packets).
The data is stored in form of rows. It looks like this:
https://i.vgy.me/h9FXXm.png
It's an extremely flexible format that consists of rows, fields and sets of rows. These row sets can in turn store more rows, etc. A row contains fields, each of which is defined by an ID which is stored in a large array of IDs that contains information about what type of value they're supposed to hold (is it a string? an integer? a floating point? a boolean?), among others.
Two important files in the game folder use this format: Lang_INT.dat and assembly.dat. Lang_INT.dat (or Lang_CHN, Lang_FRA depending on the language) contains every single localized string in the game, Each row contains the message ID, the version ID, the message's "type", the message itself, etc.. so all you need to do is loop through all the rows and get each message.
assembly.dat is what I would call the "core" of the game. It's basically the game's local database: contains item definitions, stats, tips, etc.. there are over 14 types of data.
What about actually parsing them? They are XORed by 0x2A.
After unxoring, the strings become readable (every character is two bytes, with the string length prefixed to them).
Thus, Lang_INT.dat becomes quite nice to parse and edit if you'd like to do localization.
Now, the big boy assembly.dat is the challenge. After going through the same steps I ended up with readable strings, but that's pretty much it. I have no idea where to go from here, how to actually make stuff out of what seem like random bytes.
At the end of assembly.dat we can see the actual export which converted Marshall to a format the game can understand:
- DBExport: 01/29/2019 9:24:51, Src=devsql.hirezcorp.com:game_build_server_0_14, LangSrc=devsql.hirezcorp.com:game_translations
Here are assembly.dat and Lang_INT.dat links for Hi-Rez's newest game (Realm Royale), uploaded as of making this post:
assembly.dat
Lang_INT.dat
(as a sidenote, even if the files are from Realm Royale they seem to be containing strings and data from the other two games as well, which is pretty strange if you ask me)
Also, here's a quick python script to unxor by 0x2A.
Code: Select all
import os
import sys
f = open(sys.argv[1], "rb")
o = open(sys.argv[2], "wb")
data = f.read()
for d in data:
o.write("" + chr (ord(d) ^ 0x2a))
f.close()
o.close()
That pretty much concludes my adventure with this kind of files. I don't think I can get any further by myself, so I am kindly asking for help. Any kind of suggestion matters. Thanks!