Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mengxipeng1122/22aee547f2f8348cfe469ca771671f5a to your computer and use it in GitHub Desktop.
Save mengxipeng1122/22aee547f2f8348cfe469ca771671f5a to your computer and use it in GitHub Desktop.
Python script to decrypt files in asset.dat using Thumb incstructions at mkemu
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import base64
import os
import struct
import unicorn
from unicorn import *
from unicorn.arm_const import *
from capstone import *
from capstone.arm import *
from hexdump import *
# Define the Thumb binary code
# Initialize the disassembler
md = Cs(CS_ARCH_ARM, CS_MODE_ARM)
code_ptr = 0x00000000
data_ptr = 0x10000000
data_len = 4096
sp_ptr = 0x20008000
def load_binary(uc):
uc.mem_map(code_ptr, 0x10000000);
infos =[
( 0x000000, 0x00010000 ,0x5ac10),
( 0x05b000, 0x0007b000 ,0x00c1c),
]
with open('mkemu','rb') as f:
for off, addr, sz in infos:
f.seek(off)
uc.mem_write(addr, f.read(sz))
def block_hook(uc, address, size, user_data):
print("Block hook at 0x%x, size %d" % (address, size))
if(address==0x1273c):
# void * memset(void *__s,int __c,size_t __n)
s = uc.reg_read(UC_ARM_REG_R0)
c = uc.reg_read(UC_ARM_REG_R1)
n = uc.reg_read(UC_ARM_REG_R2)
print('hook memset', hex(s), c, n)
uc.mem_write(s, bytes([c]*n))
uc.reg_write(UC_ARM_REG_R0, s)
uc.reg_write(UC_ARM_REG_PC, uc.reg_read(UC_ARM_REG_LR))
elif(address==0x12ab4):
# void * memcpy(void *__dest,void *__src,size_t __n)
__dest = uc.reg_read(UC_ARM_REG_R0)
__src = uc.reg_read(UC_ARM_REG_R1)
__n = uc.reg_read(UC_ARM_REG_R2) #TODO: hack
print('hook memcpy', hex(__dest), hex(__src), __n)
dat = uc.mem_read(__src,__n)
uc.mem_write(__dest,bytes(dat));
uc.reg_write(UC_ARM_REG_R0, __dest)
uc.reg_write(UC_ARM_REG_PC, uc.reg_read(UC_ARM_REG_LR))
elif(address==0):
uc.emu_stop();
raise Exception('address is null')
def load_stack(uc):
sp_base = (sp_ptr & 0xf0000000)
print('sp_base', hex(sp_base))
uc.mem_map(sp_base, 0x10000000);
def decryptAsset(input_fn, output_dir):
# Initialize the Unicorn engine
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)
load_binary(uc)
load_stack(uc)
uc.mem_map(data_ptr, 0x10000000);
try:
# set register
with open(input_fn,'rb') as f:
f.seek(0)
uc.mem_write(0x7bc90, f.read(0x200))
uc.reg_write(UC_ARM_REG_SP, sp_ptr)
uc.reg_write(UC_ARM_REG_R6, 0x7bc80);
uc.reg_write(UC_ARM_REG_R7, 0x7bd90);
uc.reg_write(UC_ARM_REG_R5, 0x7bc90);
ADDRESS0=0x14a14
ADDRESS1=0x14aac
# Set the block hook at the start of the code
uc.hook_add(UC_HOOK_BLOCK, block_hook, )
uc.emu_start(ADDRESS0, ADDRESS1, )
cnt = struct.unpack('I', uc.mem_read(0x7bd98,4))[0]
with open('./asset.dat','rb') as f:
f.seek(0x200)
uc.mem_write(data_ptr, f.read(cnt))
uc.mem_write(0x7be90, struct.pack('I', data_ptr))
uc.reg_write(UC_ARM_REG_R0, data_ptr);
ADDRESS0=0x14ad0
ADDRESS1=0x14ae8
uc.emu_start(ADDRESS0, ADDRESS1, )
bs=uc.mem_read(data_ptr, 0x800)
hexdump(bs)
file_data_ptr = data_ptr+0x1000;
for o in range(0, len(bs), 0x30):
item = bs[o:o+0x30]
hexdump(item)
name_data = bytes([b for b in bs[o:o+0x20] if b != 0])
name = name_data.decode()
if name=='':break
off, datasz, sz, crc = struct.unpack('IIII', bs[o+0x20:o+0x30])
print(off, datasz-sz)
with open('./asset.dat','rb') as f:
f.seek(0x200+0x800+off)
uc.mem_write(file_data_ptr, f.read(sz))
uc.reg_write(UC_ARM_REG_R0, file_data_ptr)
uc.reg_write(UC_ARM_REG_R1, file_data_ptr)
uc.reg_write(UC_ARM_REG_R2, 0x7be9c)
uc.reg_write(UC_ARM_REG_R3, sz)
ADDRESS0=0x147fc
ADDRESS1=0x14800
uc.emu_start(ADDRESS0, ADDRESS1, )
print(file_data_ptr, datasz)
file_data = bytes(uc.mem_read(file_data_ptr, datasz))
file_name = os.path.join(output_dir, name)
print('file_data', len(file_data), type(file_data))
print('file_name', file_name, type(file_name))
open(file_name,'wb').write(file_data);
finally:
print(f'R0: {hex(uc.reg_read(UC_ARM_REG_R0))} ')
print(f'R2: {hex(uc.reg_read(UC_ARM_REG_R2))} ')
print(f'R3: {hex(uc.reg_read(UC_ARM_REG_R3))} ')
print(f'R4: {hex(uc.reg_read(UC_ARM_REG_R4))} ')
print(f'R5: {hex(uc.reg_read(UC_ARM_REG_R5))} ')
print(f'R6: {hex(uc.reg_read(UC_ARM_REG_R6))} ')
print(f'PC: {hex(uc.reg_read(UC_ARM_REG_PC))} ')
def main():
decryptAsset( '../bins/out.asset.en/asset.dat', '../bins/out.asset.en/asset.files')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment