From 4b31f8f83171d65dd0d78940e4b78de6dcdd267a Mon Sep 17 00:00:00 2001 From: Jennifer Taylor Date: Fri, 6 Nov 2020 04:13:39 +0000 Subject: [PATCH] Fix a couple length calculations and a few parsing mistakes. Add coverage calculations to track down missing file sections. --- bemani/utils/bishiutils.py | 257 +++++++++++++++++++++++++++---------- 1 file changed, 190 insertions(+), 67 deletions(-) diff --git a/bemani/utils/bishiutils.py b/bemani/utils/bishiutils.py index 727e6ad..46a0aff 100644 --- a/bemani/utils/bishiutils.py +++ b/bemani/utils/bishiutils.py @@ -12,6 +12,38 @@ from bemani.protocol.binary import BinaryEncoding from bemani.protocol.lz77 import Lz77 +# Coverage tracker to help find missing chunks. +coverage: List[bool] + + +def add_coverage(offset: int, length: int, unique: bool = True) -> None: + global coverage + for i in range(offset, offset + length): + if coverage[i] and unique: + raise Exception(f"Already covered {hex(offset)}!") + coverage[i] = True + + +def print_coverage() -> None: + global coverage + + # First offset that is not coverd in a run. + start = None + + for offset, covered in enumerate(coverage): + if covered: + if start is not None: + print(f"Uncovered: {hex(start)} - {hex(offset)} ({offset-start} bytes)") + start = None + else: + if start is None: + start = offset + if start is not None: + # Print final range + offset = len(coverage) + print(f"Uncovered: {hex(start)} - {hex(offset)} ({offset-start} bytes)") + + def get_until_null(data: bytes, offset: int) -> bytes: out = b"" while data[offset] != 0: @@ -33,10 +65,13 @@ def descramble_text(text: bytes, obfuscated: bool) -> str: def descramble_pman(package_data: bytes, offset: int, obfuscated: bool) -> List[str]: - magic, _, _, _, numentries, _, offset = struct.unpack( + # Unclear what the first three unknowns are, but the fourth + # looks like it could possibly be two int16s indicating unknown? + magic, _, _, _, numentries, _, data_offset = struct.unpack( "<4sIIIIII", package_data[offset:(offset + 28)], ) + add_coverage(offset, 28) if magic != b"PMAN": raise Exception("Invalid magic value in PMAN structure!") @@ -45,15 +80,19 @@ def descramble_pman(package_data: bytes, offset: int, obfuscated: bool) -> List[ if numentries > 0: # Jump to the offset, parse it out for i in range(numentries): - file_offset = offset + (i * 12) + file_offset = data_offset + (i * 12) + # Really not sure on the first entry here, it looks + # completely random, so it might be a CRC? _, entry_no, nameoffset = struct.unpack( "