Fixed qemu usermode snapshot (#66)

* Fixed qemu usermode snapshot

---------

Co-authored-by: Romain Malmain <romain.malmain@pm.me>
This commit is contained in:
cube0x8 2024-04-26 16:56:20 +03:00 committed by Romain Malmain
parent c6d56fc94c
commit 43302cdc39
4 changed files with 30 additions and 10 deletions

View File

@ -153,6 +153,12 @@ static PageFlagsNode *pageflags_find(target_ulong start, target_ulong last)
return n ? container_of(n, PageFlagsNode, itree) : NULL; return n ? container_of(n, PageFlagsNode, itree) : NULL;
} }
//// --- Begin LibAFL code ---
IntervalTreeRoot * pageflags_get_root(void) {
return &pageflags_root;
}
//// --- End LibAFL code ---
static PageFlagsNode *pageflags_next(PageFlagsNode *p, target_ulong start, static PageFlagsNode *pageflags_next(PageFlagsNode *p, target_ulong start,
target_ulong last) target_ulong last)
{ {

View File

@ -26,6 +26,10 @@
#include "hw/core/cpu.h" #include "hw/core/cpu.h"
#include "qemu/rcu.h" #include "qemu/rcu.h"
//// --- Begin LibAFL code ---
#include "qemu/interval-tree.h"
//// --- End LibAFL code ---
/* some important defines: /* some important defines:
* *
* HOST_BIG_ENDIAN : whether the host cpu is big endian and * HOST_BIG_ENDIAN : whether the host cpu is big endian and
@ -192,6 +196,10 @@ int page_get_flags(target_ulong address);
void page_set_flags(target_ulong start, target_ulong last, int flags); void page_set_flags(target_ulong start, target_ulong last, int flags);
void page_reset_target_data(target_ulong start, target_ulong last); void page_reset_target_data(target_ulong start, target_ulong last);
//// --- Begin LibAFL code ---
IntervalTreeRoot* pageflags_get_root(void);
//// --- End LibAFL code ---
/** /**
* page_check_range * page_check_range
* @start: first byte of range * @start: first byte of range

View File

@ -14,4 +14,4 @@ struct libafl_mapinfo {
}; };
IntervalTreeNode * libafl_maps_first(IntervalTreeRoot * map_info); IntervalTreeNode * libafl_maps_first(IntervalTreeRoot * map_info);
IntervalTreeNode * libafl_maps_next(IntervalTreeNode *node, struct libafl_mapinfo* ret); IntervalTreeNode * libafl_maps_next(IntervalTreeNode *pageflags_maps_node, IntervalTreeRoot *proc_maps_node, struct libafl_mapinfo* ret);

View File

@ -13806,27 +13806,33 @@ IntervalTreeNode * libafl_maps_first(IntervalTreeRoot * map_info) {
return interval_tree_iter_first(map_info, 0, -1); return interval_tree_iter_first(map_info, 0, -1);
} }
IntervalTreeNode * libafl_maps_next(IntervalTreeNode *node, struct libafl_mapinfo* ret) { IntervalTreeNode * libafl_maps_next(IntervalTreeNode *pageflags_maps_node, IntervalTreeRoot *proc_maps_root, struct libafl_mapinfo* ret) {
ret->is_valid = false; ret->is_valid = false;
if (!node || !ret) { if (!pageflags_maps_node || !ret) {
return NULL; return NULL;
} }
MapInfo *e = container_of(node, MapInfo, itree); MapInfo *e;
IntervalTreeNode *proc_map_interval_node;
if (h2g_valid(e->itree.start)) { if (h2g_valid(pageflags_maps_node->start)) {
unsigned long min = e->itree.start; unsigned long min = pageflags_maps_node->start;
unsigned long max = e->itree.last + 1; unsigned long max = pageflags_maps_node->last + 1;
int flags = page_get_flags(h2g(min)); int flags = page_get_flags(h2g(min));
max = h2g_valid(max - 1) ? max = h2g_valid(max - 1) ?
max : (uintptr_t) g2h_untagged(GUEST_ADDR_MAX) + 1; max : (uintptr_t) g2h_untagged(GUEST_ADDR_MAX) + 1;
// I guess this is useless? we are walking the entire pageflags_root tree, so we should always have a valid node
if (!page_check_range(h2g(min), max - min, flags)) { if (!page_check_range(h2g(min), max - min, flags)) {
return libafl_maps_next(interval_tree_iter_next(node, 0, -1), ret); return libafl_maps_next(interval_tree_iter_next(pageflags_maps_node, 0, -1), proc_maps_root, ret);
} }
// Should we check for NULL? Not sure, but if an inteval is in pageflags, then it should be in proc_maps too
proc_map_interval_node = interval_tree_iter_first(proc_maps_root, min, min);
e = container_of(proc_map_interval_node, MapInfo, itree);
int libafl_flags = 0; int libafl_flags = 0;
if (flags & PAGE_READ) libafl_flags |= PROT_READ; if (flags & PAGE_READ) libafl_flags |= PROT_READ;
if (flags & PAGE_WRITE_ORG) libafl_flags |= PROT_WRITE; if (flags & PAGE_WRITE_ORG) libafl_flags |= PROT_WRITE;
@ -13840,9 +13846,9 @@ IntervalTreeNode * libafl_maps_next(IntervalTreeNode *node, struct libafl_mapinf
ret->flags = libafl_flags; ret->flags = libafl_flags;
ret->is_priv = e->is_priv; ret->is_priv = e->is_priv;
return interval_tree_iter_next(node, 0, -1); return interval_tree_iter_next(pageflags_maps_node, 0, -1);
} else { } else {
return libafl_maps_next(interval_tree_iter_next(node, 0, -1), ret); return libafl_maps_next(interval_tree_iter_next(pageflags_maps_node, 0, -1), proc_maps_root, ret);
} }
} }