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/b161b62ce6ecaa9479ada6b1b45f99d8 to your computer and use it in GitHub Desktop.
Save mengxipeng1122/b161b62ce6ecaa9479ada6b1b45f99d8 to your computer and use it in GitHub Desktop.
Python script to decrypto config.data file by emulating Thumb instructions in loader
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import unicorn
from unicorn import *
from unicorn.arm_const import *
from capstone import *
from capstone.arm import *
from hexdump import *
# Initialize the disassembler
md = Cs(CS_ARCH_ARM, CS_MODE_THUMB)
code_ptr = 0x00000000
data_ptr = 0x10000000
data_len = 4096
sp_ptr = 0x20800000
def load_binary(uc):
uc.mem_map(code_ptr, 0x10000000);
infos =[
(0x000000, 0x00010000, 0x058e8),
(0x006000, 0x00026000, 0x02a84),
]
with open('loader','rb') as f:
for off, addr, sz in infos:
f.seek(off)
uc.mem_write(addr, f.read(sz))
def load_stack(uc):
sp_base = (sp_ptr & 0xf0000000)
print('sp_base', hex(sp_base))
uc.mem_map(sp_base, 0x10000000);
def code_hook(uc, address, size, user_data):
inst = uc.mem_read(address,size)
# Disassemble the code bytes
for i in md.disasm(inst, address):
print("0x%x:\t%s\t%s" %(i.address, i.mnemonic, i.op_str))
def block_hook(uc, address, size, user_data):
print("Block hook at 0x%x, size %d" % (address, size))
if(address==0x10cb4):
# 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==0x10d2c):
# 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 decryptConfigDat():
# Initialize the Unicorn engine
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)
load_binary(uc)
load_stack(uc)
uc.mem_map(data_ptr, 0x10000000);
# Set the block hook at the start of the code
uc.hook_add(UC_HOOK_BLOCK, block_hook, )
# set register
with open('./config.dat','rb') as f:
f.seek(0)
uc.mem_write(sp_ptr+0x138, f.read(0x200))
uc.reg_write(UC_ARM_REG_SP, sp_ptr)
ADDRESS0=0x11e02
ADDRESS1=0x11e24
uc.emu_start(ADDRESS0|1, ADDRESS1)
ADDRESS0=0x11e28
ADDRESS1=0x11f6c
uc.emu_start(ADDRESS0|1, ADDRESS1)
uc.reg_write(UC_ARM_REG_R0, data_ptr)
ADDRESS0=0x11f70
ADDRESS1=0x11f7e
uc.emu_start(ADDRESS0|1, ADDRESS1)
with open('./config.dat','rb') as f:
f.seek(0x200);
buf = uc.reg_read(UC_ARM_REG_R0)
n0 = uc.reg_read(UC_ARM_REG_R1)
n1 = uc.reg_read(UC_ARM_REG_R2)
dat = f.read(n0*n1)
uc.mem_write(buf, bytes(dat));
ADDRESS0=0x11f82
ADDRESS1=0x11f96
uc.emu_start(ADDRESS0|1, ADDRESS1)
buf = uc.reg_read(UC_ARM_REG_R0)
n0 = uc.reg_read(UC_ARM_REG_R1)
n1 = uc.reg_read(UC_ARM_REG_R2)
dat = uc.mem_read(buf, n0*n1)
hexdump(dat[:0x20])
open('/tmp/tt.bin','wb').write(dat);
print(f'R0: {hex(uc.reg_read(UC_ARM_REG_R0))} ')
print(f'R1: {hex(uc.reg_read(UC_ARM_REG_R1))} ')
print(f'R2: {hex(uc.reg_read(UC_ARM_REG_R2))} ')
print(f'R3: {hex(uc.reg_read(UC_ARM_REG_R3))} ')
print(f'R6: {hex(uc.reg_read(UC_ARM_REG_R6))} ')
print(f'R8: {hex(uc.reg_read(UC_ARM_REG_R8))} ')
print(f'PC: {hex(uc.reg_read(UC_ARM_REG_PC))} ')
def main():
decryptConfigDat()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment