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 zlib
|
||||||
import re
|
import re
|
||||||
|
from hashab import compute_hashab
|
||||||
|
|
||||||
# Read current Library.itdb
|
# Read current Library.itdb
|
||||||
with open(self.sqlite_path, "rb") as f:
|
with open(self.sqlite_path, "rb") as f:
|
||||||
lib_data = f.read()
|
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()
|
new_hash = hashlib.sha1(lib_data).hexdigest()
|
||||||
|
|
||||||
compressed = zlib.compress(lib_data)
|
compressed = zlib.compress(lib_data)
|
||||||
total_size = 244 + len(compressed)
|
total_size = 244 + len(compressed)
|
||||||
|
|
||||||
# Build proper mhfd header
|
# Build mhfd header
|
||||||
header = bytearray(244)
|
header = bytearray(244)
|
||||||
header[0:4] = b"mhfd"
|
header[0:4] = b"mhfd"
|
||||||
struct.pack_into("<I", header, 4, 244)
|
struct.pack_into("<I", header, 4, 244)
|
||||||
struct.pack_into("<I", header, 8, total_size)
|
struct.pack_into("<I", header, 8, total_size)
|
||||||
struct.pack_into("<I", header, 12, 0x00020002)
|
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
|
# Write new iTunesCDB
|
||||||
with open(self.cdb_path, "wb") as f:
|
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")
|
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):
|
def sync_locations_cbk(self):
|
||||||
"""Regenerate Locations.itdb.cbk with HASHAB-signed block checksums.
|
"""Regenerate Locations.itdb.cbk with HASHAB-signed block checksums.
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user