Reverse Engineering – Supercell – Clash Royale. Part 2


Almost two month later, here we are with the act two of the Supercell reverse engineering post series, if you missed the first one about the new encryption, it can be found here.

Nothing special came in terms of updates on any of the Supercell games after holydays, waiting for the scheduled big one that will hit Clash Royale in the upcoming days and that I’m sure will be fullfit of changes and improvements, also in terms of security and protocol.

During these day, a good old friend, that toke part of that magic PoGo Unknown6 reversing night, join our open community, making me feel really stronger while waiting this new update. He immediatly start exploring something that was already partially reversed a month ago and that end up in a complete reverse, the object of this post. What we are going to explore in details today (at least, what we know about it((((that could also be really wrong)))) is (the ECT) EndClientTurn and (the OHD) OwnHomeData.

Both ECT and OHD are part of Supercell protocol and data exchange system, which is common on all their games. Both of them are messages, which holds data and structures. ECT is used mostly to keep the server and the client synced, to prevent cheats. ECT is sent by the client every 10 seconds and its mostly empty. An ECT is sent on almost all the “user actions” such as opening chests, donating a card, requesting a donation and it’s not empty anymore but instead, it’s filled with data to keep client and server synced. Another variant of ECT is used during battles, which is sent and received through the UDP part of Supercell protocol. OHD instead is one of the bigger message and carry all the data used by the client to build the “game home”, you can imagine the amount of data that can be found inside Clash Royale OHD (Events, all your decks, timestamps for chests, crown chest data and many more things).

Rebuilding ECT payloads wasn’t hard, and this was already done by the awesome guys at RoyaleDevs (Messages repo). The stuck till now was the checksum field built by the client and shipped by ECT (Battle ECT is actually using an unknown different checksum).

How the client build the checksum (method name came from my IDA db, offsets from my device):

.text:C615EA44 buildNormalChecksum ; CODE XREF: buildChecksum+2A↓p
.text:C615EA44 LDR R1, [R0,#64] .text:C615EA46 LDR.W R0, [R0,#380] .text:C615EA4A ADD.W R0, R0, R1,LSL#16
.text:C615EA4E BX LR
.text:C615EA4E ; End of function buildNormalChecksum

Once again, dumping these values was quite the faster way to reach the goal. The param which is located in R0 is a struct that should hold OHD data. The 2 fields used to calculate this are the number of cards unlocked by the current player and something that I’ve name ECTSeed. ECTSeed is a value, shipped as second field in OHD, right after the account ID (which is the first 8 bytes), with variable length integer data type. ECTSeed is incremented by 1 sometimes during gametime, I didn’t really go deeper but i can say that is incremented once at every chest received and once every 2 games (but this could be totally wrong). It wasn’t necessary to investigate more since a new login, which will give you a new OHD, will ship the updated ECTSeed. In the meantime, waiting for that new update, we did reversed the full Clash Royale OHD structure, which we will probably open source after the update (we are sure it will change). With that structure, would be possible to create different bots to auto-open chests and auto donations. Did i said we also did the ECT payloads shipped when donating or opening chests right?

Enjoy some chests OHD payloads! Don’t forget to checkout our github projects which are open for contribution!

About the author


1 comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

By GiovanniRocca