Add HASHAB signing to iTunesCDB header + fix sync_itunescdb
- Set hashing_scheme=3 at offset 0x30 (iPod Nano 7G requirement) - Compute and write HASHAB signature at offset 0xAB - Import compute_hashab from hashab module - iTunesCDB.ext creation restored (was removed accidentally) - 0-byte iTunesDB placeholder (firmware expects this file)
This commit is contained in:
parent
01902d252a
commit
fba3fe7d05
@ -1200,30 +1200,59 @@ class Nano7Database:
|
||||
"""
|
||||
import zlib
|
||||
import re
|
||||
from hashab import compute_hashab
|
||||
|
||||
# Read current Library.itdb
|
||||
with open(self.sqlite_path, "rb") as f:
|
||||
lib_data = f.read()
|
||||
|
||||
# Compute new SHA1 hash
|
||||
# Compute new SHA1 hash of Library.itdb for iTunesCDB.ext
|
||||
new_hash = hashlib.sha1(lib_data).hexdigest()
|
||||
|
||||
compressed = zlib.compress(lib_data)
|
||||
total_size = 244 + len(compressed)
|
||||
|
||||
# Build proper mhfd header
|
||||
# Build mhfd header
|
||||
header = bytearray(244)
|
||||
header[0:4] = b"mhfd"
|
||||
struct.pack_into("<I", header, 4, 244)
|
||||
struct.pack_into("<I", header, 8, total_size)
|
||||
struct.pack_into("<I", header, 12, 0x00020002)
|
||||
|
||||
# Set hashing_scheme = 3 (HASHAB) at offset 0x30
|
||||
struct.pack_into("<H", header, 0x30, 3)
|
||||
|
||||
# Build full iTunesCDB (header + compressed payload)
|
||||
itdb_data = bytes(header) + compressed
|
||||
|
||||
# Compute HASHAB signature and write it at offset 0xAB
|
||||
if self.firewire_id and len(self.firewire_id) >= 8:
|
||||
try:
|
||||
signature = compute_hashab(hashlib.sha1(itdb_data).digest(), self.firewire_id)
|
||||
header[0xAB:0xAB + 57] = signature
|
||||
itdb_data = bytes(header) + compressed
|
||||
logger.info("HASHAB signature written to iTunesCDB header")
|
||||
except Exception as e:
|
||||
logger.warning("HASHAB signing failed for iTunesCDB: %s", e)
|
||||
|
||||
# Write new iTunesCDB
|
||||
with open(self.cdb_path, "wb") as f:
|
||||
f.write(bytes(header) + compressed)
|
||||
f.write(itdb_data)
|
||||
|
||||
logger.info(f"Synced iTunesCDB: hash={new_hash}, compressed={len(compressed)} bytes")
|
||||
|
||||
# Update hash in iTunesCDB.ext
|
||||
if not os.path.exists(self.cdb_ext_path):
|
||||
ext_content = f"[iTunesCDB]\nitunesdb_hash={new_hash}\n"
|
||||
else:
|
||||
with open(self.cdb_ext_path, "r") as f:
|
||||
ext_content = f.read()
|
||||
new_ext_content = re.sub(r"itunesdb_hash=\w+", f"itunesdb_hash={new_hash}", ext_content)
|
||||
with open(self.cdb_ext_path, "w") as f:
|
||||
f.write(new_ext_content)
|
||||
|
||||
logger.info(f"Updated iTunesCDB.ext: hash={new_hash}")
|
||||
|
||||
def sync_locations_cbk(self):
|
||||
"""Regenerate Locations.itdb.cbk with HASHAB-signed block checksums.
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user