Skip to content

Instantly share code, notes, and snippets.

@balika011
Created June 24, 2018 23:34
Show Gist options
  • Save balika011/b7b30c316c13fc8ac8ed0bfc2be68777 to your computer and use it in GitHub Desktop.
Save balika011/b7b30c316c13fc8ac8ed0bfc2be68777 to your computer and use it in GitHub Desktop.
TX SX "OS" unpacking tool with 1.2 support + python 3 hax
from Crypto.Cipher import AES
from Crypto.Util import Counter
import struct, sys
"""
typedef struct boot_dat_hdr
{
unsigned char ident[0x10];
unsigned char sha2_s2[0x20];
unsigned int s2_dst;
unsigned int s2_size;
unsigned int s2_enc;
unsigned char pad[0x10];
unsigned int s3_size;
unsigned char pad2[0x90];
unsigned char sha2_hdr[0x20];
} boot_dat_hdr_t;
"""
if sys.version_info[0] >= 3:
import ctypes
class PyObject(ctypes.Structure):
pass
Py_ssize_t = hasattr(ctypes.pythonapi, 'Py_InitModule4_64') and ctypes.c_int64 or ctypes.c_int
PyObject._fields_ = [
('ob_refcnt', Py_ssize_t),
('ob_type', ctypes.POINTER(PyObject)),
]
class SlotsPointer(PyObject):
_fields_ = [('dict', ctypes.POINTER(PyObject))]
def proxy_builtin(klass):
name = klass.__name__
slots = getattr(klass, '__dict__', name)
pointer = SlotsPointer.from_address(id(slots))
namespace = {}
ctypes.pythonapi.PyDict_SetItem(
ctypes.py_object(namespace),
ctypes.py_object(name),
pointer.dict,
)
return namespace[name]
def bytes_encode(text, coding):
if coding == 'hex':
return text.hex()
raise LookupError("'%s' is not a supported text encoding" % coding)
def str_decode(text, coding):
if coding == 'hex':
return bytes.fromhex(text)
raise LookupError("'%s' is not a supported text encoding" % coding)
proxy_builtin(bytes)['encode'] = bytes_encode
proxy_builtin(str)['decode'] = str_decode
long = int
def aes_ctr_dec(buf, key, iv):
ctr = Counter.new(128, initial_value=long(iv.encode('hex'), 16))
return AES.new(key, AES.MODE_CTR, counter=ctr).encrypt(buf)
f = open("boot.dat", "rb")
b = f.read()
f.close()
boot_ver = struct.unpack("I", b[0x0C:0x10])[0]
s2_base, s2_size = struct.unpack("II", b[0x30:0x38])
if boot_ver == 0x302E3156:
s2_key = "47E6BFB05965ABCD00E2EE4DDF540261".decode("hex")
s2_ctr = "8E4C7889CBAE4A3D64797DDA84BDB086".decode("hex")
arm64_key = "35D8FFC4AA1BAB9514825EB0658FB493".decode("hex")
arm64_ctr = "C38EA26FF3CCE98FD8D5ED431D9D5B94".decode("hex")
arm64_off = 0x53BAB0
arm64_size = 0x36370
arm64_base = 0x80FFFE00
fb_key = "E2AC05206A701C9AA514D2B2B7C9F395".decode("hex")
fb_ctr = "46FAB59AF0E469EF116614DEC366D15F".decode("hex")
fb_off = 0x17BAB0
fb_size = 0x3C0000
fb_base = 0xF0000000
data_key = "030D865B7E458B10AD5706F6E227F4EB".decode("hex")
data_ctr = "AFFC93692EBD2E3D252339F01E03416B".decode("hex")
data_off = 0x5F40
data_size = 0x175B70
data_base = 0x80000000
elif boot_ver == 0x312E3156:
s2_key = "47E6BFB05965ABCD00E2EE4DDF540261".decode("hex")
s2_ctr = "8E4C7889CBAE4A3D64797DDA84BDB086".decode("hex")
arm64_key = "51A39F0B46BAE4691AD39A698146E865".decode("hex")
arm64_ctr = "7A307ED7F1ECC792F0E821ECD6999853".decode("hex")
arm64_off = 0x53BAE0
arm64_size = 0x36370
arm64_base = 0x80FFFE00
fb_key = "27BABEE3DCFEF100C744A2388B57E957".decode("hex")
fb_ctr = "0B88AC25AFAF9B92D81372331AD66E24".decode("hex")
fb_off = 0x17BAE0
fb_size = 0x3C0000
fb_base = 0xF0000000
data_key = "8D6FEABE0F3936145A474D3F05D33679".decode("hex")
data_ctr = "2846EFA9DACB065C51C71C154F0E9EA2".decode("hex")
data_off = 0x5F50
data_size = 0x175B90
data_base = 0x80000000
elif boot_ver == 0x322e3156:
s2_key = "47E6BFB05965ABCD00E2EE4DDF540261".decode("hex")
s2_ctr = "8E4C7889CBAE4A3D64797DDA84BDB086".decode("hex")
arm64_key = "22429923901AF74ED6944992C824ACFE".decode("hex")
arm64_ctr = "590BE04550CC6139921D1C95241F34AC".decode("hex")
arm64_off = 0x53BAD0
arm64_size = 0x36370
arm64_base = 0x80FFFE00
fb_key = "E483A884AB59D5D0014404C2EB698517".decode("hex")
fb_ctr = "55A60F59F29DD518B4CAA59D0E3D1629".decode("hex")
fb_off = 0x17BAD0
fb_size = 0x3C0000
fb_base = 0xF0000000
data_key = "AF8F5811D075F5317924E5C1DD70A531".decode("hex")
data_ctr = "78219A2BB518BF9E302AFF75CE5862E1".decode("hex")
data_off = 0x5F50
data_size = 0x175B80
data_base = 0x80000000
else:
raise LookupError("boot_ver '0x%x' is not supported" % boot_ver)
f = open("stage2_{0:08X}.bin".format(s2_base), "wb")
f.write(aes_ctr_dec(b[0x100:0x100+s2_size], s2_key, s2_ctr))
f.close()
f = open("arm64_{0:08X}.bin".format(arm64_base), "wb")
f.write(aes_ctr_dec(b[arm64_off:arm64_off+arm64_size], arm64_key, arm64_ctr))
f.close()
f = open("fb_{0:08X}.bin".format(fb_base), "wb")
f.write(aes_ctr_dec(b[fb_off:fb_off+fb_size], fb_key, fb_ctr))
f.close()
f = open("data_{0:08X}.bin".format(data_base), "wb")
f.write(aes_ctr_dec(b[data_off:data_off+data_size], data_key, data_ctr))
f.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment