8000 dtx: Tolerate richer response shapes and name errors by ignuslabs · Pull Request #1225 · frida/frida-core · GitHub
[go: up one dir, main page]

Skip to content

dtx: Tolerate richer response shapes and name errors - #1225

Open
ignuslabs wants to merge 1 commit into
frida:mainfrom
ignuslabs:fix/dtx-tolerant-response-parsing
Open

ignuslabs wants to merge 1 commit into
frida:mainfrom
ignuslabs:fix/dtx-tolerant-response-parsing

Conversation

@ignuslabs
Copy link
Copy Markdown
Contributor

Addressing frida/frida#3719

Problem

Three DTX methods — processIdentifierForBundleIdentifier:,
isPidDebuggable:, and
launchSuspendedProcessWithDevicePath:bundleIdentifier:environment:arguments:options:
— previously cast the reply directly to NSNumber and threw
Error.PROTOCOL ("Malformed response") on anything else.

On iOS 16 the remote service has been observed returning richer shapes
(e.g. NSDictionary wrappers with conventional result keys, or error
payloads such as NSError / dicts carrying NSLocalizedDescription),
which the strict cast rejected. The result was an opaque
Malformed response failure with no indication of which invocation
failed or why — impossible to debug from a bug report.

Fix

  • Introduce parse_uint_response / parse_bool_response helpers that
    accept NSNumber, parse numeric strings, or look up conventional
    result keys (pid, processIdentifier, result, value, …)
    inside an NSDictionary.
  • Detect error payloads via try_extract_error_response_details,
    which recognises NSError, string replies, and dict-wrapped errors
    (NSError, NSLocalizedDescription, message, …), and surface
    them as Error.NOT_SUPPORTED carrying the originating method name.
  • When no shape matches, describe_response stringifies the payload
    type and a truncated representation so future breakage is
    actionable instead of opaque.
  • Extend DTXChannel with a PendingResponse record that stashes the
    originating method name alongside each pending promise, so ERROR
    frames can report which invocation failed. The error-path
    formatting is consolidated through the new shared format_nserror
    helper.

No behaviour change for the existing happy path: an NSNumber reply
still resolves to the same value.

Testing

  • Builds clean on macOS arm64 with MACOS_CERTID=- make in the
    top-level frida tree (full frida-gum + frida-core Vala + C pipeline).
  • ninja src/libfrida-core.a explicitly rebuilds the Vala compile
    pass over every frida-core .vala file, including the patched
    dtx.vala, which confirms the new helpers and PendingResponse
    inner class typecheck against the existing DTX code.
  • iOS-device-side verification of the new error path requires a
    reproducer on a physical device; this change is a strict superset
    of the prior cast behaviour so it is safe to merge even without
    such a reproducer in CI.

  The DTX methods processIdentifierForBundleIdentifier:,
  isPidDebuggable:, and launchSuspendedProcessWithDevicePath:...
  previously insisted on an NSNumber reply and raised a generic
  PROTOCOL error on anything else. iOS 16 has been observed
  returning NSDictionary wrappers and error payloads that this
  strict cast rejected, aborting the whole flow with no useful
  diagnostic.

  Route those calls through parse_uint_response / parse_bool_response
  helpers that accept NSNumber, parse numeric strings, or look up
  conventional result keys inside an NSDictionary, and surface
  NSError / dictionary-wrapped error payloads via
  try_extract_error_response_details with the originating method
  name. Stash the pending method name on DTXChannel so ERROR frames
  can report which invocation failed and format the NSError through
  the shared format_nserror helper, and fall back to
  describe_response for any unexpected shape so future breakage is
  actionable.
@oleavr oleavr left a comment
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! 🙌 Some further refinement is needed:

Comment thread src/fruity/dtx.vala
"Result",
"value",
"Value",
};
@oleavr oleavr Apr 17, 2026 •
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Here and elsewhere:) This is a little too fuzzy/defensive for my taste. Can we make this more explicit? Each specific caller should know what shapes exist for the specific call, and use helper functions to avoid duplication.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0