8000 Windows: attach fails with TransportError "timeout was reached" when frida-helper is slow (GDBus 25 s default timeout) · Issue #1272 · frida/frida-core · GitHub
[go: up one dir, main page]

Skip to content

Windows: attach fails with TransportError "timeout was reached" when frida-helper is slow (GDBus 25 s default timeout) #1272

Open

Description

@Albasha0x0

Summary

On Windows, device.attach() to a 32-bit program fails with TransportError: timeout was reached when frida-helper is slow to answer. The failure comes at exactly 25 s, which is GLib's default D-Bus call timeout. throw_dbus_error maps the GIO timeout to Frida.Error.TRANSPORT, so a slow helper reads as a broken transport instead of a timeout.

We hit this on a heavily loaded machine: an attach to a freshly spawned 32-bit program took 42.7 s and failed with this error. On a quiet machine the same attach passes 20 of 20 times. The repro below makes it deterministic by suspending the helper.

Environment

  • frida 17.24.3 (Python bindings), Python 3.12.4
  • Windows 11 x64
  • Target: a 32-bit program (SysWOW64), injected through frida-helper

Repro

The script starts the helper with one attach and detach, suspends only the helper processes that are its own children for 40 s, then spawns a 32-bit program and attaches to it.

import ctypes, os, subprocess, sys, threading, time
import frida

PROGRAM = [r"C:\Windows\SysWOW64\ping.exe", "-n", "60", "127.0.0.1"]
HOLD = 40
ntdll = ctypes.WinDLL("ntdll")
kernel32 = ctypes.WinDLL("kernel32")

def own_helpers():
    q = ("Get-CimInstance Win32_Process | Where-Object { $_.ParentProcessId -eq %d "
         "-and $_.Name -like 'frida-helper*' } | ForEach-Object { $_.ProcessId }" % os.getpid())
    out = subprocess.run(["powershell", "-NoProfile", "-Command", q],
                         capture_output=True, text=True).stdout
    return [int(x) for x in out.split() if x.isdigit()]

print("frida", frida.__version__, "python", sys.version.split()[0])
device = frida.get_local_device()
warm = device.spawn(PROGRAM)          # starts the helper; it stays for the next attach
device.attach(warm).detach()
device.kill(warm)

handles = []
for pid in own_helpers():
    h = kernel32.OpenProcess(0x0800, False, pid)   # PROCESS_SUSPEND_RESUME
    ntdll.NtSuspendProcess(h)
    handles.append(h)
timer = threading.Timer(HOLD, lambda: [ntdll.NtResumeProcess(h) for h in handles])
timer.start()

t0 = time.time()
pid = device.spawn(PROGRAM)
try:
    device.attach(pid).detach()
    print("attached at %.1f s" % (time.time() - t0))
except Exception as e:
    print("attach failed at %.1f s: %s: %s" % (time.time() - t0, type(e).__name__, e))
finally:
    timer.join()
    for h in handles:
        kernel32.CloseHandle(h)
    device.kill(pid)

Observed

attach failed at 25.0 s: TransportError: timeout was reached

Expected

The attach waits for the helper, bounded by the caller's cancellable, or, if a limit applies, fails with TimedOutError, so a caller can tell a slow helper from a broken transport and retry.

Related

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0