Commit Graph
8 Commits
Author SHA1 Message Date
Ole André Vadla Ravnås 11c9de137d emulator: Prewarm backend before listing AVDs
availability() reads the AVD cache that only reloadAVDs()
fills, so the check found no AVD until prewarm() ran. Call
prewarm() first.
2026-09-30 15:12:13 +02:00
Ole André Vadla Ravnås f6ae01c34f core: Tell a System.map from a kernel image
QEMU hands over a System.map, which LinuxKernelImage cannot read, so no
barebone device was added. Let each machine say which kind it has.
2026-09-26 21:54:46 +02:00
Ole André Vadla Ravnås 0ef6833cd6 core: Stamp the emulator check's notes
Which part of a run is slow, or where one stopped, was guesswork. The
notes now carry the elapsed time and say when the device, the session
and the script arrive.
2026-09-19 16:45:03 +02:00
Ole André Vadla Ravnås cce9f40a4f core: Take the kernel image as an object
frida-core now reads a kernel once and answers what it names, so the
image config carries that rather than a path, and the vsock probe asks
it for the symbol instead of searching the image for the word.

That probe was never a symbol lookup: kallsyms stores its names
compressed, so the match came from whatever else in the kernel happens
to spell vsock. It took an LZ4 inflater of its own to look, which goes
with it.
2026-09-17 19:41:59 +02:00
Ole André Vadla Ravnås 87485eb0e5 core: Reach the emulator's hostlink on Windows
The emulator bridges a guest's vsock to a host UNIX socket, which
Windows has none of, so the guest is reached over the virtio-serial
hostlink there whatever its kernel offers. That channel is opened
through QMP, which QEMU serves over a named pipe on Windows -- and it
holds the machine still until something connects to that pipe, then
gives the pipe up for good once the connection goes.

So the pipe is opened here, as soon as QEMU is spawned and before the
guest is waited on, and held for the barebone backend to adopt by
handle. Waiting for adb first would have deadlocked: the guest cannot
boot until the pipe is answered.

The transport carries the QMP address as a string now rather than a
socket URL, since each host spells it differently.

Also drops the single-core launch, which nothing turned out to need.
2026-09-17 13:13:47 +02:00
Ole André Vadla Ravnås 53813d1505 core: Take the AVD's own ABI, not arm64
An AVD's config names the ABI it boots, and the agent that gets
injected has to match it, so the ABI is read rather than assumed and
the flavor follows from it. Everything on a Windows host is x86_64,
where the old arm64 assumption would have asked for an agent that
does not fit.

Which is as far as it goes for now: Frida reaches the emulator's QEMU
through a gdbstub shim that resolves aarch64_cpu_gdb_write_register,
so an x86_64 guest boots, streams its display and reports its stub,
then fails inside instrumentation. The backend offers only what can
actually be injected into, and says which ABIs it did find when that
leaves nothing:

    Frida can only instrument arm64 AVDs, and the ones installed are
    x86-64. Create one in Android Studio.
2026-09-17 13:13:47 +02:00
Ole André Vadla Ravnås 761ee194fb core: Run the Android emulator on Windows
The emulator's control channel was the only thing pulling grpc-swift
in, and with it swift-nio-ssl, which does not build on Windows at all
-- it has no branch for the platform and its PosixPort reaches for
mlock, lstat and readlink. Nothing here wants TLS: the endpoint is
plaintext on the loopback, and only seven calls are ever made.

So the wire is spoken directly. GRPCConnection opens one HTTP/2
stream per call over swift-nio-http2 and frames length-prefixed
protobuf into it; EmulatorControlClient names the seven. That drops
grpc-swift-2, grpc-swift-nio-transport, grpc-swift-protobuf and
swift-nio-ssl from the graph, along with 7840 lines of generated
service stubs. The generated messages stay.

The rest is what running it on Windows turned up:

  - AVD discovery split on "\n" and trimmed only .whitespaces, so
    every name kept a trailing \r and every AVD was dropped.
  - An AVD config spells its paths with backslashes, which URL keeps
    as ordinary characters rather than separators.
  - emulator and adb want .exe, and the SDK sits under LOCALAPPDATA.
  - Port reservation and process lookup move into HostPort and
    HostProcessLookup, which QemuMachine's two copies also wanted.
  - The launcher re-execs into QEMU there, so the discovery ini is
    named after that process; the one naming this launch's debug port
    is taken when the launcher's own is absent.

Frames still arrive through a mapping rather than the socket:
CreateFileMapping backs the same file:// handle the emulator is
handed elsewhere.

A guest without vsock is refused outright on Windows, where the
virtio-serial fallback would ask QEMU for a QMP UNIX socket and be
told "unix sockets are not available on windows".

LUMA_EMULATOR_DISPLAY_ONLY drives launch, control and streaming
without a guest agent. Against a Pixel_2 AVD it reports a 1080x1920
first frame and nine more in three seconds.
2026-09-17 13:13:47 +02:00
Ole André Vadla Ravnås 55a4aa7033 tools: Add an Android emulator check harness
Drive the whole Android-emulator path headless -- launch an AVD, inject
the barebone agent, run one script -- for a fast feedback loop without
the UI. Links a local frida devkit named by LUMA_FRIDA_DEVKIT.
2026-09-16 19:17:40 +02:00