Conversation
257f146 to
72b384a
Compare
72b384a to
0950f1b
Compare
0950f1b to
4c27cf6
Compare
4c27cf6 to
dc4dc2b
Compare
|
Current build: @il-steffen , @schumilo would you like to review this PR ? I documented most of the Nyx API here, with examples , and i'd like to already merge this already, if there are no other feedback. Thanks ! |
|
Generally, the documentation already looks good! However, here are some nits that I found:
"The while() loop in our guest agent is not actually needed anymore." -> That is not entirely correct. So in case the user wants to gain some extra performance, disabling snapshot mode might be beneficial, which will require a loop. However, disabling snapshot mode does not mean that the actual snapshot is not taken and restored in case of timeouts or crashes. -> This obviously depends on whether the target or agent supports fuzzing without restoring the snapshot after each and every execution. That's why there is the
Maybe it's worth mentioning that with this approach, around 20-26 Bytes are overwritten (depending on whether the target runs in protected or long mode; however, I'm actually not quite sure if protected mode is still supported; 32-Bit userland applications running in long mode work just fine).
I would add a warning that hprintfs should be seen more as a debug mechanism for agent "debug" builds. Once you run the fuzzer, hprintfs called in the fuzzing loop will significantly impact performance. And instead of using this hypercall directly, you should always use the hprintf wrapper instead (especially if you need format string capabilities).
Running the fuzzer without an enabled CR3 filter is actually not supported if Intel PT mode is enabled and also by the actual decoding library libxdc. This hypercall must be called at least once before If Intel PT mode is disabled, this hypercall is not required, but it is still good practice to include it in case the user wants to use Intel PT mode.
The reason for this hypercall is that in the case of userland fuzzing, the agent is supposed to make the corresponding code ranges persistent (and prefetched) in the guest's memory by calling mlock() so that the hypervisor has a chance to dump the required pages for the PT decoder. However, this step is most likely no longer required since code pages can now be dumped even if they are not yet present in the guest's memory at the time of creating the snapshot (for that, we are using hardware breakpoints and some other hacks). Nevertheless, it might be reasonable to prefetch the code pages for better fuzzing performance.
For files larger than 4KB, this hypercall needs to be called multiple times for each page. The first call needs to reset the append field, while the following ones need to set the append byte (otherwise, the resulting file will be <= 4KB in size and will only contain the content of the last call).
In addition to the two hypercalls mentioned, the hypercall https://github.com/nyx-fuzz/QEMU-Nyx/blob/qemu-nyx-4.2.0/nyx/hypercall/hypercall.c#L912 This hypercall basically solves the issue of changing CR3 values in case of disabled snapshots and an in-guest employed fork server without requiring to call 3 different snapshots in a row.
This hypercall will create a Nyx pre-snapshot if QEMU-Nyx is launched in a specific mode. You can find some documentation regarding the pre-snapshot feature here: https://github.com/nyx-fuzz/Nyx/blob/main/docs/01-Nyx-VMs.md In case QEMU-Nyx is started without enabling the pre-snapshot capability, this hypercall will effectively do nothing.
This hypercall serves basically the same purpose as
This hypercall excludes a single page frame from being reset by the snapshot restore mechanism. This hypercall expects a page-aligned virtual address of a single page at a time (but can be called multiple times to exclude a number of page frames from being reset). |
This relationship is good to point out + document also the elements of the buffer structures (agent_config, host_config, ip filter list, ...?). On the host side, Note that the ijon_bitmap is not supported in the frontend - I think we allocate the default size buffer to make qemu happy but don't parse it as part of overall bitmap (qemu.py).
Note that this only has the most basic functions and even that has to be changed for anything not Linux. I was thinking to remove the variable args hprintf() there as well since it's been incompatible even with Linux kernel and Zephyr, who have all the types but slightly different function/macro names. |
dc4dc2b to
c6a77d7
Compare
|
Thanks @schumilo and @il-steffen for your comments ! Lastest build:
I managed to call What about introducing conditional compilation with |
Refactor the hypercall API reference.
TODO: