Fix ramdisk identity mismatch and add USBMux UDID patching

This commit is contained in:
Lakr
2026-03-06 13:02:25 +08:00
parent b50b630d19
commit 40599d461d
5 changed files with 158 additions and 7 deletions
+47
View File
@@ -51,6 +51,8 @@ from patchers.kernel import KernelPatcher
OUTPUT_DIR = "Ramdisk"
TEMP_DIR = "ramdisk_builder_temp"
INPUT_DIR = "ramdisk_input"
RESTORED_EXTERNAL_PATH = "usr/local/bin/restored_external"
RESTORED_EXTERNAL_SERIAL_MARKER = b"SSHRD_Script Sep 22 2022 18:56:50"
# Ramdisk boot-args
RAMDISK_BOOT_ARGS = b"serial=3 rd=md0 debug=0x2014e -v wdt=-1 %s"
@@ -310,6 +312,50 @@ def patch_ibec_bootargs(data):
return True
def patch_restored_external_usbmux_label(mountpoint):
"""Patch restored_external USBMux serial label when RAMDISK_UDID is provided."""
target_udid = os.environ.get("RAMDISK_UDID", "").strip()
if not target_udid:
print(" [*] RAMDISK_UDID not set; keeping default restored_external USBMux label")
return
try:
target_bytes = target_udid.encode("ascii")
except UnicodeEncodeError:
print(f"[-] RAMDISK_UDID must be ASCII, got: {target_udid!r}")
sys.exit(1)
marker_len = len(RESTORED_EXTERNAL_SERIAL_MARKER)
if len(target_bytes) > marker_len:
print(f"[-] RAMDISK_UDID too long for restored_external label ({len(target_bytes)} > {marker_len})")
print(f" RAMDISK_UDID={target_udid}")
sys.exit(1)
restored_external = os.path.join(mountpoint, RESTORED_EXTERNAL_PATH)
if not os.path.isfile(restored_external):
print(f"[-] Missing restored_external for USBMux label patch: {restored_external}")
sys.exit(1)
with open(restored_external, "rb") as f:
data = f.read()
off = data.find(RESTORED_EXTERNAL_SERIAL_MARKER)
if off < 0:
print("[-] Could not find default USBMux serial marker in restored_external")
sys.exit(1)
if data.find(RESTORED_EXTERNAL_SERIAL_MARKER, off + 1) >= 0:
print("[!] Multiple USBMux serial markers found in restored_external; patching first occurrence")
replacement = target_bytes + (b"\x00" * (marker_len - len(target_bytes)))
patched = data[:off] + replacement + data[off + marker_len :]
with open(restored_external, "wb") as f:
f.write(patched)
print(f" [+] Patched restored_external USBMux label to: {target_udid}")
# ══════════════════════════════════════════════════════════════════
# Ramdisk DMG building
# ══════════════════════════════════════════════════════════════════
@@ -397,6 +443,7 @@ def build_ramdisk(restore_dir, im4m_path, vm_dir, input_dir, output_dir, temp_di
run_sudo(
[gtar_bin, "-x", "--no-overwrite-dir", "-f", ssh_tar, "-C", mountpoint]
)
patch_restored_external_usbmux_label(mountpoint)
# Remove unnecessary files
for rel_path in RAMDISK_REMOVE:
+13
View File
@@ -9,6 +9,7 @@ set -euo pipefail
IRECOVERY="${IRECOVERY:-irecovery}"
IRECOVERY_ECID="${IRECOVERY_ECID:-}"
RAMDISK_UDID="${RAMDISK_UDID:-${RESTORE_UDID:-}}"
RAMDISK_DIR="${1:-Ramdisk}"
IRECOVERY_ARGS=()
@@ -24,6 +25,18 @@ if [[ -n "$IRECOVERY_ECID" ]]; then
echo "[*] Using ECID selector for irecovery: ${IRECOVERY_ECID}"
fi
echo "[*] Identity context for ramdisk_send:"
if [[ -n "$RAMDISK_UDID" ]]; then
echo " UDID: ${RAMDISK_UDID}"
else
echo " UDID: <unset>"
fi
if [[ -n "$IRECOVERY_ECID" ]]; then
echo " ECID: ${IRECOVERY_ECID}"
else
echo " ECID: <unset>"
fi
irecovery_cmd() {
"$IRECOVERY" "${IRECOVERY_ARGS[@]}" "$@"
}
+90 -5
View File
@@ -35,6 +35,7 @@ RAMDISK_SSH_INTERVAL="${RAMDISK_SSH_INTERVAL:-2}"
RAMDISK_SSH_PORT="${RAMDISK_SSH_PORT:-}"
RAMDISK_SSH_USER="${RAMDISK_SSH_USER:-root}"
RAMDISK_SSH_PASS="${RAMDISK_SSH_PASS:-alpine}"
IPROXY_UDID="${IPROXY_UDID:-}"
RAMDISK_SSH_PORT_EXPLICIT=0
if [[ -n "$RAMDISK_SSH_PORT" ]]; then
RAMDISK_SSH_PORT_EXPLICIT=1
@@ -42,6 +43,7 @@ fi
DEVICE_UDID=""
DEVICE_ECID=""
IPROXY_TARGET_UDID=""
JB_MODE=0
DEV_MODE=0
SKIP_PROJECT_SETUP=0
@@ -110,6 +112,84 @@ load_device_identity() {
echo "[+] Device identity loaded: UDID=${DEVICE_UDID} ECID=0x${DEVICE_ECID}"
}
list_usbmux_udids() {
local idevice_id_bin
idevice_id_bin="${PROJECT_ROOT}/.limd/bin/idevice_id"
if [[ ! -x "$idevice_id_bin" ]]; then
idevice_id_bin="$(command -v idevice_id || true)"
fi
[[ -x "$idevice_id_bin" ]] || return 0
"$idevice_id_bin" -l 2>/dev/null | tr -d '\r' | sed '/^[[:space:]]*$/d'
}
print_usbmux_udids() {
local -a udids
local udid
udids=(${(@f)$(list_usbmux_udids)})
if (( ${#udids[@]} == 0 )); then
echo " (none)"
return
fi
for udid in "${udids[@]}"; do
echo " - ${udid}"
done
}
resolve_iproxy_target_udid() {
local -a usbmux_udids ecid_matches
local udid
local ecid_lower
if [[ -n "$IPROXY_UDID" ]]; then
IPROXY_TARGET_UDID="$IPROXY_UDID"
echo "[*] Using explicit IPROXY_UDID override: ${IPROXY_TARGET_UDID}"
return
fi
usbmux_udids=(${(@f)$(list_usbmux_udids)})
echo "[*] USBMux IDs currently visible:"
print_usbmux_udids
(( ${#usbmux_udids[@]} > 0 )) \
|| die "No USBMux devices detected for iproxy. Ensure ramdisk has fully booted USB stack."
for udid in "${usbmux_udids[@]}"; do
if [[ "$udid" == "$DEVICE_UDID" ]]; then
IPROXY_TARGET_UDID="$udid"
echo "[+] iproxy target UDID matched restore UDID: ${IPROXY_TARGET_UDID}"
return
fi
done
ecid_lower="${DEVICE_ECID:l}"
ecid_matches=()
for udid in "${usbmux_udids[@]}"; do
if [[ "${udid:l}" == *"${ecid_lower}"* ]]; then
ecid_matches+=("$udid")
fi
done
if (( ${#ecid_matches[@]} == 1 )); then
IPROXY_TARGET_UDID="${ecid_matches[1]}"
echo "[+] iproxy target UDID matched ECID substring: ${IPROXY_TARGET_UDID}"
return
fi
if (( ${#usbmux_udids[@]} == 1 )); then
IPROXY_TARGET_UDID="${usbmux_udids[1]}"
echo "[!] Restore UDID (${DEVICE_UDID}) is not visible in ramdisk USBMux enumeration."
echo "[!] Falling back to the only available USBMux ID: ${IPROXY_TARGET_UDID}"
return
fi
die "Could not resolve iproxy target UDID from USBMux IDs. Set IPROXY_UDID explicitly."
}
port_is_listening() {
local port="$1"
lsof -n -t -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1
@@ -450,9 +530,10 @@ start_iproxy() {
local iproxy_bin
iproxy_bin="${PROJECT_ROOT}/.limd/bin/iproxy"
[[ -x "$iproxy_bin" ]] || die "iproxy not found at $iproxy_bin (run: make setup_libimobiledevice)"
[[ -n "$DEVICE_UDID" ]] || die "Device UDID is empty; cannot start isolated iproxy"
[[ -n "$DEVICE_UDID" ]] || die "Device UDID is empty; cannot resolve iproxy target"
choose_ramdisk_ssh_port
resolve_iproxy_target_udid
if port_is_listening "$RAMDISK_SSH_PORT"; then
if [[ "$RAMDISK_SSH_PORT_EXPLICIT" == "1" ]]; then
@@ -466,8 +547,8 @@ start_iproxy() {
mkdir -p "$LOG_DIR"
: > "$IPROXY_LOG"
echo "[*] Starting iproxy ${RAMDISK_SSH_PORT} -> 22 (UDID=${DEVICE_UDID})..."
("$iproxy_bin" -u "$DEVICE_UDID" "$RAMDISK_SSH_PORT" 22 >"$IPROXY_LOG" 2>&1) &
echo "[*] Starting iproxy ${RAMDISK_SSH_PORT} -> 22 (target_udid=${IPROXY_TARGET_UDID}, restore_udid=${DEVICE_UDID}, ecid=0x${DEVICE_ECID})..."
("$iproxy_bin" -u "$IPROXY_TARGET_UDID" "$RAMDISK_SSH_PORT" 22 >"$IPROXY_LOG" 2>&1) &
IPROXY_PID=$!
sleep 1
@@ -530,6 +611,9 @@ wait_for_ramdisk_ssh() {
done
echo "[-] Timed out waiting for ramdisk SSH readiness."
echo "[-] Identity context: restore_udid=${DEVICE_UDID}, ecid=0x${DEVICE_ECID}, iproxy_target_udid=${IPROXY_TARGET_UDID}"
echo "[-] USBMux IDs at timeout:"
print_usbmux_udids
if [[ -n "$IPROXY_LOG" ]]; then
echo "[-] iproxy log tail:"
tail -n 40 "$IPROXY_LOG" 2>/dev/null || true
@@ -637,8 +721,9 @@ main() {
start_boot_dfu
load_device_identity
wait_for_recovery
run_make "Ramdisk" ramdisk_build
run_make "Ramdisk" ramdisk_send IRECOVERY_ECID="0x$DEVICE_ECID"
run_make "Ramdisk" ramdisk_build RAMDISK_UDID="$DEVICE_UDID"
echo "[*] Ramdisk identity context: restore_udid=${DEVICE_UDID} ecid=0x${DEVICE_ECID}"
run_make "Ramdisk" ramdisk_send IRECOVERY_ECID="0x$DEVICE_ECID" RAMDISK_UDID="$DEVICE_UDID"
start_iproxy
wait_for_ramdisk_ssh