From d1e5d324a4d0d651e6d31162ff876ad396973b7e Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Tue, 4 Aug 2026 16:14:42 +0200 Subject: [PATCH] WIP --- .github/workflows/ios-gadget-spike.yml | 75 ++++++++++++-------------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/.github/workflows/ios-gadget-spike.yml b/.github/workflows/ios-gadget-spike.yml index 03d8e14..1af9492 100644 --- a/.github/workflows/ios-gadget-spike.yml +++ b/.github/workflows/ios-gadget-spike.yml @@ -346,12 +346,15 @@ jobs: ps -p "$(awk '{print $2}' "$RUNNER_TEMP/baseline.log")" xcrun simctl terminate "$UDID" "$BUNDLE_ID" - - name: Find a gadget version the app survives + - name: Find a gadget version that can run a script here run: | - # Gadget 17.16.4 segfaults during its own initialisation here: listen mode with no - # script of ours loaded crashes identically to a full run, and 16.7.19 doesn't crash at - # all. So rather than pinning a version, walk back from the newest until one survives. - # That gets us running, and shows where this broke. + # Recent gadgets segfault on this simulator: 17.16.4 dies during its own initialisation + # with nothing of ours loaded, and 17.16.0 survives that but dies as soon as it runs a + # script. So rather than pinning a version, walk back from the newest until one works, + # which gets us running and shows where this broke. + # + # N.b. tested in script mode with a trivial script, not listen mode: script mode is what + # we actually need, and 17.16.0 proves surviving without one means nothing. BUNDLE_DIR="$(xcrun simctl get_app_container "$UDID" "$BUNDLE_ID" app)" echo "BUNDLE_DIR=$BUNDLE_DIR" >> $GITHUB_ENV echo "Installed at: $BUNDLE_DIR" @@ -361,9 +364,15 @@ jobs: mkdir -p "$BUNDLE_DIR/Frameworks" cp "$RUNNER_TEMP/spike.js" "$BUNDLE_DIR/Frameworks/spike.js" - # Listen mode with on_load resume: the gadget initialises, but runs nothing of ours and - # doesn't hold the app waiting for a client, so this tests the gadget by itself. - printf '%s\n' '{ "interaction": { "type": "listen", "on_load": "resume" } }' \ + cat > "$BUNDLE_DIR/Frameworks/trivial.js" < "$BUNDLE_DIR/Frameworks/FridaGadget.config" WORKING="" @@ -384,6 +393,7 @@ jobs: codesign --force --sign - "$BUNDLE_DIR" # The bundle's contents just changed xcrun simctl terminate "$UDID" "$BUNDLE_ID" > /dev/null 2>&1 || true + rm -f "$DATA_DIR/trivial-ran.txt" # Otherwise a previous version's marker counts if ! SIMCTL_CHILD_DYLD_INSERT_LIBRARIES="$BUNDLE_DIR/Frameworks/FridaGadget.dylib" \ xcrun simctl launch "$UDID" "$BUNDLE_ID" > "$RUNNER_TEMP/attempt.log" 2>&1 @@ -397,14 +407,20 @@ jobs: PID="$(awk '{print $2}' "$RUNNER_TEMP/attempt.log")" sleep 10 - if ps -p "$PID" > /dev/null 2>&1; then - echo " the app survived (pid $PID)" - WORKING="$VERSION" - xcrun simctl terminate "$UDID" "$BUNDLE_ID" > /dev/null 2>&1 || true - break + if ! ps -p "$PID" > /dev/null 2>&1; then + echo " the app crashed (pid $PID)" + continue fi - echo " the app crashed (pid $PID)" + if [ ! -f "$DATA_DIR/trivial-ran.txt" ]; then + echo " the app survived, but the gadget never ran the script (pid $PID)" + continue + fi + + echo " the app survived & ran our script (pid $PID)" + WORKING="$VERSION" + xcrun simctl terminate "$UDID" "$BUNDLE_ID" > /dev/null 2>&1 || true + break done if [ -z "$WORKING" ]; then @@ -417,29 +433,12 @@ jobs: echo "Using Frida $WORKING" echo "GADGET_VERSION=$WORKING" >> $GITHUB_ENV - - name: Check script mode works, and whether its output reaches the log + - name: Check whether the gadget's output reaches the simulator log run: | - # Two separate questions: will the gadget run a script of ours at all, and does its - # console output reach the simulator log? The second decides how much the log-based - # checks below are worth, so the marker file is the signal that can't be lost. - cat > "$BUNDLE_DIR/Frameworks/trivial.js" < "$BUNDLE_DIR/Frameworks/FridaGadget.config" - codesign --force --sign - "$BUNDLE_DIR" - + # The search above leaves the working gadget & the trivial script in place, and has + # already proved script mode runs, so this answers only the remaining question: does the + # gadget's console output show up in the log? That decides how much the log-based checks + # below are worth, and so whether our scripts need to report on themselves. rm -f "$DATA_DIR/trivial-ran.txt" xcrun simctl spawn "$UDID" log stream --level debug \ @@ -464,10 +463,6 @@ jobs: "marker file & proxy evidence mean anything below" fi - # Fatal, because nothing else below can work without it: - test -f "$DATA_DIR/trivial-ran.txt" - echo "=> the gadget ran our script" - - name: Launch the app with the gadget injected run: | # Started before the app & given time to attach, since our scripts log within