Reverse mobile applications on cocos2dx
What do you need?
Oddly enough, we need the apk of our application
You will also need some of your own software to automate the process. I prefer to use python
Development environment, mine is vs-code
Any hexadecimal editor, I have this extension for vs code
Let’s start!
First, let’s look at what we have
APK files are the most common zip archive that can be opened with any archiver. Let’s unpack the files into some folder
By quickly running through the files you can find files with lua code
You can’t just open these files – they are encrypted. But all these files have one thing in common – the word signatr at the very beginning. Let’s put this information aside for now and move on.
Let’s go to the lib folder and go to the desired architecture – I found one single .so file
Let’s try to view it through a hex editor
There is a lot of incomprehensible text, but if you look below, you can find readable lines!
Let’s enter into the search the word that we received earlier – signatr
To the left of this result is a nondescript word. Well, this word is our encryption key. Let’s try to use it
I will write a simple script in Python for decryption using the xxtea method
import xxtea # pip install xxtea
file="client.luac"
sign = 'signatr'
key = 'anyxteakey'
with open(file, 'rb') as f:
filedata = f.read()
filedata = filedata[len(sign):] # обрежем начало файла чтоб убрать 'signatr'
data = xxtea.decrypt(filedata, key) # Дешифруем ключом
with open('test.lua', 'wb') as f:
f.write(data)
Let’s run the script and get the file test.lua
Everything worked! We have received the decrypted file
All that remains is to make a wrapper for the decoding script and implement recursive decoding in folders
import os
import xxtea
sign = 'signatr'
key = 'anyxteakey'
def recursive_decrypt(directory):
files = os.listdir(directory)
for f in files:
if os.path.isdir(directory + "/" + f):
recursive_decrypt(directory + "/" + f)
else:
if f.endswith(".luac"):
print("Decrypting", f)
data = b""
with open(directory + "/" + f, "rb") as file:
data = file.read()[len(sign):]
decrypted = xxtea.decrypt(data, key)
if decrypted:
with open(directory + "/" + f[:-1], "wb") as file:
file.write(decrypted)
os.remove(directory + "/" + f)
else:
print("Failed to decrypt", f)
On my own behalf, I also added a cleaning function to remove empty folders and non-lua files
import shutil
def post_clean(directory):
# delete all not lua files
ls = os.listdir(directory)
if not ls:
shutil.rmtree(directory)
print("Removed", directory)
return
for file in os.listdir(directory):
if os.path.isdir(directory + "/" + file):
post_clean(directory + "/" + file)
elif not file.endswith(".lua"):
os.remove(os.path.join(directory, file))
print("Removed", file)
if not os.listdir(directory):
shutil.rmtree(directory)
print("Removed", directory)
That’s all.
Thank you for your attention 🙂