Started parsing for hwid / version.

This commit is contained in:
2019-10-16 01:48:03 +02:00
parent 8be7833770
commit aaea75bb08
3 changed files with 101 additions and 4 deletions
+87 -4
View File
@@ -18,7 +18,9 @@ class ParseException(Exception):
class RgnBin:
def __init__(self, filename: str=None):
self.filename = filename
self.struct = []
self.hwid = None
self.version = None
self.payload = None
if filename is not None:
self.load()
@@ -30,14 +32,95 @@ class RgnBin:
f.close()
self.load_from_bytes(rawdata)
def find_metadata(self):
try:
end_loc = self.payload.rindex(END_PATTERN)
#print("end_loc: {}".format(end_loc))
except ValueError:
# No END_PATTERN found
end_loc = None
jmp = unpack("<L", self.payload[0:4])[0]
print("JMP: 0x{:08x}".format(jmp))
hwid_addr = None
swver_addr = None
if jmp == 0xe59ff008:
# Variant 1a or 1b (end > hwid > swver > entry OR hwid > swver > end > entry)
(x1, x2, x3, entry_addr) = unpack("<LLLL", self.payload[4:20])
print("{:04x} / {:04x} / {:04x} / {:04x}".format(x1, x2, x3, entry_addr))
# HWID and SWVER are near each other
if abs(x2 - x1) == 2:
# Assume 1b: x1 = hw_id, x2 = swver
delta = 20 - entry_addr
hwid_addr = x1 + delta
swver_addr = x2 + delta
else:
# Assume 1a: x2 = hw_id, x3 = swver
delta = 20 - entry_addr
hwid_addr = x2 + delta
swver_addr = x3 + delta
if jmp == 0xe59ff00c:
print(RED + "Checking for 2" + RESET)
# Variant 2 (end > hwid > swver > lend > entry)
(end_addr, hwid_addr, swver_addr, lend_addr, entry_addr) = unpack("<LLLlL", self.payload[4:24])
print("hwid_addr: {} / swver_addr: {}".format(hwid_addr, swver_addr))
print("end_addr: {} / lend_addr: {} / entry_addr: {}".format(end_addr, lend_addr, entry_addr))
if lend_addr < 0:
load_addr = -lend_addr
print("load_addr: {}".format(load_addr))
delta = 24 - load_addr
else:
delta = 24 - entry_addr
print("delta: {}".format(delta))
hwid_addr += delta
swver_addr += delta
print("hwaddr: {} / swveraddr: {}".format(hwid_addr, swver_addr))
# expected hw_addr: 0x4b5e = 19294 / swver: 0x4b60 = 19296
if end_loc and jmp == 0xea000002:
# Variant 3 (end > hwid > swver)
(end_addr, hwid_addr, swver_addr) = unpack("<LLL", self.payload[4:16])
delta = end_loc + 2 - end_addr
hwid_addr += delta
swver_addr += delta
if jmp == 0xea000003:
print(RED + "Checking for 4" + RESET)
# Variant 4 (end > hwid > swver > ???)
if jmp == 0xea000004:
print(RED + "checking for 5" + RESET)
# Variant 5
if hwid_addr:
if hwid_addr < 0 or hwid_addr > len(self.payload)-2:
print(RED + "HWID OFFSET {:04x} OUT OF BOUNDS {:04x}".format(hwid_addr, len(self.payload)) + RESET)
else:
self.hwid = unpack("<H", self.payload[hwid_addr:hwid_addr+2])[0]
if swver_addr:
if swver_addr < 0 or swver_addr > len(self.payload)-2:
print(RED + "SWVER OFFSET {:04x} OUT OF BOUNDS {:04x}".format(swver_addr, len(self.payload)) + RESET)
else:
self.version = unpack("<H", self.payload[swver_addr:swver_addr+2])[0]
# Try EOF-4
if not self.hwid and not self.version:
print("Checking for EOF-4")
(hwid, version) = unpack("<HH", self.payload[-6:-2])
if hwid < 0xffff and version < 0xffff:
print("EOF-4 matches")
self.hwid = hwid
self.version = version
return None
def load_from_bytes(self, payload: bytes):
self.payload = payload
print(repr(payload[0:10]))
jmp = unpack("<L", payload[0:4])[0]
print("{:08x}".format(jmp))
self.find_metadata()
def __str__(self):
txt = "Binary payload, {} Bytes".format(len(self.payload))
if self.hwid:
txt += "\n - hw_id: 0x{:04x} / {:d} ({})".format(self.hwid, self.hwid, devices.DEVICES.get(self.hwid, RED + "Unknown device" + RESET))
if self.version:
txt += "\n - Version: 0x{:04x} / {:d}".format(self.version, self.version)
cksum = ChkSum()
cksum.add(self.payload)
exp_byte = cksum.get_expected()