Hi Alex, hi Pierrick,
I'm taking the freedom to reply to both of you at the same time, I hope
you don't mind :)
On 04/08/2025 18:05, Alex Bennée wrote:
>> I was wondering whether the QEMU community would be open to extending
>> the plugin API so that a plugin can fully emulate a syscall without
>> the original syscall being executed by QEMU.
>
> I will defer to the *-user maintainers here. One thing we are keen to
> avoid is plugins being used as a mechanism to work around the GPL
> requirements of QEMU itself. It would be useful if you could outline
> the use case for a plugin doing the emulation itself?
On 04/08/2025 19:01, Pierrick Bouvier wrote:
> Before talking about the how and what, it could be useful to explain
> why it's needed to replace syscalls.
I'm using QEMU as a tool for security research in the context of my
studies. I'm analyzing black-box binaries, i.e., I don't have source
code access and ideally don't want to spend much time statically reverse
engineering the binaries (there might be complex logic, code
obfuscation, etc. at play). Emulating syscalls myself instead of passing
them through to the host OS has two advantages:
1. I can sandbox the (untrusted) binaries.
2. I can make the binaries execute more of their code by simulating an
environment different to the one they're actually running in (e.g., by
returning values from syscalls that are required to pass certain
conditional checks in the code).
Both could in theory also be achieved by using utilities like seccomp
filters or eBPF programs. However, I'd like to have arbitrarily complex
logic to determine the outcome of a syscall, which quickly reaches its
limits with the aforementioned approaches, in addition to the overhead
of switching into and out of the kernel (negligible for a single
execution but quickly adds up if we're talking about automated
analyses). Further, I'd like my code to be able to profit from future
improvements to QEMU and therefore implement it as a plugin (which is
likely more portable than constantly forward-porting patches from a
custom QEMU fork, as the majority of security research is doing it
currently).
As a contrived example, I might want to inspect the arguments to a read
syscall and return data accordingly. Say, I know from a previous open
syscall that a file descriptor refers to /dev/random, I might want to
return exactly the (arguably non-random) bytes required to pass a
certain condition when a read syscall on that file descriptor is issued.
> Another option would be to have a set_pc function that would restart
> the execution at new PC. Then the vcpu_syscall_cb callback could set
> the PC to post the syscall with whatever state it wants to set up.
Such a set_pc functionality is already covered with the register write
API, as long as I have a handle to the PC register, right? Please do
correct me if I'm misunderstanding something here!
Thanks for your input,
Florian