diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 59d32d2ef1..05bf2ceec9 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -49,7 +49,7 @@
#include "nyx/hypercall/hypercall.h"
#include "nyx/synchronization.h"
#include "nyx/debug.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include "nyx/interface.h"
#include "nyx/fast_vm_reload_sync.h"
#include "nyx/snapshot/memory/backend/nyx_dirty_ring.h"
@@ -2866,11 +2866,6 @@ int kvm_device_access(int fd, int group, uint64_t attr,
return err;
}
-#ifdef QEMU_NYX
-int kvm_has_vapic(void){
- return !kvm_check_extension(kvm_state, KVM_CAP_VAPIC);
-}
-#endif
bool kvm_has_sync_mmu(void)
{
diff --git a/hw/char/serial.c b/hw/char/serial.c
index a5034ae4ef..23737c56dd 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -35,7 +35,7 @@
#include "qemu/error-report.h"
#include "trace.h"
#ifdef QEMU_NYX
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#endif
//#define DEBUG_SERIAL
diff --git a/memory.c b/memory.c
index f741b142a8..2bd35b6262 100644
--- a/memory.c
+++ b/memory.c
@@ -36,7 +36,7 @@
#include "migration/vmstate.h"
#ifdef QEMU_NYX
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include "nyx/fast_vm_reload.h"
#endif
diff --git a/nyx/Makefile.objs b/nyx/Makefile.objs
index 197f9121c6..5400116161 100644
--- a/nyx/Makefile.objs
+++ b/nyx/Makefile.objs
@@ -3,10 +3,9 @@ memory_access.o \
interface.o \
fast_vm_reload.o \
fast_vm_reload_sync.o \
-printk.o synchronization.o \
+synchronization.o \
page_cache.o \
kvm_nested.o \
-state.o \
debug.o \
auxiliary_buffer.o \
mmh3.o \
@@ -31,5 +30,7 @@ snapshot/memory/backend/nyx_dirty_ring.o \
hypercall/hypercall.o \
hypercall/configuration.o \
hypercall/debug.o \
+state/state.o \
+state/snapshot_state.o \
pt.o
diff --git a/nyx/auxiliary_buffer.c b/nyx/auxiliary_buffer.c
index 72f25924a3..46e784032d 100644
--- a/nyx/auxiliary_buffer.c
+++ b/nyx/auxiliary_buffer.c
@@ -23,7 +23,7 @@ along with QEMU-PT. If not, see .
#include
#include
#include
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include "nyx/debug.h"
/* experimental feature (currently broken)
@@ -161,15 +161,11 @@ void check_auxiliary_config_buffer(auxilary_buffer_t* auxilary_buffer, auxilary_
}
void set_crash_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer){
- VOLATILE_WRITE_8(auxilary_buffer->result.crash_found, 1);
-}
-
-void set_asan_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer){
- VOLATILE_WRITE_8(auxilary_buffer->result.asan_found, 1);
+ VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_crash);
}
void set_timeout_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer){
- VOLATILE_WRITE_8(auxilary_buffer->result.timeout_found, 1);
+ VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_timeout);
}
void set_reload_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer){
@@ -180,65 +176,32 @@ void set_pt_overflow_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer)
VOLATILE_WRITE_8(auxilary_buffer->result.pt_overflow, 1);
}
-void set_exec_done_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t sec, uint32_t usec){
+void set_exec_done_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t sec, uint32_t usec, uint32_t num_dirty_pages){
VOLATILE_WRITE_8(auxilary_buffer->result.exec_done, 1);
- VOLATILE_WRITE_8(auxilary_buffer->result.runtime_sec, sec);
+ VOLATILE_WRITE_32(auxilary_buffer->result.runtime_sec, sec);
VOLATILE_WRITE_32(auxilary_buffer->result.runtime_usec, usec);
+ VOLATILE_WRITE_32(auxilary_buffer->result.dirty_pages, num_dirty_pages);
}
-void flush_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer){
- memset(&auxilary_buffer->result.hprintf, 0x0, sizeof(auxilary_buffer_result_t)-2);
-
-
- //memset(&(auxilary_buffer->result) + offsetof(auxilary_buffer_result_t, hprintf), 0x0, sizeof(auxilary_buffer_result_t) - offsetof(auxilary_buffer_result_t, hprintf));
-
- /*
- VOLATILE_WRITE_8(auxilary_buffer->result.exec_done, 0);
- VOLATILE_WRITE_8(auxilary_buffer->result.hprintf, 0);
-
-
- VOLATILE_WRITE_8(auxilary_buffer->result.crash_found, 0);
- VOLATILE_WRITE_8(auxilary_buffer->result.asan_found, 0);
- VOLATILE_WRITE_8(auxilary_buffer->result.timeout_found, 0);
- VOLATILE_WRITE_8(auxilary_buffer->result.reloaded, 0);
- VOLATILE_WRITE_8(auxilary_buffer->result.pt_overflow, 0);
-
- VOLATILE_WRITE_8(auxilary_buffer->result.runtime_sec, 0);
- VOLATILE_WRITE_32(auxilary_buffer->result.runtime_usec, 0);
-
- VOLATILE_WRITE_8(auxilary_buffer->result.page_not_found, 0);
- VOLATILE_WRITE_64(auxilary_buffer->result.page_addr, 0);
-
- VOLATILE_WRITE_8(auxilary_buffer->result.payload_buffer_write_attempt_found, 0);
-
- VOLATILE_WRITE_32(auxilary_buffer->result.dirty_pages, 0);
- VOLATILE_WRITE_32(auxilary_buffer->result.pt_trace_size, 0);
- */
-
-}
void set_hprintf_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len){
VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, MISC_SIZE-2));
volatile_memcpy((void*)&auxilary_buffer->misc.data, (void*)msg, (size_t)MIN(len, MISC_SIZE-2));
- VOLATILE_WRITE_8(auxilary_buffer->result.hprintf, 1);
+ VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_hprintf);
}
void set_crash_reason_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len){
VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, MISC_SIZE-2));
volatile_memcpy((void*)&auxilary_buffer->misc.data, (void*)msg, (size_t) MIN(len, MISC_SIZE-2));
- VOLATILE_WRITE_8(auxilary_buffer->result.crash_found, 1);
+ VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_crash);
}
void set_abort_reason_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len){
VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, MISC_SIZE-2));
volatile_memcpy((void*)&auxilary_buffer->misc.data, (void*)msg, (size_t) MIN(len, MISC_SIZE-2));
- VOLATILE_WRITE_8(auxilary_buffer->result.abort, 1);
-}
-
-void flush_hprintf_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer){
- VOLATILE_WRITE_8(auxilary_buffer->result.hprintf, 0);
+ VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_aborted);
}
void set_state_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t state){
@@ -255,14 +218,18 @@ void set_page_not_found_result_buffer(auxilary_buffer_t* auxilary_buffer, uint64
VOLATILE_WRITE_64(auxilary_buffer->result.page_addr, page_addr);
}
+void reset_page_not_found_result_buffer(auxilary_buffer_t* auxilary_buffer){
+ VOLATILE_WRITE_8(auxilary_buffer->result.page_not_found, 0);
+}
+
void set_success_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t success){
- VOLATILE_WRITE_8(auxilary_buffer->result.success, success);
+ VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_success);
}
void set_payload_buffer_write_reason_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len){
VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, MISC_SIZE-2));
volatile_memcpy((void*)&auxilary_buffer->misc.data, (void*)msg, (size_t) MIN(len, MISC_SIZE-2));
- VOLATILE_WRITE_8(auxilary_buffer->result.payload_buffer_write_attempt_found, 1);
+ VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_input_buffer_write);
}
diff --git a/nyx/auxiliary_buffer.h b/nyx/auxiliary_buffer.h
index fbf82a637a..53edb09b2a 100644
--- a/nyx/auxiliary_buffer.h
+++ b/nyx/auxiliary_buffer.h
@@ -37,6 +37,15 @@ along with QEMU-PT. If not, see .
#define ADD_PADDING(max, type) uint8_t type ## _padding [max - sizeof(type)]
+enum nyx_result_codes {
+ rc_success = 0,
+ rc_crash = 1,
+ rc_hprintf = 2,
+ rc_timeout = 3,
+ rc_input_buffer_write = 4,
+ rc_aborted = 5,
+};
+
typedef struct auxilary_buffer_header_s{
uint64_t magic; /* 0x54502d554d4551 */
uint16_t version;
@@ -93,40 +102,21 @@ typedef struct auxilary_buffer_result_s{
3 -> ready to fuzz
*/
uint8_t state;
- /* snapshot extension */
- uint8_t tmp_snapshot_created;
-
- /* FML */
- uint8_t padding_1;
- uint8_t padding_2;
-
- uint32_t bb_coverage;
-
- uint8_t padding_3;
- uint8_t padding_4;
-
- uint8_t hprintf;
- uint8_t exec_done;
-
- uint8_t crash_found;
- uint8_t asan_found;
-
- uint8_t timeout_found;
+ uint8_t exec_done;
+ uint8_t exec_result_code;
uint8_t reloaded;
uint8_t pt_overflow;
- uint8_t runtime_sec;
-
uint8_t page_not_found;
- uint8_t success;
+ uint8_t tmp_snapshot_created; /* incremental snapshot extension */
+ uint8_t padding_3;
- uint32_t runtime_usec;
uint64_t page_addr;
uint32_t dirty_pages;
- uint32_t pt_trace_size;
-
- uint8_t payload_buffer_write_attempt_found;
- uint8_t abort;
+ uint32_t pt_trace_size;
+ uint32_t bb_coverage;
+ uint32_t runtime_usec;
+ uint32_t runtime_sec;
/* more to come */
} __attribute__((packed)) auxilary_buffer_result_t;
@@ -158,19 +148,16 @@ typedef struct auxilary_buffer_s{
void init_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer);
void check_auxiliary_config_buffer(auxilary_buffer_t* auxilary_buffer, auxilary_buffer_config_t* shadow_config);
-void flush_hprintf_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer);
-
void set_crash_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
-void set_asan_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_timeout_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_reload_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_pt_overflow_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
-void flush_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
-void set_exec_done_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t sec, uint32_t usec);
+void set_exec_done_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t sec, uint32_t usec, uint32_t num_dirty_pages);
void set_state_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t state);
void set_hprintf_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len);
void set_page_not_found_result_buffer(auxilary_buffer_t* auxilary_buffer, uint64_t page_addr);
+void reset_page_not_found_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_success_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t success);
void set_crash_reason_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len);
void set_abort_reason_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len);
diff --git a/nyx/fast_vm_reload.c b/nyx/fast_vm_reload.c
index 50be74bb0e..6981917788 100644
--- a/nyx/fast_vm_reload.c
+++ b/nyx/fast_vm_reload.c
@@ -47,7 +47,8 @@ along with QEMU-PT. If not, see .
#include "nyx/fast_vm_reload.h"
#include "nyx/debug.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
+#include "nyx/state/snapshot_state.h"
#include "sysemu/block-backend.h"
#include "block/qapi.h"
@@ -125,33 +126,36 @@ static void fast_snapshot_init_operation(fast_reload_t* self, const char* snapsh
static void fast_snapshot_restore_operation(fast_reload_t* self){
+ uint32_t num_dirty_pages = 0;
+
switch(mode){
case RELOAD_MEMORY_MODE_DEBUG:
- nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, true);
+ num_dirty_pages += nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, true);
break;
case RELOAD_MEMORY_MODE_DEBUG_QUIET:
- nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, false);
+ num_dirty_pages += nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, false);
break;
case RELOAD_MEMORY_MODE_FDL:
- nyx_snapshot_nyx_fdl_restore(self->fdl_state, self->shadow_memory_state, self->blocklist);
+ num_dirty_pages += nyx_snapshot_nyx_fdl_restore(self->fdl_state, self->shadow_memory_state, self->blocklist);
break;
case RELOAD_MEMORY_MODE_FDL_DEBUG:
- nyx_snapshot_nyx_fdl_restore(self->fdl_state, self->shadow_memory_state, self->blocklist);
- nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, true);
+ num_dirty_pages += nyx_snapshot_nyx_fdl_restore(self->fdl_state, self->shadow_memory_state, self->blocklist);
+ num_dirty_pages += nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, true);
break;
case RELOAD_MEMORY_MODE_DIRTY_RING:
- nyx_snapshot_nyx_dirty_ring_restore(self->dirty_ring_state, self->shadow_memory_state, self->blocklist);
+ num_dirty_pages += nyx_snapshot_nyx_dirty_ring_restore(self->dirty_ring_state, self->shadow_memory_state, self->blocklist);
break;
case RELOAD_MEMORY_MODE_DIRTY_RING_DEBUG:
- nyx_snapshot_nyx_dirty_ring_restore(self->dirty_ring_state, self->shadow_memory_state, self->blocklist);
- nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, true);
+ num_dirty_pages += nyx_snapshot_nyx_dirty_ring_restore(self->dirty_ring_state, self->shadow_memory_state, self->blocklist);
+ num_dirty_pages += nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, true);
//assert(false);
//sleep(1);
break;
}
- nyx_snapshot_user_fdl_restore(self->fdl_user_state, self->shadow_memory_state, self->blocklist);
+ num_dirty_pages += nyx_snapshot_user_fdl_restore(self->fdl_user_state, self->shadow_memory_state, self->blocklist);
//nyx_device_state_post_restore(self->device_state);
+ GET_GLOBAL_STATE()->num_dirty_pages = num_dirty_pages;
}
static inline void fast_snapshot_pre_create_incremental_operation(fast_reload_t* self){
@@ -279,7 +283,7 @@ inline static void wait_for_snapshot(const char* folder){
free(lock_file);
}
-void fast_reload_serialize_to_file(fast_reload_t* self, const char* folder){
+void fast_reload_serialize_to_file(fast_reload_t* self, const char* folder, bool is_pre_snapshot){
//printf("================ %s => %s =============\n", __func__, folder);
@@ -299,7 +303,7 @@ void fast_reload_serialize_to_file(fast_reload_t* self, const char* folder){
nyx_block_snapshot_serialize(self->block_state, folder);
/* NYX's state */
- dump_global_state(folder);
+ serialize_state(folder, is_pre_snapshot);
/* finalize snapshot */
unlock_snapshot(folder);
@@ -332,7 +336,7 @@ static void fast_reload_create_from_snapshot(fast_reload_t* self, const char* fo
rcu_read_unlock();
if(!pre_snapshot){
- load_global_state(folder);
+ deserialize_state(folder);
}
cpu_synchronize_all_post_init();
@@ -480,10 +484,7 @@ void fast_reload_create_tmp_snapshot(fast_reload_t* self){
fast_snapshot_pre_create_incremental_operation(self);
if(!self->bitmap_copy){
- if(GET_GLOBAL_STATE()->shared_bitmap_size+GET_GLOBAL_STATE()->shared_ijon_bitmap_size){
- assert(GET_GLOBAL_STATE()->shared_bitmap_size+GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
- self->bitmap_copy = malloc(GET_GLOBAL_STATE()->shared_bitmap_size+GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
- }
+ self->bitmap_copy = new_coverage_bitmaps();
}
coverage_bitmap_copy_to_buffer(self->bitmap_copy);
diff --git a/nyx/fast_vm_reload.h b/nyx/fast_vm_reload.h
index 0c829377e4..00333c6f24 100644
--- a/nyx/fast_vm_reload.h
+++ b/nyx/fast_vm_reload.h
@@ -35,6 +35,7 @@ along with QEMU-PT. If not, see .
#include "nyx/snapshot/block/nyx_block_snapshot.h"
#include "nyx/snapshot/memory/backend/nyx_dirty_ring.h"
+#include "nyx/helpers.h"
typedef enum FastReloadMemoryMode {
@@ -82,7 +83,7 @@ typedef struct fast_reload_s{
bool incremental_snapshot_enabled;
/* copy of the fuzzing bitmap & ijon state buffer */
- void* bitmap_copy;
+ nyx_coverage_bitmap_copy_t* bitmap_copy;
@@ -104,7 +105,7 @@ void fast_reload_create_from_file_pre_image(fast_reload_t* self, const char* fol
void fast_reload_create_in_memory(fast_reload_t* self);
-void fast_reload_serialize_to_file(fast_reload_t* self, const char* folder);
+void fast_reload_serialize_to_file(fast_reload_t* self, const char* folder, bool is_pre_snapshot);
void fast_reload_restore(fast_reload_t* self);
diff --git a/nyx/fast_vm_reload_sync.c b/nyx/fast_vm_reload_sync.c
index 02c93c5201..7e3780b5a8 100644
--- a/nyx/fast_vm_reload_sync.c
+++ b/nyx/fast_vm_reload_sync.c
@@ -11,7 +11,7 @@
#include "sysemu/kvm_int.h"
#include "sysemu/kvm.h"
#include "sysemu/runstate.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include "nyx/fast_vm_reload.h"
#include "nyx/debug.h"
#include "nyx/kvm_nested.h"
@@ -127,7 +127,7 @@ static inline void create_root_snapshot(void){
debug_printf("===> GET_GLOBAL_STATE()->fast_reload_mode: FALSE\n");
/* store the current state as a snapshot folder */
fast_reload_create_in_memory(get_fast_reload_snapshot());
- fast_reload_serialize_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_path);
+ fast_reload_serialize_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_path, false);
}
}
else{
@@ -149,7 +149,7 @@ static inline void perform_task_no_block_mode(fast_vm_reload_sync_t* self, FastR
vm_stop(RUN_STATE_SAVE_VM);
//fast_reload_create_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_pre_path, true);
fast_reload_create_in_memory(get_fast_reload_snapshot());
- fast_reload_serialize_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_pre_path);
+ fast_reload_serialize_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_pre_path, true);
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
qemu_mutex_unlock_iothread();
@@ -218,7 +218,7 @@ static inline void perform_task_block_mode(fast_vm_reload_sync_t* self, FastRelo
vm_stop(RUN_STATE_SAVE_VM);
//fast_reload_create_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_pre_path, true);
fast_reload_create_in_memory(get_fast_reload_snapshot());
- fast_reload_serialize_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_pre_path);
+ fast_reload_serialize_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_pre_path, true);
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
return; /* return here to skip the vm_start call */
case REQUEST_SAVE_SNAPSHOT_ROOT_FIX_RIP:
diff --git a/nyx/helpers.c b/nyx/helpers.c
index 6892a0a12b..a24be89e1c 100644
--- a/nyx/helpers.c
+++ b/nyx/helpers.c
@@ -10,9 +10,15 @@
#include "qemu/main-loop.h"
#include "sysemu/kvm_int.h"
#include "sysemu/kvm.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include "nyx/memory_access.h"
#include "nyx/debug.h"
+#include "nyx/helpers.h"
+
+void nyx_abort(char* msg){
+ set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, msg, strlen(msg));
+ synchronization_lock();
+}
uint64_t get_rip(CPUState *cpu){
kvm_arch_get_registers(cpu);
@@ -33,26 +39,49 @@ int get_capstone_mode(int word_width_in_bits){
}
}
+nyx_coverage_bitmap_copy_t* new_coverage_bitmaps(void){
+ nyx_coverage_bitmap_copy_t* bitmaps = malloc(sizeof(nyx_coverage_bitmap_copy_t));
+ memset(bitmaps, 0, sizeof(nyx_coverage_bitmap_copy_t));
+
+ assert(GET_GLOBAL_STATE()->shared_bitmap_size);
+ bitmaps->coverage_bitmap = malloc(GET_GLOBAL_STATE()->shared_bitmap_size);
+
+ assert(GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
+ bitmaps->ijon_bitmap_buffer = malloc(GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
+
+ return bitmaps;
+}
+
void coverage_bitmap_reset(void){
if(GET_GLOBAL_STATE()->shared_bitmap_ptr){
- //fprintf(stderr, "%s: %lx %lx\n", __func__, coverage_bitmap, coverage_bitmap_size);
- memset(GET_GLOBAL_STATE()->shared_bitmap_ptr, 0x00, GET_GLOBAL_STATE()->shared_bitmap_size + GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
+ memset(GET_GLOBAL_STATE()->shared_bitmap_ptr, 0x00, GET_GLOBAL_STATE()->shared_bitmap_real_size);
+ }
+ if (GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr && GET_GLOBAL_STATE()->shared_ijon_bitmap_size){
+ memset(GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr, 0x00, GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
}
}
-void coverage_bitmap_copy_to_buffer(void* buffer){
+void coverage_bitmap_copy_to_buffer(nyx_coverage_bitmap_copy_t* buffer){
+
if(GET_GLOBAL_STATE()->shared_bitmap_ptr){
- memcpy(buffer, GET_GLOBAL_STATE()->shared_bitmap_ptr, GET_GLOBAL_STATE()->shared_bitmap_size + GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
+ memcpy(buffer->coverage_bitmap, GET_GLOBAL_STATE()->shared_bitmap_ptr, GET_GLOBAL_STATE()->shared_bitmap_real_size);
+ }
+ if (GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr){
+ memcpy(buffer->ijon_bitmap_buffer, GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr, GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
}
}
-void coverage_bitmap_copy_from_buffer(void* buffer){
+void coverage_bitmap_copy_from_buffer(nyx_coverage_bitmap_copy_t* buffer){
+
if(GET_GLOBAL_STATE()->shared_bitmap_ptr){
- memcpy(GET_GLOBAL_STATE()->shared_bitmap_ptr, buffer, GET_GLOBAL_STATE()->shared_bitmap_size + GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
+ memcpy(GET_GLOBAL_STATE()->shared_bitmap_ptr, buffer->coverage_bitmap, GET_GLOBAL_STATE()->shared_bitmap_real_size);
+ }
+ if (GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr){
+ memcpy(GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr, buffer->ijon_bitmap_buffer, GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
}
}
-void apply_capabilities(CPUState *cpu){
+bool apply_capabilities(CPUState *cpu){
//X86CPU *cpux86 = X86_CPU(cpu);
//CPUX86State *env = &cpux86->env;
@@ -74,7 +103,8 @@ void apply_capabilities(CPUState *cpu){
debug_printf("--------------------------\n");
if(GET_GLOBAL_STATE()->cap_compile_time_tracing_buffer_vaddr&0xfff){
- fprintf(stderr, "[QEMU-Nyx] Warning: guest's trace bitmap v_addr (0x%lx) is not page aligned!\n", GET_GLOBAL_STATE()->cap_compile_time_tracing_buffer_vaddr);
+ fprintf(stderr, "[QEMU-Nyx] Error: guest's trace bitmap v_addr (0x%lx) is not page aligned!\n", GET_GLOBAL_STATE()->cap_compile_time_tracing_buffer_vaddr);
+ return false;
}
for(uint64_t i = 0; i < GET_GLOBAL_STATE()->shared_bitmap_size; i += 0x1000){
@@ -84,18 +114,20 @@ void apply_capabilities(CPUState *cpu){
}
if(GET_GLOBAL_STATE()->cap_ijon_tracing){
- debug_fprintf(stderr, "%s: agent trace buffer at vaddr: %lx\n", __func__, GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr);
+ debug_printf(stderr, "%s: agent trace buffer at vaddr: %lx\n", __func__, GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr);
if(GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr&0xfff){
- fprintf(stderr, "[QEMU-Nyx] Warning: guest's ijon buffer v_addr (0x%lx) is not page aligned!\n", GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr);
+ fprintf(stderr, "[QEMU-Nyx] Error: guest's ijon buffer v_addr (0x%lx) is not page aligned!\n", GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr);
+ return false;
}
kvm_arch_get_registers_fast(cpu);
for(uint64_t i = 0; i < GET_GLOBAL_STATE()->shared_ijon_bitmap_size; i += 0x1000){
- assert(remap_slot(GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr + i, (GET_GLOBAL_STATE()->shared_bitmap_size+i)/0x1000, cpu, GET_GLOBAL_STATE()->shared_bitmap_fd, GET_GLOBAL_STATE()->shared_bitmap_size+GET_GLOBAL_STATE()->shared_ijon_bitmap_size, true, GET_GLOBAL_STATE()->cap_cr3));
+ assert(remap_slot(GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr + i, i/0x1000, cpu, GET_GLOBAL_STATE()->shared_ijon_bitmap_fd, GET_GLOBAL_STATE()->shared_ijon_bitmap_size+GET_GLOBAL_STATE()->shared_ijon_bitmap_size, true, GET_GLOBAL_STATE()->cap_cr3));
}
set_cap_agent_ijon_trace_bitmap(GET_GLOBAL_STATE()->auxilary_buffer, true);
}
+ return true;
}
bool folder_exits(const char* path){
diff --git a/nyx/helpers.h b/nyx/helpers.h
index 1cd6d744f3..81eaf23610 100644
--- a/nyx/helpers.h
+++ b/nyx/helpers.h
@@ -3,13 +3,22 @@
#include "qemu/osdep.h"
uint64_t get_rip(CPUState *cpu);
+
+typedef struct nyx_coverage_bitmap_copy_s{
+ void* coverage_bitmap;
+ void* ijon_bitmap_buffer;
+}nyx_coverage_bitmap_copy_t;
+
+void nyx_abort(char* msg);
+
+nyx_coverage_bitmap_copy_t* new_coverage_bitmaps(void);
void coverage_bitmap_reset(void);
-void coverage_bitmap_copy_to_buffer(void* buffer);
-void coverage_bitmap_copy_from_buffer(void* buffer);
+void coverage_bitmap_copy_to_buffer(nyx_coverage_bitmap_copy_t* buffer);
+void coverage_bitmap_copy_from_buffer(nyx_coverage_bitmap_copy_t* buffer);
int get_capstone_mode(int word_width_in_bits);
-void apply_capabilities(CPUState *cpu);
+bool apply_capabilities(CPUState *cpu);
bool folder_exits(const char* path);
bool file_exits(const char* path);
diff --git a/nyx/hypercall/configuration.c b/nyx/hypercall/configuration.c
index 038767eb79..e2cb8b0a17 100644
--- a/nyx/hypercall/configuration.c
+++ b/nyx/hypercall/configuration.c
@@ -1,7 +1,8 @@
#include "qemu/osdep.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include "nyx/hypercall/configuration.h"
#include "nyx/memory_access.h"
+#include "nyx/helpers.h"
void handle_hypercall_kafl_get_host_config(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
uint64_t vaddr = hypercall_arg;
@@ -17,6 +18,20 @@ void handle_hypercall_kafl_get_host_config(struct kvm_run *run, CPUState *cpu, u
write_virtual_memory(vaddr, (uint8_t*)&config, sizeof(host_config_t), cpu);
}
+static void resize_coverage_bitmap(uint32_t new_bitmap_size){
+ uint32_t new_bitmap_shm_size = new_bitmap_size;
+
+ if (new_bitmap_shm_size % 64 > 0) {
+ new_bitmap_shm_size = ((new_bitmap_shm_size + 64) >> 6) << 6;
+ }
+
+ GET_GLOBAL_STATE()->shared_bitmap_real_size = new_bitmap_shm_size;
+ resize_shared_memory(new_bitmap_shm_size, &GET_GLOBAL_STATE()->shared_bitmap_size, &GET_GLOBAL_STATE()->shared_bitmap_ptr, GET_GLOBAL_STATE()->shared_bitmap_fd);
+
+ /* pass the actual bitmap buffer size to the front-end */
+ GET_GLOBAL_STATE()->auxilary_buffer->capabilites.agent_coverage_bitmap_size = new_bitmap_size;
+}
+
void handle_hypercall_kafl_set_agent_config(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
uint64_t vaddr = hypercall_arg;
agent_config_t config;
@@ -60,12 +75,14 @@ void handle_hypercall_kafl_set_agent_config(struct kvm_run *run, CPUState *cpu,
if (config.coverage_bitmap_size){
resize_coverage_bitmap(config.coverage_bitmap_size);
}
-
+
if (config.input_buffer_size){
- resize_payload_buffer(config.coverage_bitmap_size);
+ resize_payload_buffer(config.input_buffer_size);
}
- apply_capabilities(cpu);
+ if(apply_capabilities(cpu) == false){
+ nyx_abort((char*)"applying agent configuration failed...");
+ }
if(getenv("DUMP_PAYLOAD_MODE")){
config.dump_payloads = 1;
diff --git a/nyx/hypercall/debug.c b/nyx/hypercall/debug.c
index a146f58258..38eb2b48ae 100644
--- a/nyx/hypercall/debug.c
+++ b/nyx/hypercall/debug.c
@@ -2,7 +2,7 @@
#include
#include "nyx/synchronization.h"
#include "nyx/fast_vm_reload.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include "nyx/hypercall/debug.h"
//#define NYX_ENABLE_DEBUG_HYPERCALLS
diff --git a/nyx/hypercall/hypercall.c b/nyx/hypercall/hypercall.c
index 8d97601d5d..c50e75a96a 100644
--- a/nyx/hypercall/hypercall.c
+++ b/nyx/hypercall/hypercall.c
@@ -30,8 +30,6 @@ along with QEMU-PT. If not, see .
#include "sysemu/kvm_int.h"
#include "sysemu/runstate.h"
-#include "sysemu/cpus.h"
-
#include "sysemu/kvm_int.h"
#include "sysemu/kvm.h"
#include "sysemu/cpus.h"
@@ -43,12 +41,11 @@ along with QEMU-PT. If not, see .
#include "nyx/hypercall/hypercall.h"
#include "nyx/memory_access.h"
#include "nyx/interface.h"
-#include "nyx/printk.h"
#include "nyx/debug.h"
#include "nyx/synchronization.h"
#include "nyx/fast_vm_reload.h"
#include "nyx/kvm_nested.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include "sysemu/runstate.h"
#include "nyx/helpers.h"
#include "nyx/nested_hypercalls.h"
@@ -59,8 +56,8 @@ along with QEMU-PT. If not, see .
#include "nyx/hypercall/debug.h"
//#define DEBUG_HPRINTF
+#define HPRINTF_SIZE 0x1000
-bool notifiers_enabled = false;
bool hypercall_enabled = false;
char hprintf_buffer[HPRINTF_SIZE];
@@ -115,10 +112,10 @@ bool handle_hypercall_kafl_next_payload(struct kvm_run *run, CPUState *cpu, uint
//pt_reset_bitmap();
if (GET_GLOBAL_STATE()->pt_trace_mode){
- fprintf(stderr, "[QEMU-Nyx] coverage mode: Intel-PT (KVM-Nyx and libxdc)\n");
+ printf("[QEMU-Nyx] coverage mode: Intel-PT (KVM-Nyx and libxdc)\n");
}
else{
- fprintf(stderr, "[QEMU-Nyx] coverage mode: compile-time instrumentation\n");
+ printf("[QEMU-Nyx] coverage mode: compile-time instrumentation\n");
}
coverage_bitmap_reset();
@@ -312,13 +309,6 @@ static void handle_hypercall_kafl_range_submit(struct kvm_run *run, CPUState *cp
}
-static void handle_hypercall_get_program(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
- fprintf(stderr, "[QEMU-Nyx] Error: This hypercall (HYPERCALL_KAFL_GET_PAYLOAD) is deprecated -> use ./hget instead!\n");
- set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, (char*)"Deprecated hypercall called...", strlen("Deprecated hypercall called..."));
- synchronization_lock();
-}
-
-
static void release_print_once(CPUState *cpu){
if(release_print_once_bool){
release_print_once_bool = false;
@@ -351,7 +341,7 @@ void handle_hypercall_kafl_mtf(struct kvm_run *run, CPUState *cpu, uint64_t hype
//assert(false);
kvm_arch_get_registers_fast(cpu);
- debug_fprintf(stderr, "%s --> %lx\n", __func__, get_rip(cpu));
+ fprintf(stderr, "%s --> %lx\n", __func__, get_rip(cpu));
kvm_vcpu_ioctl(cpu, KVM_VMX_PT_DISABLE_MTF);
@@ -417,18 +407,7 @@ static void handle_hypercall_kafl_cr3(struct kvm_run *run, CPUState *cpu, uint64
static void handle_hypercall_kafl_submit_panic(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
if(hypercall_enabled){
QEMU_PT_PRINTF(CORE_PREFIX, "Panic address:\t%lx", hypercall_arg);
- if(notifiers_enabled){
- write_virtual_memory(hypercall_arg, (uint8_t*)PANIC_PAYLOAD, PAYLOAD_BUFFER_SIZE, cpu);
- }
- }
-}
-
-static void handle_hypercall_kafl_submit_kasan(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
- if(hypercall_enabled){
- QEMU_PT_PRINTF(CORE_PREFIX, "kASAN address:\t%lx", hypercall_arg);
- if(notifiers_enabled){
- write_virtual_memory(hypercall_arg, (uint8_t*)KASAN_PAYLOAD, PAYLOAD_BUFFER_SIZE, cpu);
- }
+ write_virtual_memory(hypercall_arg, (uint8_t*)PANIC_PAYLOAD, PAYLOAD_BUFFER_SIZE, cpu);
}
}
@@ -475,9 +454,7 @@ static void handle_hypercall_kafl_panic(struct kvm_run *run, CPUState *cpu, uint
}
synchronization_lock_crash_found();
} else{
- #define AGENT_HAS_CRASHED_REPORT "Agent has crashed before initializing the fuzzing loop..."
- set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, (char*)AGENT_HAS_CRASHED_REPORT, strlen(AGENT_HAS_CRASHED_REPORT));
- synchronization_lock();
+ nyx_abort((char*)"Agent has crashed before initializing the fuzzing loop...");
}
}
}
@@ -541,61 +518,15 @@ static void handle_hypercall_kafl_panic_extended(struct kvm_run *run, CPUState *
read_virtual_memory(hypercall_arg, (uint8_t*)hprintf_buffer, HPRINTF_SIZE, cpu);
char* report = NULL;
assert(asprintf(&report, "Agent has crashed before initializing the fuzzing loop: %s", hprintf_buffer) != -1);
-
- set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, report, strlen(report));
- synchronization_lock();
+ nyx_abort(report);
}
}
-
-static void handle_hypercall_kafl_kasan(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
- if(hypercall_enabled){
-#ifdef PANIC_DEBUG
- if(hypercall_arg){
- QEMU_PT_PRINTF(CORE_PREFIX, "ASan notification in user mode!");
- } else{
- QEMU_PT_PRINTF(CORE_PREFIX, "ASan notification in kernel mode!");
- }
-#endif
- if(fast_reload_snapshot_exists(get_fast_reload_snapshot())){
- synchronization_lock_asan_found();
- //synchronization_stop_vm_kasan(cpu);
- } else{
- QEMU_PT_PRINTF(CORE_PREFIX, "KASAN detected during initialization of stage 1 or stage 2 loader");
- //hypercall_snd_char(KAFL_PROTO_KASAN);
- QEMU_PT_PRINTF_DEBUG("Protocol - SEND: KAFL_PROTO_KASAN");
-
- }
- }
-}
-
-
-/*
-static uint64_t get_rsp(CPUState *cpu){
- kvm_arch_get_registers(cpu);
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
- kvm_cpu_synchronize_state(cpu);
- return env->regs[4];
-}
-*/
-
static void handle_hypercall_kafl_lock(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
if(!GET_GLOBAL_STATE()->fast_reload_pre_image){
QEMU_PT_PRINTF(CORE_PREFIX, "Skipping pre image creation (hint: set pre=on) ...");
return;
-
-/*
-
- fast_reload_create_in_memory(get_fast_reload_snapshot(), true);
-
-qemu_mutex_lock_iothread();
- fast_reload_restore(get_fast_reload_snapshot());
-
- qemu_mutex_unlock_iothread();
- */
- //return;
}
QEMU_PT_PRINTF(CORE_PREFIX, "Creating pre image snapshot <%s> ...", GET_GLOBAL_STATE()->fast_reload_pre_path);
@@ -604,16 +535,6 @@ qemu_mutex_lock_iothread();
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_PRE);
}
-static void handle_hypercall_kafl_info(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
- fprintf(stderr, "[QEMU-Nyx] Error: This hypercall (HYPERCALL_KAFL_INFO) is deprecated -> use hprintf() & ./habort instead!\n");
- set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, (char*)"Deprecated hypercall called...", strlen("Deprecated hypercall called..."));
- synchronization_lock();
-}
-
-void enable_notifies(void){
- notifiers_enabled = true;
-}
-
static void handle_hypercall_kafl_printf(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
read_virtual_memory(hypercall_arg, (uint8_t*)hprintf_buffer, HPRINTF_SIZE, cpu);
#ifdef DEBUG_HPRINTF
@@ -624,26 +545,6 @@ static void handle_hypercall_kafl_printf(struct kvm_run *run, CPUState *cpu, uin
#endif
}
-
-static void handle_hypercall_kafl_printk(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
- if(!notifiers_enabled){
- if (hypercall_enabled && GET_GLOBAL_STATE()->enable_hprintf){
- if(kafl_linux_printk(cpu)){
- handle_hypercall_kafl_panic(run, cpu, (uint64_t)run->hypercall.args[0]);
- }
- }
- }
-}
-
-static void handle_hypercall_kafl_printk_addr(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
- if(!notifiers_enabled){
- debug_printf("%s\n", __func__);
- debug_printf("%lx\n", hypercall_arg);
- write_virtual_memory(hypercall_arg, (uint8_t*)PRINTK_PAYLOAD, PRINTK_PAYLOAD_SIZE, cpu);
- debug_printf("Done\n");
- }
-}
-
static void handle_hypercall_kafl_user_range_advise(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
kAFL_ranges* buf = malloc(sizeof(kAFL_ranges));
@@ -831,9 +732,11 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall
ret = 0;
break;
case KVM_EXIT_KAFL_GET_PROGRAM:
- //timeout_reload_pending = false;
- //fprintf(stderr, "KVM_EXIT_KAFL_GET_PROGRAM\n");
- handle_hypercall_get_program(run, cpu, arg);
+ nyx_abort((char*)"Deprecated hypercall called (HYPERCALL_KAFL_GET_PROGRAM)...");
+ ret = 0;
+ break;
+ case KVM_EXIT_KAFL_GET_ARGV:
+ nyx_abort((char*)"Deprecated hypercall called (HYPERCALL_KAFL_GET_ARGV)...");
ret = 0;
break;
case KVM_EXIT_KAFL_RELEASE:
@@ -855,9 +758,7 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall
ret = 0;
break;
case KVM_EXIT_KAFL_SUBMIT_KASAN:
- //timeout_reload_pending = false;
- //fprintf(stderr, "KVM_EXIT_KAFL_SUBMIT_KASAN\n");
- handle_hypercall_kafl_submit_kasan(run, cpu, arg);
+ nyx_abort((char*)"Deprecated hypercall called (HYPERCALL_SUBMIT_KASAN)...");
ret = 0;
break;
case KVM_EXIT_KAFL_PANIC:
@@ -867,9 +768,7 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall
ret = 0;
break;
case KVM_EXIT_KAFL_KASAN:
- //timeout_reload_pending = false;
- //fprintf(stderr, "KVM_EXIT_KAFL_KASAN\n");
- handle_hypercall_kafl_kasan(run, cpu, arg);
+ nyx_abort((char*)"Deprecated hypercall called (HYPERCALL_KAFL_KASAN)...");
ret = 0;
break;
case KVM_EXIT_KAFL_LOCK:
@@ -879,9 +778,7 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall
ret = 0;
break;
case KVM_EXIT_KAFL_INFO:
- //timeout_reload_pending = false;
- //fprintf(stderr, "KVM_EXIT_KAFL_INFO\n");
- handle_hypercall_kafl_info(run, cpu, arg);
+ nyx_abort((char*)"Deprecated hypercall called (HYPERCALL_KAFL_INFO)...");
ret = 0;
break;
case KVM_EXIT_KAFL_NEXT_PAYLOAD:
@@ -897,13 +794,11 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall
ret = 0;
break;
case KVM_EXIT_KAFL_PRINTK_ADDR:
- //timeout_reload_pending = false;
- handle_hypercall_kafl_printk_addr(run, cpu, arg);
+ nyx_abort((char*)"Deprecated hypercall called (KVM_EXIT_KAFL_PRINTK_ADDR)...");
ret = 0;
break;
case KVM_EXIT_KAFL_PRINTK:
- //timeout_reload_pending = false;
- handle_hypercall_kafl_printk(run, cpu, arg);
+ nyx_abort((char*)"Deprecated hypercall called (KVM_EXIT_KAFL_PRINTK)...");
ret = 0;
break;
diff --git a/nyx/hypercall/hypercall.h b/nyx/hypercall/hypercall.h
index 29dc87daab..c9cb788846 100644
--- a/nyx/hypercall/hypercall.h
+++ b/nyx/hypercall/hypercall.h
@@ -22,7 +22,6 @@ along with QEMU-PT. If not, see .
#pragma once
#define PAYLOAD_BUFFER_SIZE 26
-#define PRINTK_PAYLOAD_SIZE 4
#define KAFL_MODE_64 0
#define KAFL_MODE_32 1
@@ -100,7 +99,6 @@ void handle_hypercall_kafl_page_dump_bp(struct kvm_run *run, CPUState *cpu, uint
void hprintf(char* msg);
-void enable_notifies(void);
bool handle_hypercall_kafl_next_payload(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg);
void hypercall_reset_hprintf_counter(void);
diff --git a/nyx/interface.c b/nyx/interface.c
index f55ddf3f03..96b5f7f71f 100644
--- a/nyx/interface.c
+++ b/nyx/interface.c
@@ -48,7 +48,7 @@ along with QEMU-PT. If not, see .
#include "nyx/snapshot/devices/state_reallocation.h"
#include "nyx/memory_access.h"
#include
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include "nyx/sharedir.h"
#include "nyx/helpers.h"
@@ -85,10 +85,9 @@ typedef struct nyx_interface_state {
char* filter_bitmap[4];
char* ip_filter[4][2];
- uint64_t bitmap_size;
+ uint32_t bitmap_size;
+ uint32_t input_buffer_size;
- bool debug_mode; /* support for hprintf */
- bool notifier;
bool dump_pt_trace;
bool redqueen;
@@ -183,6 +182,7 @@ static void nyx_guest_setup_bitmap(nyx_interface_state *s, char* filename, uint3
GET_GLOBAL_STATE()->shared_bitmap_ptr = (void*)ptr;
GET_GLOBAL_STATE()->shared_bitmap_fd = fd;
GET_GLOBAL_STATE()->shared_bitmap_size = bitmap_size;
+ GET_GLOBAL_STATE()->shared_bitmap_real_size = bitmap_size;
}
@@ -197,12 +197,9 @@ static void nyx_guest_setup_ijon_buffer(nyx_interface_state *s, char* filename){
assert(DEFAULT_NYX_IJON_BITMAP_SIZE == st.st_size);
ptr = mmap(0, DEFAULT_NYX_IJON_BITMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- /*
- GET_GLOBAL_STATE()->shared_bitmap_ptr = (void*)ptr;
- GET_GLOBAL_STATE()->shared_bitmap_fd = fd;
- GET_GLOBAL_STATE()->shared_bitmap_size = bitmap_size-DEFAULT_NYX_IJON_BITMAP_SIZE;
+ GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr = (void*)ptr;
+ GET_GLOBAL_STATE()->shared_ijon_bitmap_fd = fd;
GET_GLOBAL_STATE()->shared_ijon_bitmap_size = DEFAULT_NYX_IJON_BITMAP_SIZE;
- */
}
static bool verify_workdir_state(nyx_interface_state *s, Error **errp){
@@ -238,7 +235,7 @@ static bool verify_workdir_state(nyx_interface_state *s, Error **errp){
return false;
}
else {
- nyx_create_payload_buffer(s, PAYLOAD_SIZE, tmp, errp);
+ nyx_create_payload_buffer(s, s->input_buffer_size, tmp, errp);
}
free(tmp);
@@ -304,8 +301,8 @@ static bool verify_workdir_state(nyx_interface_state *s, Error **errp){
if(s->dump_pt_trace){
assert(asprintf(&tmp, "%s/pt_trace_dump_%d", workdir, id) != -1);
- pt_open_pt_trace_file(tmp);
- free(tmp);
+ pt_open_pt_trace_file(tmp);
+ free(tmp);
}
@@ -391,8 +388,6 @@ static void nyx_realize(DeviceState *dev, Error **errp){
s->bitmap_size = DEFAULT_NYX_BITMAP_SIZE;
}
- assert((uint32_t)s->bitmap_size > (0x1000 + DEFAULT_NYX_IJON_BITMAP_SIZE));
- assert((((uint32_t)s->bitmap_size-DEFAULT_NYX_IJON_BITMAP_SIZE) & (((uint32_t)s->bitmap_size-DEFAULT_NYX_IJON_BITMAP_SIZE) - 1)) == 0 );
if(s->worker_id == 0xFFFF){
fprintf(stderr, "[QEMU-Nyx] Error: Invalid worker id...\n");
@@ -421,14 +416,6 @@ static void nyx_realize(DeviceState *dev, Error **errp){
}
check_available_ipt_ranges(s);
-
- if(s->debug_mode){
- GET_GLOBAL_STATE()->enable_hprintf = true;
- }
-
- if(s->notifier){
- enable_notifies();
- }
pt_setup_enable_hypercalls();
init_crash_handler();
@@ -458,9 +445,8 @@ static Property nyx_interface_properties[] = {
DEFINE_PROP_STRING("ip3_b", nyx_interface_state, ip_filter[3][1]),
- DEFINE_PROP_UINT64("bitmap_size", nyx_interface_state, bitmap_size, DEFAULT_NYX_BITMAP_SIZE),
- DEFINE_PROP_BOOL("debug_mode", nyx_interface_state, debug_mode, false),
- DEFINE_PROP_BOOL("crash_notifier", nyx_interface_state, notifier, true),
+ DEFINE_PROP_UINT32("bitmap_size", nyx_interface_state, bitmap_size, DEFAULT_NYX_BITMAP_SIZE),
+ DEFINE_PROP_UINT32("input_buffer_size", nyx_interface_state, input_buffer_size, DEFAULT_NYX_BITMAP_SIZE),
DEFINE_PROP_BOOL("dump_pt_trace", nyx_interface_state, dump_pt_trace, false),
diff --git a/nyx/interface.h b/nyx/interface.h
index 54a93172c4..e75e22d90a 100644
--- a/nyx/interface.h
+++ b/nyx/interface.h
@@ -23,15 +23,10 @@ along with QEMU-PT. If not, see .
#define INTERFACE_H
/* 64k bitmap + 4k ijon buffer */
-#define DEFAULT_NYX_IJON_BITMAP_SIZE 0x1000
-#define DEFAULT_NYX_BITMAP_SIZE 0x10000 + DEFAULT_NYX_IJON_BITMAP_SIZE
-#define DEFAULT_EDGE_FILTER_SIZE 0x1000000
+#define DEFAULT_NYX_IJON_BITMAP_SIZE 0x1000 /* fixed size buffer for IJON -> 4k */
+#define DEFAULT_NYX_BITMAP_SIZE 0x10000 /* default bitmap size => 64k */
-#define PAYLOAD_SIZE (128 << 10) /* 128KB Payload Data */
-#define HPRINTF_SIZE 0x1000 /* 4KB hprintf Data */
-
-
-#define NYX_INTERFACE_PING 'x'
+#define NYX_INTERFACE_PING 'x'
bool interface_send_char(char val);
diff --git a/nyx/kvm_nested.c b/nyx/kvm_nested.c
index 521c44f234..f42a0dce47 100644
--- a/nyx/kvm_nested.c
+++ b/nyx/kvm_nested.c
@@ -4,7 +4,7 @@
#include "nyx/debug.h"
#include "exec/ram_addr.h"
#include "qemu/rcu_queue.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include "sysemu/kvm.h"
#include "pt.h"
diff --git a/nyx/memory_access.c b/nyx/memory_access.c
index 48c9c8f219..08adee0bc7 100644
--- a/nyx/memory_access.c
+++ b/nyx/memory_access.c
@@ -30,7 +30,7 @@ along with QEMU-PT. If not, see .
#include "debug.h"
#include "nyx/fast_vm_reload.h"
#include "exec/gdbstub.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include "sysemu/kvm.h"
#include "nyx/helpers.h"
@@ -200,7 +200,7 @@ bool remap_slot(uint64_t addr, uint32_t slot, CPUState *cpu, int fd, uint64_t sh
if(virtual){
phys_addr = get_paging_phys_addr(cpu, cr3, (addr & x86_64_PAGE_MASK));
- if(phys_addr == (uint64_t)-1){
+ if(phys_addr == INVALID_ADDRESS){
fprintf(stderr, "[QEMU-Nyx] Error: failed to translate v_addr (0x%lx) to p_addr!\n", addr);
fprintf(stderr, "[QEMU-Nyx] Check if the buffer is present in the guest's memory...\n");
exit(1);
@@ -259,22 +259,37 @@ bool remap_payload_slot_protected(uint64_t phys_addr, uint32_t slot, CPUState *c
return true;
}
-void resize_coverage_bitmap(uint32_t new_size){
- assert(GET_GLOBAL_STATE()->shared_bitmap_fd && GET_GLOBAL_STATE()->shared_bitmap_size);
- fprintf(stderr, "shared_bitmap_size -> %x - new_size: %x\n", GET_GLOBAL_STATE()->shared_bitmap_size, new_size);
- assert(GET_GLOBAL_STATE()->shared_bitmap_size <= (new_size+0x1000) && !(new_size & 0xFFF));
+void resize_shared_memory(uint32_t new_size, uint32_t* shm_size, void** shm_ptr, int fd){
+ assert(fd && *shm_size);
+
+ /* check if the new_size is a multiple of PAGE_SIZE */
+ if(new_size & (PAGE_SIZE-1)){
+ new_size = (new_size & ~(PAGE_SIZE-1)) + PAGE_SIZE;
+ }
+
+ if(*shm_size >= new_size){
+ /* no need no resize the buffer -> early exit */
+ return;
+ }
+
assert(!GET_GLOBAL_STATE()->pt_trace_mode);
assert(!GET_GLOBAL_STATE()->in_fuzzing_mode);
- assert(ftruncate(GET_GLOBAL_STATE()->shared_bitmap_fd, new_size+0x1000) == 0);
+ assert(ftruncate(fd, new_size) == 0);
- printf("MUNMAP: %d\n", GET_GLOBAL_STATE()->shared_bitmap_size);
- munmap((void*)GET_GLOBAL_STATE()->shared_bitmap_ptr , GET_GLOBAL_STATE()->shared_bitmap_size+0x1000);
- GET_GLOBAL_STATE()->shared_bitmap_ptr = (void*)mmap(0, new_size+0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, GET_GLOBAL_STATE()->shared_bitmap_fd, 0);;
-
- GET_GLOBAL_STATE()->shared_bitmap_size = new_size;
- GET_GLOBAL_STATE()->auxilary_buffer->capabilites.agent_coverage_bitmap_size = new_size;
+ if(shm_ptr){
+ munmap(*shm_ptr , *shm_size);
+ *shm_ptr = (void*)mmap(0, new_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ assert(*shm_ptr != MAP_FAILED);
+ }
+ else{
+ fprintf(stderr, "=> shm_ptr is NULL\n");
+ abort();
+ }
+ *shm_size = new_size;
}
+
+
void resize_payload_buffer(uint32_t new_size){
assert(GET_GLOBAL_STATE()->shared_payload_buffer_fd && GET_GLOBAL_STATE()->shared_payload_buffer_size);
assert(GET_GLOBAL_STATE()->shared_payload_buffer_size < new_size && !(new_size & 0xFFF));
@@ -302,7 +317,7 @@ bool remap_payload_buffer(uint64_t virt_guest_addr, CPUState *cpu){
QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
if(!memcmp(block->idstr, "pc.ram", 6)){
//printf("MMUNMAP: %d\n", munmap((void*)(((uint64_t)block->host) + phys_addr), x86_64_PAGE_SIZE));
- if(munmap((void*)(((uint64_t)block->host) + phys_addr), x86_64_PAGE_SIZE) == -1){
+ if(munmap((void*)(((uint64_t)block->host) + phys_addr), x86_64_PAGE_SIZE) == -1){
fprintf(stderr, "munmap failed!\n");
//exit(1);
assert(false);
@@ -351,7 +366,7 @@ bool write_virtual_memory(uint64_t address, uint8_t* data, uint32_t size, CPUSta
attrs = MEMTXATTRS_UNSPECIFIED;
phys_addr = cpu_get_phys_page_attrs_debug(cpu, (address & x86_64_PAGE_MASK), &attrs);
- if (phys_addr == -1){
+ if (phys_addr == INVALID_ADDRESS){
QEMU_PT_PRINTF(MEM_PREFIX, "phys_addr == -1:\t%lx", address);
return false;
}
@@ -680,12 +695,17 @@ void print_48_paging2(uint64_t cr3){
}
-static uint64_t* load_page_table(uint64_t page_table_address, uint64_t* paging_entries_buffer, uint8_t level, bool read_from_snapshot){
+static uint64_t* load_page_table(uint64_t page_table_address, uint64_t* paging_entries_buffer, uint8_t level, bool read_from_snapshot, bool *success){
+ if(page_table_address == INVALID_ADDRESS){
+ *success = false;
+ }
+
if (read_from_snapshot){
- read_snapshot_memory(get_fast_reload_snapshot(), page_table_address, (uint8_t *) paging_entries_buffer, PPAGE_SIZE);
+ *success = read_snapshot_memory(get_fast_reload_snapshot(), page_table_address, (uint8_t *) paging_entries_buffer, PPAGE_SIZE);
}
else{
cpu_physical_memory_rw(page_table_address, (uint8_t *) paging_entries_buffer, PPAGE_SIZE, false);
+ *success = true; /* fix this */
}
return paging_entries_buffer;
}
@@ -702,8 +722,14 @@ static uint64_t get_48_paging_phys_addr(uint64_t cr3, uint64_t addr, bool read_f
uint64_t* paging_entries_buffer_ptr = NULL;
uint64_t page_table_address = 0;
+ bool success = false;
+
page_table_address = (cr3&PAGETABLE_MASK);
- paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 0, read_from_snapshot);
+ paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 0, read_from_snapshot, &success);
+
+ if (unlikely(success == false)){
+ goto fail;
+ }
if(paging_entries_buffer_ptr[pml_4_index]){
address_identifier_4 = ((uint64_t)pml_4_index) << PLEVEL_1_SHIFT;
@@ -713,7 +739,11 @@ static uint64_t get_48_paging_phys_addr(uint64_t cr3, uint64_t addr, bool read_f
if(CHECK_BIT(paging_entries_buffer_ptr[pml_4_index], 0)){ /* otherwise swapped out */
page_table_address = (paging_entries_buffer_ptr[pml_4_index]&PAGETABLE_MASK);
- paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 1, read_from_snapshot);
+ paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 1, read_from_snapshot, &success);
+
+ if (unlikely(success == false)){
+ goto fail;
+ }
if(paging_entries_buffer_ptr[pml_3_index]){
@@ -726,7 +756,11 @@ static uint64_t get_48_paging_phys_addr(uint64_t cr3, uint64_t addr, bool read_f
else{
page_table_address = (paging_entries_buffer_ptr[pml_3_index]&PAGETABLE_MASK);
- paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 2, read_from_snapshot);
+ paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 2, read_from_snapshot, &success);
+
+ if (unlikely(success == false)){
+ goto fail;
+ }
if(paging_entries_buffer_ptr[pml_2_index]){
if (CHECK_BIT(paging_entries_buffer_ptr[pml_2_index], 0)){ /* otherwise swapped out */
@@ -737,7 +771,11 @@ static uint64_t get_48_paging_phys_addr(uint64_t cr3, uint64_t addr, bool read_f
else{
page_table_address = (paging_entries_buffer_ptr[pml_2_index]&PAGETABLE_MASK);
- paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 3, read_from_snapshot);
+ paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 3, read_from_snapshot, &success);
+
+ if (unlikely(success == false)){
+ goto fail;
+ }
if(paging_entries_buffer_ptr[pml_1_index]){
if (CHECK_BIT(paging_entries_buffer_ptr[pml_1_index], 0)){
@@ -753,6 +791,8 @@ static uint64_t get_48_paging_phys_addr(uint64_t cr3, uint64_t addr, bool read_f
}
}
}
+
+ fail:
return INVALID_ADDRESS;
}
@@ -839,15 +879,21 @@ bool is_addr_mapped_cr3_snapshot(uint64_t address, CPUState *cpu, uint64_t cr3){
bool dump_page_cr3_snapshot(uint64_t address, uint8_t* data, CPUState *cpu, uint64_t cr3){
fast_reload_t* snapshot = get_fast_reload_snapshot();
- return read_snapshot_memory(snapshot, get_paging_phys_addr_snapshot(cpu, cr3, address), data, PPAGE_SIZE);
+ uint64_t phys_addr = get_paging_phys_addr_snapshot(cpu, cr3, address);
+ if(phys_addr == INVALID_ADDRESS){
+ return false;
+ }
+ else{
+ return read_snapshot_memory(snapshot, phys_addr, data, PPAGE_SIZE);
+ }
}
bool dump_page_cr3_ht(uint64_t address, uint8_t* data, CPUState *cpu, uint64_t cr3){
hwaddr phys_addr = (hwaddr) get_paging_phys_addr(cpu, cr3, address);
int asidx = cpu_asidx_from_attrs(cpu, MEMTXATTRS_UNSPECIFIED);
- if(phys_addr == 0xffffffffffffffffULL || address_space_rw(cpu_get_address_space(cpu, asidx), phys_addr, MEMTXATTRS_UNSPECIFIED, data, 0x1000, 0)){
- if(phys_addr != 0xffffffffffffffffULL){
+ if(phys_addr == INVALID_ADDRESS || address_space_rw(cpu_get_address_space(cpu, asidx), phys_addr, MEMTXATTRS_UNSPECIFIED, data, 0x1000, 0)){
+ if(phys_addr != INVALID_ADDRESS){
fprintf(stderr, "%s: Warning, read failed:\t%lx (%lx)\n", __func__, address, phys_addr);
}
return false;
diff --git a/nyx/memory_access.h b/nyx/memory_access.h
index bdc0c39dbd..37c4ac0fd7 100644
--- a/nyx/memory_access.h
+++ b/nyx/memory_access.h
@@ -67,7 +67,7 @@ void print_48_paging2(uint64_t cr3);
bool dump_page_ht(uint64_t address, uint8_t* data, CPUState *cpu);
-void resize_coverage_bitmap(uint32_t new_size);
+void resize_shared_memory(uint32_t new_size, uint32_t* shm_size, void** shm_ptr, int fd);
void resize_payload_buffer(uint32_t new_size);
#endif
diff --git a/nyx/nested_hypercalls.c b/nyx/nested_hypercalls.c
index 0600ab832b..23ccb4d93e 100644
--- a/nyx/nested_hypercalls.c
+++ b/nyx/nested_hypercalls.c
@@ -5,7 +5,7 @@
#include "debug.h"
#include "nested_hypercalls.h"
#include "interface.h"
-#include "state.h"
+#include "state/state.h"
#include "pt.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
diff --git a/nyx/page_cache.c b/nyx/page_cache.c
index de64b05fbb..fcb9aa2f3f 100644
--- a/nyx/page_cache.c
+++ b/nyx/page_cache.c
@@ -17,7 +17,7 @@
#include "memory_access.h"
#include "fast_vm_reload.h"
#include "kvm_nested.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#endif
@@ -106,7 +106,7 @@ static bool append_page(page_cache_t* self, uint64_t page, uint64_t cr3){
if(!dump_page_cr3_ht(page, self->page_data+(PAGE_SIZE*self->num_pages), self->cpu, GET_GLOBAL_STATE()->parent_cr3)){
if(!dump_page_cr3_snapshot(page, self->page_data+(PAGE_SIZE*self->num_pages), self->cpu, GET_GLOBAL_STATE()->parent_cr3)){
- fprintf(stderr, "FAILED DUMP PROCESS of PAGE %lx\n", page);
+ //fprintf(stderr, "FAILED DUMP PROCESS of PAGE %lx\n", page);
//memset(self->page_data+(PAGE_SIZE*self->num_pages), 0xff, PAGE_SIZE);
munmap(self->page_data, (self->num_pages+1)*PAGE_SIZE);
@@ -255,7 +255,7 @@ static bool update_page_cache(page_cache_t* self, uint64_t page, khiter_t* k){
kh_value(self->lookup, *k) = (self->num_pages-1)*PAGE_SIZE;
}
else{
- fprintf(stderr, "Fail!!!!\n");
+ //fprintf(stderr, "Fail!!!!\n");
page_cache_unlock(self);
return false;
/*
diff --git a/nyx/patcher.c b/nyx/patcher.c
index f1897ac094..7cb7998849 100644
--- a/nyx/patcher.c
+++ b/nyx/patcher.c
@@ -2,7 +2,7 @@
#include "nyx/memory_access.h"
#include "nyx/disassembler.h"
#include "debug.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
uint8_t cmp_patch_data[] = { 0x38, 0xC0, [2 ... MAX_INSTRUCTION_SIZE]=0x90 }; // CMP AL,AL; NOP, NOP ...
const uint8_t *cmp_patch = &cmp_patch_data[0];
diff --git a/nyx/printk.c b/nyx/printk.c
deleted file mode 100644
index 7f0256ed18..0000000000
--- a/nyx/printk.c
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "qemu/osdep.h"
-#include
-#include "qemu-common.h"
-#include "nyx/memory_access.h"
-#include "nyx/hypercall/hypercall.h"
-#include "nyx/printk.h"
-
-enum reg_types{RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15, RIP};
-
-uint8_t types[] = {RSI, RDX, RCX, R8, R9} ;
-/* calling convention: RDI, RSI, RDX, RCX, R8, R9 */
-
-/* https://www.kernel.org/doc/Documentation/printk-formats.txt :-( */
-
-bool kafl_linux_printk(CPUState *cpu){
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
-
- char printk_buf[0x1000];
-
- uint8_t rsp_buf[0x1000];
- uint8_t rdi_buf[0x1000];
- uint8_t rsi_buf[0x1000];
- uint8_t rdx_buf[0x1000];
- uint8_t rcx_buf[0x1000];
- uint8_t r8_buf[0x1000];
- uint8_t r9_buf[0x1000];
-
- read_virtual_memory((uint64_t)env->regs[RSP], (uint8_t*)rsp_buf, 0x1000, cpu);
- read_virtual_memory((uint64_t)env->regs[RDI], (uint8_t*)rdi_buf, 0x1000, cpu);
-
- uint8_t* buf[] = {rsi_buf, rdx_buf, rcx_buf, r8_buf, r9_buf};
-
-
-
- for(uint16_t i = 0, type = 0; i < 0x1000 && rdi_buf[i] != '\x00'; i++){
-
- if(i > 1 && rdi_buf[i-2] == '%' && rdi_buf[i-1] != '%'){
-
- if(rdi_buf[i-1] == 's' || rdi_buf[i-1] == 'p' || rdi_buf[i-1] == '.'){
-
-
- if(rdi_buf[i] == 'B'){
- rdi_buf[i-1] = 'l';
- rdi_buf[i] = 'x';
- buf[type] = (uint8_t*)env->regs[types[type]];
- }
-
- else if(rdi_buf[i-1] == 'p' && rdi_buf[i] == 'V'){
- rdi_buf[i-1] = 's';
- rdi_buf[i] = ' ';
- read_virtual_memory((uint64_t)env->regs[types[type]], (uint8_t*)buf[type], 0x1000, cpu);
- uint64_t tmp = *((uint64_t*)buf[type]);
- read_virtual_memory(tmp, (uint8_t*)buf[type], 0x1000, cpu);
-
- }
- else if(rdi_buf[i-1] == 'p'){
- rdi_buf[i-1] = 'l';
- memmove(rdi_buf+i+1, rdi_buf+i, 0x1000-i-1);
- rdi_buf[i] = 'x';
- buf[type] = (uint8_t*)env->regs[types[type]];
-
- }
- else {
- read_virtual_memory((uint64_t)env->regs[types[type]], (uint8_t*)buf[type], 0x1000, cpu);
- }
- }
- else{
- buf[type] = (uint8_t*)env->regs[types[type]];
- }
-
- type++;
-
-
- if(type > 4){
- rdi_buf[i] = '\n';
- rdi_buf[i+1] = '\x00';
- break;
- }
- }
-
- }
-
- snprintf(printk_buf, 0x1000, (char*)rdi_buf, buf[0], buf[1], buf[2], buf[3], buf[4]);
-
- if(printk_buf[0] == 0x1){
- //printf("%s", rdi_buf+2);
- //hprintf(printk_buf+2);
- //printf("%s", printk_buf+2);
- if(!strncmp(printk_buf+2, "---[ end Kernel panic", 21)){
- return true;
- }
- }
- else {
- //printf("%s", rdi_buf);
- //hprintf(printk_buf);
- //printf("%s", printk_buf);
- if(!strncmp(printk_buf, "---[ end Kernel panic", 21)){
- return true;
- }
- }
- return false;
-
-}
\ No newline at end of file
diff --git a/nyx/printk.h b/nyx/printk.h
deleted file mode 100644
index 9fac4721db..0000000000
--- a/nyx/printk.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-
-Copyright (C) 2017 Sergej Schumilo
-
-This file is part of QEMU-PT (kAFL).
-
-QEMU-PT is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-QEMU-PT is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with QEMU-PT. If not, see .
-
-*/
-
-#ifndef PRINTK_H
-#define PRINTK_H
-
-bool kafl_linux_printk(CPUState *cpu);
-
-
-#endif
\ No newline at end of file
diff --git a/nyx/pt.c b/nyx/pt.c
index 66a07eb899..abaa8cb35c 100644
--- a/nyx/pt.c
+++ b/nyx/pt.c
@@ -38,7 +38,7 @@ along with QEMU-PT. If not, see .
#include "nyx/redqueen_patch.h"
#include "nyx/patcher.h"
#include "nyx/page_cache.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include
#include "nyx/helpers.h"
@@ -145,7 +145,7 @@ void pt_dump(CPUState *cpu, int bytes){
cpu->intel_pt_run_trashed = true;
break;
case decoder_page_fault:
- fprintf(stderr, "Page not found => 0x%lx\n", libxdc_get_page_fault_addr(GET_GLOBAL_STATE()->decoder));
+ //fprintf(stderr, "Page not found => 0x%lx\n", libxdc_get_page_fault_addr(GET_GLOBAL_STATE()->decoder));
GET_GLOBAL_STATE()->decoder_page_fault = true;
GET_GLOBAL_STATE()->decoder_page_fault_addr = libxdc_get_page_fault_addr(GET_GLOBAL_STATE()->decoder);
break;
@@ -157,7 +157,7 @@ void pt_dump(CPUState *cpu, int bytes){
break;
}
}
- }
+ }
}
diff --git a/nyx/redqueen.c b/nyx/redqueen.c
index 921c1ee1ec..d878013687 100644
--- a/nyx/redqueen.c
+++ b/nyx/redqueen.c
@@ -28,7 +28,7 @@ along with QEMU-PT. If not, see .
#include "patcher.h"
#include "debug.h"
#include "redqueen_trace.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include
#include
diff --git a/nyx/snapshot/block/block_cow.c b/nyx/snapshot/block/block_cow.c
index ecded94277..dab91421f0 100644
--- a/nyx/snapshot/block/block_cow.c
+++ b/nyx/snapshot/block/block_cow.c
@@ -3,7 +3,7 @@
#include
#include "nyx/snapshot/block/block_cow.h"
#include "sysemu/block-backend.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
//#define COW_CACHE_DEBUG
diff --git a/nyx/snapshot/block/nyx_block_snapshot.c b/nyx/snapshot/block/nyx_block_snapshot.c
index e2a0fd897c..caad18f5eb 100644
--- a/nyx/snapshot/block/nyx_block_snapshot.c
+++ b/nyx/snapshot/block/nyx_block_snapshot.c
@@ -11,7 +11,7 @@
#include "nyx/snapshot/block/nyx_block_snapshot.h"
#include "nyx/debug.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
typedef struct fast_reload_cow_entry_s{
uint32_t id;
diff --git a/nyx/snapshot/memory/backend/nyx_debug.c b/nyx/snapshot/memory/backend/nyx_debug.c
index 726b011755..224bff27c7 100644
--- a/nyx/snapshot/memory/backend/nyx_debug.c
+++ b/nyx/snapshot/memory/backend/nyx_debug.c
@@ -29,7 +29,9 @@ void nyx_snapshot_debug_enable(fast_reload_t* self){
}
/* restore operation */
-void nyx_snapshot_debug_restore(shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist, bool verbose){
+uint32_t nyx_snapshot_debug_restore(shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist, bool verbose){
+ uint32_t num_dirty_pages = 0;
+
void* current_region = NULL;
int counter = 0;
for(uint8_t i = 0; i < shadow_memory_state->ram_regions_num; i++){
@@ -59,6 +61,7 @@ void nyx_snapshot_debug_restore(shadow_memory_t* shadow_memory_state, snapshot_p
}
memcpy(host_addr, snapshot_addr, TARGET_PAGE_SIZE);
+ num_dirty_pages++;
}
}
}
@@ -67,6 +70,7 @@ void nyx_snapshot_debug_restore(shadow_memory_t* shadow_memory_state, snapshot_p
if(verbose){
printf("TOTAL: %d\n", counter);
}
+ return num_dirty_pages;
}
void nyx_snapshot_debug_save_root_pages(shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist, bool verbose){
diff --git a/nyx/snapshot/memory/backend/nyx_debug.h b/nyx/snapshot/memory/backend/nyx_debug.h
index de4682be42..653d4ee1a0 100644
--- a/nyx/snapshot/memory/backend/nyx_debug.h
+++ b/nyx/snapshot/memory/backend/nyx_debug.h
@@ -5,6 +5,6 @@
void nyx_snapshot_debug_pre_init(void);
void nyx_snapshot_debug_init(fast_reload_t* self);
void nyx_snapshot_debug_enable(fast_reload_t* self);
-void nyx_snapshot_debug_restore(shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist, bool verbose);
+uint32_t nyx_snapshot_debug_restore(shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist, bool verbose);
void nyx_snapshot_debug_set(fast_reload_t* self);
void nyx_snapshot_debug_save_root_pages(shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist, bool verbose);
diff --git a/nyx/snapshot/memory/backend/nyx_dirty_ring.c b/nyx/snapshot/memory/backend/nyx_dirty_ring.c
index 39e245307b..296d7b47a1 100644
--- a/nyx/snapshot/memory/backend/nyx_dirty_ring.c
+++ b/nyx/snapshot/memory/backend/nyx_dirty_ring.c
@@ -242,7 +242,8 @@ nyx_dirty_ring_t* nyx_dirty_ring_init(shadow_memory_t* shadow_memory){
return self;
}
-static void restore_memory(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
+static uint32_t restore_memory(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
+ uint32_t num_dirty_pages = 0;
void* host_addr = NULL;
void* snapshot_addr = NULL;
uint64_t physical_addr = 0;
@@ -272,13 +273,15 @@ static void restore_memory(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memor
snapshot_addr = shadow_memory_state->ram_regions[kvm_region_slot->region_id].snapshot_region_ptr + entry_offset_addr;
}
- memcpy(host_addr, snapshot_addr, TARGET_PAGE_SIZE);
+ memcpy(host_addr, snapshot_addr, TARGET_PAGE_SIZE);
clear_bit(gfn, (void*)kvm_region_slot->bitmap);
+ num_dirty_pages++;
}
kvm_region_slot->stack_ptr = 0;
}
}
+ return num_dirty_pages;
}
static void save_root_pages(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
@@ -318,8 +321,7 @@ static void save_root_pages(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memo
//entry = &ring->dirty_gfns[ring->reset_index & (ring->size - 1)];
-void nyx_snapshot_nyx_dirty_ring_restore(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
-
+uint32_t nyx_snapshot_nyx_dirty_ring_restore(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
/*
static int perf_counter = 0;
@@ -330,8 +332,8 @@ void nyx_snapshot_nyx_dirty_ring_restore(nyx_dirty_ring_t* self, shadow_memory_t
perf_counter++;
*/
- dirty_ring_flush_and_collect(self, shadow_memory_state, blocklist, kvm_get_vm_fd(kvm_state));
- restore_memory(self, shadow_memory_state, blocklist);
+ dirty_ring_flush_and_collect(self, shadow_memory_state, blocklist, kvm_get_vm_fd(kvm_state));
+ return restore_memory(self, shadow_memory_state, blocklist);
}
void nyx_snapshot_nyx_dirty_ring_save_root_pages(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
diff --git a/nyx/snapshot/memory/backend/nyx_dirty_ring.h b/nyx/snapshot/memory/backend/nyx_dirty_ring.h
index d0fb7c89bb..fa9fab40a3 100644
--- a/nyx/snapshot/memory/backend/nyx_dirty_ring.h
+++ b/nyx/snapshot/memory/backend/nyx_dirty_ring.h
@@ -36,7 +36,7 @@ void nyx_dirty_ring_pre_init(int kvm_fd, int vm_fd);
nyx_dirty_ring_t* nyx_dirty_ring_init(shadow_memory_t* shadow_memory);
-void nyx_snapshot_nyx_dirty_ring_restore(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
+uint32_t nyx_snapshot_nyx_dirty_ring_restore(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
void nyx_snapshot_nyx_dirty_ring_save_root_pages(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
void nyx_snapshot_nyx_dirty_ring_flush(void);
diff --git a/nyx/snapshot/memory/backend/nyx_fdl.c b/nyx/snapshot/memory/backend/nyx_fdl.c
index b1b21c2a69..31649a3348 100644
--- a/nyx/snapshot/memory/backend/nyx_fdl.c
+++ b/nyx/snapshot/memory/backend/nyx_fdl.c
@@ -98,8 +98,9 @@ nyx_fdl_t* nyx_fdl_init(shadow_memory_t* shadow_memory){
#define MEMSET_BITMAP
#ifdef MEMSET_BITMAP
-static void nyx_snapshot_nyx_fdl_restore_new(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
+static uint32_t nyx_snapshot_nyx_fdl_restore_new(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
+ uint32_t num_dirty_pages = 0;
void* current_region = NULL;
struct fdl_result result;
@@ -142,24 +143,26 @@ static void nyx_snapshot_nyx_fdl_restore_new(nyx_fdl_t* self, shadow_memory_t* s
clear_bit(entry_offset_addr>>12, (void*)self->entry[i].bitmap);
memcpy(host_addr, snapshot_addr, TARGET_PAGE_SIZE);
+ num_dirty_pages++;
}
}
#ifdef RESET_VRAM
//nyx_snapshot_nyx_fdl_restore_vram(self, shadow_memory_state);
#endif
+ return num_dirty_pages;
}
#endif
/* restore operation */
-void nyx_snapshot_nyx_fdl_restore(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
+uint32_t nyx_snapshot_nyx_fdl_restore(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
/* not sure which one is faster -> benchmark ASAP */
#ifdef MEMSET_BITMAP
- nyx_snapshot_nyx_fdl_restore_new(self, shadow_memory_state, blocklist);
+ return nyx_snapshot_nyx_fdl_restore_new(self, shadow_memory_state, blocklist);
#else
- nyx_snapshot_nyx_fdl_restore_old(self, shadow_memory_state, blocklist);
+ return nyx_snapshot_nyx_fdl_restore_old(self, shadow_memory_state, blocklist);
#endif
}
diff --git a/nyx/snapshot/memory/backend/nyx_fdl.h b/nyx/snapshot/memory/backend/nyx_fdl.h
index fc9b7b55ba..be81fdcc5c 100644
--- a/nyx/snapshot/memory/backend/nyx_fdl.h
+++ b/nyx/snapshot/memory/backend/nyx_fdl.h
@@ -54,6 +54,6 @@ typedef struct nyx_fdl_s{
}nyx_fdl_t;
nyx_fdl_t* nyx_fdl_init(shadow_memory_t* self);
-void nyx_snapshot_nyx_fdl_restore(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
+uint32_t nyx_snapshot_nyx_fdl_restore(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
void nyx_snapshot_nyx_fdl_save_root_pages(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
diff --git a/nyx/snapshot/memory/nyx_fdl_user.c b/nyx/snapshot/memory/nyx_fdl_user.c
index fec247d1bc..db6aee78c8 100644
--- a/nyx/snapshot/memory/nyx_fdl_user.c
+++ b/nyx/snapshot/memory/nyx_fdl_user.c
@@ -51,7 +51,8 @@ static void nyx_snapshot_user_fdl_reset(nyx_fdl_user_t* self){
}
/* reset operation */
-void nyx_snapshot_user_fdl_restore(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
+uint32_t nyx_snapshot_user_fdl_restore(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
+ uint32_t num_dirty_pages = 0;
if(self){
void* current_region = NULL;
@@ -85,6 +86,7 @@ void nyx_snapshot_user_fdl_restore(nyx_fdl_user_t* self, shadow_memory_t* shadow
#endif
clear_bit(entry_offset_addr>>12, (void*)self->entry[i].bitmap);
memcpy(host_addr, snapshot_addr, TARGET_PAGE_SIZE);
+ num_dirty_pages++;
}
}
@@ -92,6 +94,7 @@ void nyx_snapshot_user_fdl_restore(nyx_fdl_user_t* self, shadow_memory_t* shadow
}
nyx_snapshot_user_fdl_reset(self);
+ return num_dirty_pages;
}
/* set operation (mark pf as dirty) */
diff --git a/nyx/snapshot/memory/nyx_fdl_user.h b/nyx/snapshot/memory/nyx_fdl_user.h
index d20f51837d..391a879aef 100644
--- a/nyx/snapshot/memory/nyx_fdl_user.h
+++ b/nyx/snapshot/memory/nyx_fdl_user.h
@@ -21,5 +21,5 @@ nyx_fdl_user_t* nyx_fdl_user_init(shadow_memory_t* shadow_memory_state);
void nyx_fdl_user_enable(nyx_fdl_user_t* self);
void nyx_fdl_user_set(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state, nyx_fdl_t* nyx_fdl_state, uint64_t addr, uint64_t length);
-void nyx_snapshot_user_fdl_restore(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
+uint32_t nyx_snapshot_user_fdl_restore(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
void nyx_snapshot_nyx_fdl_user_save_root_pages(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
diff --git a/nyx/snapshot/memory/shadow_memory.c b/nyx/snapshot/memory/shadow_memory.c
index ec4fba9513..ae84a24a5b 100644
--- a/nyx/snapshot/memory/shadow_memory.c
+++ b/nyx/snapshot/memory/shadow_memory.c
@@ -395,7 +395,7 @@ void shadow_memory_serialize(shadow_memory_t* self, const char* snapshot_folder)
}
bool shadow_memory_read_physical_memory(shadow_memory_t* self, uint64_t address, void* ptr, size_t size){
-
+
assert(size == 0x1000 && (address & 0xFFFULL) == 0); /* remove this limitation later */
if(address < self->memory_size){
diff --git a/nyx/state.c b/nyx/state.c
deleted file mode 100644
index cf519218c3..0000000000
--- a/nyx/state.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
-
-Copyright (C) 2019 Sergej Schumilo
-
-This file is part of QEMU-PT (HyperTrash / kAFL).
-
-QEMU-PT is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-QEMU-PT is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with QEMU-PT. If not, see .
-
-*/
-
-#include "nyx/state.h"
-#include "nyx/debug.h"
-#include "nyx/memory_access.h"
-#include "sysemu/kvm.h"
-#include "nyx/auxiliary_buffer.h"
-#include "nyx/sharedir.h"
-#include "nyx/fast_vm_reload_sync.h"
-#include "nyx/helpers.h"
-
-//#define STATE_VERBOSE
-
-/* global singleton */
-struct state_qemu_pt global_state;
-
-#define LIBXDC_RELEASE_VERSION_REQUIRED 2
-
-void state_init_global(void){
-#ifdef STATE_VERBOSE
- fprintf(stderr, "--> %s <--\n", __func__);
-#endif
- /* safety first */
- assert(libxdc_get_release_version() == LIBXDC_RELEASE_VERSION_REQUIRED);
-
- global_state.nyx_fdl = false;
-
- global_state.workdir_path = NULL;
-
- global_state.fast_reload_enabled = false;
- global_state.fast_reload_mode = false;
- global_state.fast_reload_path = NULL;
- global_state.fast_reload_pre_path = NULL;
- global_state.fast_reload_pre_image = false;
-
- global_state.fast_reload_snapshot = fast_reload_new();
- global_state.reload_state = init_fast_vm_reload_sync();
-
- global_state.decoder = NULL;
-
- global_state.page_cache = NULL;
-
- global_state.redqueen_enable_pending = false;
- global_state.redqueen_disable_pending = false;
- global_state.redqueen_instrumentation_mode = 0;
- global_state.redqueen_update_blacklist = false;
- global_state.patches_enable_pending = false;
- global_state.patches_disable_pending = false;
- global_state.redqueen_state = NULL;
-
- for(uint8_t i = 0; i < INTEL_PT_MAX_RANGES; i++){
- global_state.pt_ip_filter_configured[i] = false;
- global_state.pt_ip_filter_enabled[i] = false;
- global_state.pt_ip_filter_a[i] = 0x0;
- global_state.pt_ip_filter_b[i] = 0x0;
- }
- global_state.pt_c3_filter = 0;
-
- global_state.enable_hprintf = false;
- global_state.parent_cr3 = 0;
- global_state.disassembler_word_width = 64;
- global_state.nested = false;
- global_state.payload_buffer = 0;
- global_state.nested_payload_pages = NULL;
- global_state.nested_payload_pages_num = 0;
- global_state.protect_payload_buffer = 0;
- global_state.discard_tmp_snapshot = 0;
- global_state.mem_mode = mm_unkown;
-
- init_timeout_detector(&(global_state.timeout_detector));
-
- global_state.in_fuzzing_mode = false;
- global_state.in_reload_mode = true;
- global_state.shutdown_requested = false;
- global_state.cow_cache_full = false;
-
- global_state.auxilary_buffer = NULL;
- memset(&global_state.shadow_config, 0x0, sizeof(auxilary_buffer_config_t));
-
- global_state.decoder_page_fault = false;
- global_state.decoder_page_fault_addr = 0x0;
-
- global_state.dump_page = false;
- global_state.dump_page_addr = 0x0;
-
- global_state.in_redqueen_reload_mode = false;
-
- global_state.pt_trace_mode = true;
- global_state.pt_trace_mode_force = false;
-
- global_state.sharedir = sharedir_new();
-
-
- global_state.shared_bitmap_fd = 0;
- global_state.shared_bitmap_size = 0;
- global_state.shared_ijon_bitmap_size = 0;
- global_state.shared_payload_buffer_fd = 0;
- global_state.shared_payload_buffer_size = 0;
- global_state.shared_bitmap_ptr = NULL;
-
- global_state.pt_trace_size = 0;
- global_state.bb_coverage = 0;
-
- global_state.cap_timeout_detection = 0;
- global_state.cap_only_reload_mode = 0;
- global_state.cap_compile_time_tracing = 0;
- global_state.cap_ijon_tracing = 0;
- global_state.cap_cr3 = 0;
- global_state.cap_compile_time_tracing_buffer_vaddr = 0;
- global_state.cap_ijon_tracing_buffer_vaddr = 0;
-
- QTAILQ_INIT(&global_state.redqueen_breakpoints);
-}
-
-
-fast_reload_t* get_fast_reload_snapshot(void){
- return global_state.fast_reload_snapshot;
-}
-
-void set_fast_reload_mode(bool mode){
- global_state.fast_reload_mode = mode;
-}
-
-void set_fast_reload_path(const char* path){
- assert(global_state.fast_reload_path == NULL);
- global_state.fast_reload_path = malloc(strlen(path)+1);
- strcpy(global_state.fast_reload_path, path);
-}
-
-void set_fast_reload_pre_path(const char* path){
- assert(global_state.fast_reload_pre_path == NULL);
- global_state.fast_reload_pre_path = malloc(strlen(path)+1);
- strcpy(global_state.fast_reload_pre_path, path);
-}
-
-void set_fast_reload_pre_image(void){
- assert(global_state.fast_reload_pre_path != NULL);
- global_state.fast_reload_pre_image = true;
-}
-
-void enable_fast_reloads(void){
- assert(global_state.fast_reload_path != NULL);
- global_state.fast_reload_enabled = true;
-}
-
-void init_page_cache(char* path){
- assert(global_state.page_cache == NULL);
- global_state.page_cache = page_cache_new((CPUState *)qemu_get_cpu(0), path);
- #ifdef STATE_VERBOSE
- debug_printf("\n\nINIT PAGE_CACHE => %s\n", path);
- #endif
-}
-
-page_cache_t* get_page_cache(void){
- assert(global_state.page_cache);
- return global_state.page_cache;
-}
-
-void init_redqueen_state(void){
- global_state.redqueen_state = new_rq_state((CPUState *)qemu_get_cpu(0), get_page_cache());
-}
-
-
-redqueen_t* get_redqueen_state(void){
- assert(global_state.redqueen_state != NULL);
- return global_state.redqueen_state;
-}
-
-
-void dump_global_state(const char* filename_prefix){
- debug_printf("%s\n", __func__);
-
- char* tmp;
-
- assert(asprintf(&tmp, "%s/global.state", filename_prefix) != -1);
- debug_printf("%s\n", tmp);
-
- FILE *fp = fopen(tmp, "wb");
- if(fp == NULL) {
- debug_fprintf(stderr, "[%s] Could not open file %s.\n", __func__, tmp);
- assert(false);
- //exit(EXIT_FAILURE);
- }
-
-
- debug_printf("DUMPING global_state.pt_ip_filter_configured: -\n");
- fwrite(&global_state.pt_ip_filter_configured, sizeof(bool)*4, 1, fp);
-
- debug_printf("DUMPING global_state.pt_ip_filter_a: -\n");
- fwrite(&global_state.pt_ip_filter_a, sizeof(uint64_t)*4, 1, fp);
-
- debug_printf("DUMPING global_state.pt_ip_filter_b: -\n");
- fwrite(&global_state.pt_ip_filter_b, sizeof(uint64_t)*4, 1, fp);
-
- debug_printf("DUMPING global_state.enable_hprintf: %x\n", global_state.enable_hprintf);
- fwrite(&global_state.enable_hprintf, sizeof(bool), 1, fp);
- debug_printf("DUMPING global_state.parent_cr3: %lx\n", global_state.parent_cr3);
- fwrite(&global_state.parent_cr3, sizeof(uint64_t), 1, fp);
-
- debug_printf("DUMPING global_state.disassembler_word_width: %x\n", global_state.disassembler_word_width);
- fwrite(&global_state.disassembler_word_width, sizeof(uint8_t), 1, fp);
- debug_printf("DUMPING global_state.fast_reload_pre_image: %x\n", global_state.fast_reload_pre_image);
- fwrite(&global_state.fast_reload_pre_image, sizeof(bool), 1, fp);
-
- debug_printf("DUMPING global_state.mem_mode: %x\n", global_state.mem_mode);
- fwrite(&global_state.mem_mode, sizeof(uint8_t), 1, fp);
-
- debug_printf("DUMPING global_state.pt_trace_mode: %x\n", global_state.pt_trace_mode);
- fwrite(&global_state.pt_trace_mode, sizeof(bool), 1, fp);
-
- debug_printf("DUMPING global_state.nested: %x\n", global_state.nested);
- fwrite(&global_state.nested, sizeof(bool), 1, fp);
-
- if(!global_state.nested){
- debug_printf("DUMPING global_state.payload_buffer: %lx\n", global_state.payload_buffer);
- fwrite(&global_state.payload_buffer, sizeof(uint64_t), 1, fp);
-
- fwrite(&global_state.cap_timeout_detection, sizeof(global_state.cap_timeout_detection), 1, fp);
- fwrite(&global_state.cap_only_reload_mode, sizeof(global_state.cap_only_reload_mode), 1, fp);
- fwrite(&global_state.cap_compile_time_tracing, sizeof(global_state.cap_compile_time_tracing), 1, fp);
- fwrite(&global_state.cap_ijon_tracing, sizeof(global_state.cap_ijon_tracing), 1, fp);
- fwrite(&global_state.cap_cr3, sizeof(global_state.cap_cr3), 1, fp);
- fwrite(&global_state.cap_compile_time_tracing_buffer_vaddr, sizeof(global_state.cap_compile_time_tracing_buffer_vaddr), 1, fp);
- fwrite(&global_state.cap_ijon_tracing_buffer_vaddr, sizeof(global_state.cap_ijon_tracing_buffer_vaddr), 1, fp);
- fwrite(&global_state.protect_payload_buffer, sizeof(bool), 1, fp);
- }
- else{
- assert(global_state.nested_payload_pages != NULL && global_state.nested_payload_pages_num != 0);
- debug_printf("DUMPING global_state.nested_payload_pages_num: %x\n", global_state.nested_payload_pages_num);
- fwrite(&global_state.nested_payload_pages_num, sizeof(uint32_t), 1, fp);
-
- if(global_state.nested_payload_pages_num != 0){
- debug_printf("DUMPING global_state.protect_payload_buffer: %x\n", global_state.protect_payload_buffer);
- fwrite(&global_state.protect_payload_buffer, sizeof(bool), 1, fp);
- }
-
- for(uint32_t i = 0; i < global_state.nested_payload_pages_num; i++){
- debug_printf("DUMPING global_state.nested_payload_pages[%d]: %lx\n", i, global_state.nested_payload_pages[i]);
- fwrite(&global_state.nested_payload_pages[i], sizeof(uint64_t), 1, fp);
- }
- }
-
-
- fclose(fp);
-
- free(tmp);
-}
-
-void load_global_state(const char* filename_prefix){
- debug_printf("%s\n", __func__);
-
- char* tmp;
-
- assert(asprintf(&tmp, "%s/global.state", filename_prefix) != -1);
- debug_printf("%s\n", tmp);
-
- FILE *fp = fopen(tmp, "rb");
- if(fp == NULL) {
- debug_fprintf(stderr, "[%s] Could not open file %s.\n", __func__, tmp);
- assert(false);
- //exit(EXIT_FAILURE);
- }
-
-
- assert(fread(&global_state.pt_ip_filter_configured, sizeof(bool)*4, 1, fp) == 1);
- debug_printf("LOADING global_state.pt_ip_filter_configured: -\n");
-
- assert(fread(&global_state.pt_ip_filter_a, sizeof(uint64_t)*4, 1, fp) == 1);
- debug_printf("LOADING global_state.pt_ip_filter_a: -\n");
-
- assert(fread(&global_state.pt_ip_filter_b, sizeof(uint64_t)*4, 1, fp) == 1);
- debug_printf("LOADING global_state.pt_ip_filter_b: -\n");
-
- assert(fread(&global_state.enable_hprintf, sizeof(bool), 1, fp) == 1);
- debug_printf("LOADING global_state.enable_hprintf: %x\n", global_state.enable_hprintf);
-
- assert(fread(&global_state.parent_cr3, sizeof(uint64_t), 1, fp) == 1);
- debug_printf("LOADING global_state.parent_cr3: %lx\n", global_state.parent_cr3);
-
- assert(fread(&global_state.disassembler_word_width, sizeof(uint8_t), 1, fp) == 1);
- debug_printf("LOADING global_state.disassembler_word_width: %x\n", global_state.disassembler_word_width);
-
- assert(fread(&global_state.fast_reload_pre_image, sizeof(bool), 1, fp) == 1);
- debug_printf("LOADING global_state.fast_reload_pre_image: %x\n", global_state.fast_reload_pre_image);
-
- assert(fread(&global_state.mem_mode, sizeof(uint8_t), 1, fp) == 1);
- debug_printf("LOADING global_state.mem_mode: %x\n", global_state.mem_mode);
-
- assert(fread(&global_state.pt_trace_mode, sizeof(bool), 1, fp) == 1);
- debug_printf("LOADING global_state.pt_trace_mode: %x\n", global_state.pt_trace_mode);
-
- assert(fread(&global_state.nested, sizeof(bool), 1, fp) == 1);
- debug_printf("LOADING global_state.nested: %x\n", global_state.nested);
-
- if(!global_state.nested){
- assert(fread(&global_state.payload_buffer, sizeof(uint64_t), 1, fp) == 1);
- debug_printf("LOADING global_state.payload_buffer: %lx\n", global_state.payload_buffer);
-
- assert(fread(&global_state.cap_timeout_detection, sizeof(global_state.cap_timeout_detection), 1, fp) == 1);
- assert(fread(&global_state.cap_only_reload_mode, sizeof(global_state.cap_only_reload_mode), 1, fp) == 1);
- assert(fread(&global_state.cap_compile_time_tracing, sizeof(global_state.cap_compile_time_tracing), 1, fp) == 1);
- assert(fread(&global_state.cap_ijon_tracing, sizeof(global_state.cap_ijon_tracing), 1, fp) == 1);
- assert(fread(&global_state.cap_cr3, sizeof(global_state.cap_cr3), 1, fp) == 1);
- assert(fread(&global_state.cap_compile_time_tracing_buffer_vaddr, sizeof(global_state.cap_compile_time_tracing_buffer_vaddr), 1, fp) == 1);
- assert(fread(&global_state.cap_ijon_tracing_buffer_vaddr, sizeof(global_state.cap_ijon_tracing_buffer_vaddr), 1, fp) == 1);
-
- if(!global_state.fast_reload_pre_image){
- assert(fread(&global_state.protect_payload_buffer, sizeof(bool), 1, fp) == 1);
- if(global_state.payload_buffer != 0){
- debug_printf("REMAP PAYLOAD BUFFER!\n");
- remap_payload_buffer(global_state.payload_buffer, ((CPUState *)qemu_get_cpu(0)) );
- }
- else{
- fprintf(stderr, "WARNING: address of payload buffer in snapshot file is zero!\n");
- }
- }
-
- apply_capabilities(qemu_get_cpu(0));
- }
- else{
- assert(fread(&global_state.nested_payload_pages_num, sizeof(uint32_t), 1, fp) == 1);
- debug_printf("LOADING global_state.nested_payload_pages_num: %x\n", global_state.nested_payload_pages_num);
-
- global_state.in_fuzzing_mode = true; /* haaaeeeeh ??? */
- if(!global_state.fast_reload_pre_image){
-
- assert(fread(&global_state.protect_payload_buffer, sizeof(bool), 1, fp) == 1);
- debug_printf("LOADING global_state.protect_payload_buffer: %x\n", global_state.protect_payload_buffer);
-
- global_state.nested_payload_pages = (uint64_t*)malloc(sizeof(uint64_t)*global_state.nested_payload_pages_num);
-
- for(uint32_t i = 0; i < global_state.nested_payload_pages_num; i++){
- assert(fread(&global_state.nested_payload_pages[i], sizeof(uint64_t), 1, fp) == 1);
- debug_printf("LOADED global_state.nested_payload_pages[%d]: %lx\n", i, global_state.nested_payload_pages[i]);
- if(global_state.protect_payload_buffer){
- assert(remap_payload_slot_protected(GET_GLOBAL_STATE()->nested_payload_pages[i], i, ((CPUState *)qemu_get_cpu(0))) == true);
- }
- else{
- remap_payload_slot(global_state.nested_payload_pages[i], i, ((CPUState *)qemu_get_cpu(0)));
- }
- }
-
- }
- }
-
- fclose(fp);
-
- free(tmp);
-}
-
-static void* alloc_auxiliary_buffer(const char* file){
- void* ptr;
- struct stat st;
- int fd = open(file, O_CREAT|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO);
- assert(ftruncate(fd, AUX_BUFFER_SIZE) == 0);
- stat(file, &st);
- QEMU_PT_PRINTF(INTERFACE_PREFIX, "new aux buffer file: (max size: %x) %lx", AUX_BUFFER_SIZE, st.st_size);
-
- assert(AUX_BUFFER_SIZE == st.st_size);
- ptr = mmap(0, AUX_BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (ptr == MAP_FAILED) {
- fprintf(stderr, "aux buffer allocation failed!\n");
- return (void*)-1;
- }
- return ptr;
-}
-
-void init_aux_buffer(const char* filename){
- global_state.auxilary_buffer = (auxilary_buffer_t*)alloc_auxiliary_buffer(filename);
- init_auxiliary_buffer(global_state.auxilary_buffer);
-}
-
-void set_payload_buffer(uint64_t payload_buffer){
- assert(global_state.payload_buffer == 0 && global_state.nested == false);
- global_state.payload_buffer = payload_buffer;
- global_state.nested = false;
-}
-
-void set_payload_pages(uint64_t* payload_pages, uint32_t pages){
- assert(global_state.nested_payload_pages == NULL && global_state.nested_payload_pages_num == 0);
- global_state.nested_payload_pages = (uint64_t*)malloc(sizeof(uint64_t)*pages);
- global_state.nested_payload_pages_num = pages;
- memcpy(global_state.nested_payload_pages, payload_pages, sizeof(uint64_t)*pages);
- global_state.nested = true;
-}
-
-void set_workdir_path(char* workdir){
- assert(workdir && !global_state.workdir_path);
- assert(asprintf(&global_state.workdir_path, "%s", workdir) != -1);
-}
\ No newline at end of file
diff --git a/nyx/state/snapshot_state.c b/nyx/state/snapshot_state.c
new file mode 100644
index 0000000000..b45baa7ff4
--- /dev/null
+++ b/nyx/state/snapshot_state.c
@@ -0,0 +1,186 @@
+
+#include "qemu/osdep.h"
+#include "sysemu/cpus.h"
+#include "nyx/state/snapshot_state.h"
+#include "nyx/debug.h"
+#include "nyx/state/state.h"
+#include "nyx/memory_access.h"
+#include
+
+void serialize_state(const char* filename_prefix, bool is_pre_snapshot){
+ debug_printf("%s\n", __func__);
+
+ char* tmp;
+
+ assert(asprintf(&tmp, "%s/global.state", filename_prefix) != -1);
+ debug_printf("%s\n", tmp);
+
+ FILE *fp = fopen(tmp, "wb");
+ if(fp == NULL) {
+ debug_fprintf(stderr, "[%s] Could not open file %s.\n", __func__, tmp);
+ assert(false);
+ //exit(EXIT_FAILURE);
+ }
+
+ qemu_nyx_state_t* nyx_global_state = GET_GLOBAL_STATE();
+
+ debug_printf("DUMPING global_state.pt_ip_filter_configured: -\n");
+ fwrite(&nyx_global_state->pt_ip_filter_configured, sizeof(bool)*4, 1, fp);
+
+ debug_printf("DUMPING global_state.pt_ip_filter_a: -\n");
+ fwrite(&nyx_global_state->pt_ip_filter_a, sizeof(uint64_t)*4, 1, fp);
+
+ debug_printf("DUMPING global_state.pt_ip_filter_b: -\n");
+ fwrite(&nyx_global_state->pt_ip_filter_b, sizeof(uint64_t)*4, 1, fp);
+
+ debug_printf("DUMPING global_state.parent_cr3: %lx\n", global_state.parent_cr3);
+ fwrite(&nyx_global_state->parent_cr3, sizeof(uint64_t), 1, fp);
+
+ debug_printf("DUMPING global_state.disassembler_word_width: %x\n", global_state.disassembler_word_width);
+ fwrite(&nyx_global_state->disassembler_word_width, sizeof(uint8_t), 1, fp);
+ debug_printf("DUMPING global_state.fast_reload_pre_image: %x\n", global_state.fast_reload_pre_image);
+ fwrite(&nyx_global_state->fast_reload_pre_image, sizeof(bool), 1, fp);
+
+ debug_printf("DUMPING global_state.mem_mode: %x\n", global_state.mem_mode);
+ fwrite(&nyx_global_state->mem_mode, sizeof(uint8_t), 1, fp);
+
+ debug_printf("DUMPING global_state.pt_trace_mode: %x\n", global_state.pt_trace_mode);
+ fwrite(&nyx_global_state->pt_trace_mode, sizeof(bool), 1, fp);
+
+ debug_printf("DUMPING global_state.nested: %x\n", global_state.nested);
+ fwrite(&nyx_global_state->nested, sizeof(bool), 1, fp);
+
+ if(!global_state.nested){
+ debug_printf("DUMPING global_state.payload_buffer: %lx\n", global_state.payload_buffer);
+ fwrite(&nyx_global_state->payload_buffer, sizeof(uint64_t), 1, fp);
+
+ fwrite(&nyx_global_state->cap_timeout_detection, sizeof(global_state.cap_timeout_detection), 1, fp);
+ fwrite(&nyx_global_state->cap_only_reload_mode, sizeof(global_state.cap_only_reload_mode), 1, fp);
+ fwrite(&nyx_global_state->cap_compile_time_tracing, sizeof(global_state.cap_compile_time_tracing), 1, fp);
+ fwrite(&nyx_global_state->cap_ijon_tracing, sizeof(global_state.cap_ijon_tracing), 1, fp);
+ fwrite(&nyx_global_state->cap_cr3, sizeof(global_state.cap_cr3), 1, fp);
+ fwrite(&nyx_global_state->cap_compile_time_tracing_buffer_vaddr, sizeof(global_state.cap_compile_time_tracing_buffer_vaddr), 1, fp);
+ fwrite(&nyx_global_state->cap_ijon_tracing_buffer_vaddr, sizeof(global_state.cap_ijon_tracing_buffer_vaddr), 1, fp);
+ fwrite(&nyx_global_state->protect_payload_buffer, sizeof(bool), 1, fp);
+ }
+ else{
+ assert(global_state.nested_payload_pages != NULL && global_state.nested_payload_pages_num != 0);
+ debug_printf("DUMPING global_state.nested_payload_pages_num: %x\n", global_state.nested_payload_pages_num);
+ fwrite(&nyx_global_state->nested_payload_pages_num, sizeof(uint32_t), 1, fp);
+
+ if(global_state.nested_payload_pages_num != 0){
+ debug_printf("DUMPING global_state.protect_payload_buffer: %x\n", global_state.protect_payload_buffer);
+ fwrite(&nyx_global_state->protect_payload_buffer, sizeof(bool), 1, fp);
+ }
+
+ for(uint32_t i = 0; i < global_state.nested_payload_pages_num; i++){
+ debug_printf("DUMPING global_state.nested_payload_pages[%d]: %lx\n", i, global_state.nested_payload_pages[i]);
+ fwrite(&nyx_global_state->nested_payload_pages[i], sizeof(uint64_t), 1, fp);
+ }
+ }
+
+
+ fclose(fp);
+
+ free(tmp);
+}
+
+void deserialize_state(const char* filename_prefix){
+ debug_printf("%s\n", __func__);
+
+ char* tmp;
+
+ assert(asprintf(&tmp, "%s/global.state", filename_prefix) != -1);
+ debug_printf("%s\n", tmp);
+
+ FILE *fp = fopen(tmp, "rb");
+ if(fp == NULL) {
+ debug_fprintf(stderr, "[%s] Could not open file %s.\n", __func__, tmp);
+ assert(false);
+ //exit(EXIT_FAILURE);
+ }
+
+ qemu_nyx_state_t* nyx_global_state = GET_GLOBAL_STATE();
+
+ assert(fread(&nyx_global_state->pt_ip_filter_configured, sizeof(bool)*4, 1, fp) == 1);
+ debug_printf("LOADING global_state.pt_ip_filter_configured: -\n");
+
+ assert(fread(&nyx_global_state->pt_ip_filter_a, sizeof(uint64_t)*4, 1, fp) == 1);
+ debug_printf("LOADING global_state.pt_ip_filter_a: -\n");
+
+ assert(fread(&nyx_global_state->pt_ip_filter_b, sizeof(uint64_t)*4, 1, fp) == 1);
+ debug_printf("LOADING global_state.pt_ip_filter_b: -\n");
+
+ assert(fread(&nyx_global_state->parent_cr3, sizeof(uint64_t), 1, fp) == 1);
+ debug_printf("LOADING global_state.parent_cr3: %lx\n", global_state.parent_cr3);
+
+ assert(fread(&nyx_global_state->disassembler_word_width, sizeof(uint8_t), 1, fp) == 1);
+ debug_printf("LOADING global_state.disassembler_word_width: %x\n", global_state.disassembler_word_width);
+
+ assert(fread(&nyx_global_state->fast_reload_pre_image, sizeof(bool), 1, fp) == 1);
+ debug_printf("LOADING global_state.fast_reload_pre_image: %x\n", global_state.fast_reload_pre_image);
+
+ assert(fread(&nyx_global_state->mem_mode, sizeof(uint8_t), 1, fp) == 1);
+ debug_printf("LOADING global_state.mem_mode: %x\n", global_state.mem_mode);
+
+ assert(fread(&nyx_global_state->pt_trace_mode, sizeof(bool), 1, fp) == 1);
+ debug_printf("LOADING global_state.pt_trace_mode: %x\n", global_state.pt_trace_mode);
+
+ assert(fread(&nyx_global_state->nested, sizeof(bool), 1, fp) == 1);
+ debug_printf("LOADING global_state.nested: %x\n", global_state.nested);
+
+ if(!global_state.nested){
+ assert(fread(&nyx_global_state->payload_buffer, sizeof(uint64_t), 1, fp) == 1);
+ debug_printf("LOADING global_state.payload_buffer: %lx\n", global_state.payload_buffer);
+
+ assert(fread(&nyx_global_state->cap_timeout_detection, sizeof(global_state.cap_timeout_detection), 1, fp) == 1);
+ assert(fread(&nyx_global_state->cap_only_reload_mode, sizeof(global_state.cap_only_reload_mode), 1, fp) == 1);
+ assert(fread(&nyx_global_state->cap_compile_time_tracing, sizeof(global_state.cap_compile_time_tracing), 1, fp) == 1);
+ assert(fread(&nyx_global_state->cap_ijon_tracing, sizeof(global_state.cap_ijon_tracing), 1, fp) == 1);
+ assert(fread(&nyx_global_state->cap_cr3, sizeof(global_state.cap_cr3), 1, fp) == 1);
+ assert(fread(&nyx_global_state->cap_compile_time_tracing_buffer_vaddr, sizeof(global_state.cap_compile_time_tracing_buffer_vaddr), 1, fp) == 1);
+ assert(fread(&nyx_global_state->cap_ijon_tracing_buffer_vaddr, sizeof(global_state.cap_ijon_tracing_buffer_vaddr), 1, fp) == 1);
+
+ if(!global_state.fast_reload_pre_image){
+ assert(fread(&nyx_global_state->protect_payload_buffer, sizeof(bool), 1, fp) == 1);
+ if(global_state.payload_buffer != 0){
+ debug_printf("REMAP PAYLOAD BUFFER!\n");
+ remap_payload_buffer(global_state.payload_buffer, ((CPUState *)qemu_get_cpu(0)) );
+ }
+ else{
+ fprintf(stderr, "WARNING: address of payload buffer in snapshot file is zero!\n");
+ }
+ }
+
+ assert(apply_capabilities(qemu_get_cpu(0)));
+ }
+ else{
+ assert(fread(&nyx_global_state->nested_payload_pages_num, sizeof(uint32_t), 1, fp) == 1);
+ debug_printf("LOADING global_state.nested_payload_pages_num: %x\n", global_state.nested_payload_pages_num);
+
+ global_state.in_fuzzing_mode = true; /* haaaeeeeh ??? */
+ if(!global_state.fast_reload_pre_image){
+
+ assert(fread(&nyx_global_state->protect_payload_buffer, sizeof(bool), 1, fp) == 1);
+ debug_printf("LOADING global_state.protect_payload_buffer: %x\n", global_state.protect_payload_buffer);
+
+ global_state.nested_payload_pages = (uint64_t*)malloc(sizeof(uint64_t)*global_state.nested_payload_pages_num);
+
+ for(uint32_t i = 0; i < global_state.nested_payload_pages_num; i++){
+ assert(fread(&nyx_global_state->nested_payload_pages[i], sizeof(uint64_t), 1, fp) == 1);
+ debug_printf("LOADED global_state.nested_payload_pages[%d]: %lx\n", i, global_state.nested_payload_pages[i]);
+ if(global_state.protect_payload_buffer){
+ assert(remap_payload_slot_protected(GET_GLOBAL_STATE()->nested_payload_pages[i], i, ((CPUState *)qemu_get_cpu(0))) == true);
+ }
+ else{
+ remap_payload_slot(global_state.nested_payload_pages[i], i, ((CPUState *)qemu_get_cpu(0)));
+ }
+ }
+
+ }
+ }
+
+ fclose(fp);
+
+ free(tmp);
+}
\ No newline at end of file
diff --git a/nyx/state/snapshot_state.h b/nyx/state/snapshot_state.h
new file mode 100644
index 0000000000..397c05e01e
--- /dev/null
+++ b/nyx/state/snapshot_state.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include
+
+void serialize_state(const char* filename_prefix, bool is_pre_snapshot);
+void deserialize_state(const char* filename_prefix);
diff --git a/nyx/state/state.c b/nyx/state/state.c
new file mode 100644
index 0000000000..9a2c827f01
--- /dev/null
+++ b/nyx/state/state.c
@@ -0,0 +1,233 @@
+/*
+
+Copyright (C) 2019 Sergej Schumilo
+
+This file is part of QEMU-PT (HyperTrash / kAFL).
+
+QEMU-PT is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+QEMU-PT is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with QEMU-PT. If not, see .
+
+*/
+
+#include "nyx/state/state.h"
+#include "nyx/debug.h"
+#include "nyx/memory_access.h"
+#include "sysemu/kvm.h"
+#include "nyx/auxiliary_buffer.h"
+#include "nyx/sharedir.h"
+#include "nyx/fast_vm_reload_sync.h"
+#include "nyx/helpers.h"
+
+//#define STATE_VERBOSE
+
+/* global singleton */
+qemu_nyx_state_t global_state;
+
+#define LIBXDC_RELEASE_VERSION_REQUIRED 2
+
+void state_init_global(void){
+#ifdef STATE_VERBOSE
+ fprintf(stderr, "--> %s <--\n", __func__);
+#endif
+ /* safety first */
+ assert(libxdc_get_release_version() == LIBXDC_RELEASE_VERSION_REQUIRED);
+
+ global_state.nyx_fdl = false;
+
+ global_state.workdir_path = NULL;
+
+ global_state.fast_reload_enabled = false;
+ global_state.fast_reload_mode = false;
+ global_state.fast_reload_path = NULL;
+ global_state.fast_reload_pre_path = NULL;
+ global_state.fast_reload_pre_image = false;
+
+ global_state.fast_reload_snapshot = fast_reload_new();
+ global_state.reload_state = init_fast_vm_reload_sync();
+
+ global_state.decoder = NULL;
+
+ global_state.page_cache = NULL;
+
+ global_state.redqueen_enable_pending = false;
+ global_state.redqueen_disable_pending = false;
+ global_state.redqueen_instrumentation_mode = 0;
+ global_state.redqueen_update_blacklist = false;
+ global_state.patches_enable_pending = false;
+ global_state.patches_disable_pending = false;
+ global_state.redqueen_state = NULL;
+
+ for(uint8_t i = 0; i < INTEL_PT_MAX_RANGES; i++){
+ global_state.pt_ip_filter_configured[i] = false;
+ global_state.pt_ip_filter_enabled[i] = false;
+ global_state.pt_ip_filter_a[i] = 0x0;
+ global_state.pt_ip_filter_b[i] = 0x0;
+ }
+ global_state.pt_c3_filter = 0;
+
+ global_state.parent_cr3 = 0;
+ global_state.disassembler_word_width = 64;
+ global_state.nested = false;
+ global_state.payload_buffer = 0;
+ global_state.nested_payload_pages = NULL;
+ global_state.nested_payload_pages_num = 0;
+ global_state.protect_payload_buffer = 0;
+ global_state.discard_tmp_snapshot = 0;
+ global_state.mem_mode = mm_unkown;
+
+ init_timeout_detector(&(global_state.timeout_detector));
+
+ global_state.in_fuzzing_mode = false;
+ global_state.in_reload_mode = true;
+ global_state.shutdown_requested = false;
+ global_state.cow_cache_full = false;
+
+ global_state.auxilary_buffer = NULL;
+ memset(&global_state.shadow_config, 0x0, sizeof(auxilary_buffer_config_t));
+
+ global_state.decoder_page_fault = false;
+ global_state.decoder_page_fault_addr = 0x0;
+
+ global_state.dump_page = false;
+ global_state.dump_page_addr = 0x0;
+
+ global_state.in_redqueen_reload_mode = false;
+
+ global_state.pt_trace_mode = true;
+ global_state.pt_trace_mode_force = false;
+
+ global_state.num_dirty_pages = 0;
+
+ global_state.sharedir = sharedir_new();
+
+
+ global_state.shared_bitmap_fd = 0;
+ global_state.shared_bitmap_size = 0;
+ global_state.shared_bitmap_real_size = 0;
+ global_state.shared_bitmap_ptr = NULL;
+
+ global_state.shared_payload_buffer_fd = 0;
+ global_state.shared_payload_buffer_size = 0;
+
+ global_state.shared_ijon_bitmap_fd = 0;
+ global_state.shared_ijon_bitmap_size = 0;
+ global_state.shared_ijon_bitmap_ptr = NULL;
+
+ global_state.pt_trace_size = 0;
+ global_state.bb_coverage = 0;
+
+ global_state.cap_timeout_detection = 0;
+ global_state.cap_only_reload_mode = 0;
+ global_state.cap_compile_time_tracing = 0;
+ global_state.cap_ijon_tracing = 0;
+ global_state.cap_cr3 = 0;
+ global_state.cap_compile_time_tracing_buffer_vaddr = 0;
+ global_state.cap_ijon_tracing_buffer_vaddr = 0;
+
+ QTAILQ_INIT(&global_state.redqueen_breakpoints);
+}
+
+
+fast_reload_t* get_fast_reload_snapshot(void){
+ return global_state.fast_reload_snapshot;
+}
+
+void set_fast_reload_mode(bool mode){
+ global_state.fast_reload_mode = mode;
+}
+
+void set_fast_reload_path(const char* path){
+ assert(global_state.fast_reload_path == NULL);
+ global_state.fast_reload_path = malloc(strlen(path)+1);
+ strcpy(global_state.fast_reload_path, path);
+}
+
+void set_fast_reload_pre_path(const char* path){
+ assert(global_state.fast_reload_pre_path == NULL);
+ global_state.fast_reload_pre_path = malloc(strlen(path)+1);
+ strcpy(global_state.fast_reload_pre_path, path);
+}
+
+void set_fast_reload_pre_image(void){
+ assert(global_state.fast_reload_pre_path != NULL);
+ global_state.fast_reload_pre_image = true;
+}
+
+void enable_fast_reloads(void){
+ assert(global_state.fast_reload_path != NULL);
+ global_state.fast_reload_enabled = true;
+}
+
+void init_page_cache(char* path){
+ assert(global_state.page_cache == NULL);
+ global_state.page_cache = page_cache_new((CPUState *)qemu_get_cpu(0), path);
+ #ifdef STATE_VERBOSE
+ debug_printf("\n\nINIT PAGE_CACHE => %s\n", path);
+ #endif
+}
+
+page_cache_t* get_page_cache(void){
+ assert(global_state.page_cache);
+ return global_state.page_cache;
+}
+
+void init_redqueen_state(void){
+ global_state.redqueen_state = new_rq_state((CPUState *)qemu_get_cpu(0), get_page_cache());
+}
+
+
+redqueen_t* get_redqueen_state(void){
+ assert(global_state.redqueen_state != NULL);
+ return global_state.redqueen_state;
+}
+
+static void* alloc_auxiliary_buffer(const char* file){
+ void* ptr;
+ struct stat st;
+ int fd = open(file, O_CREAT|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO);
+ assert(ftruncate(fd, AUX_BUFFER_SIZE) == 0);
+ stat(file, &st);
+ QEMU_PT_PRINTF(INTERFACE_PREFIX, "new aux buffer file: (max size: %x) %lx", AUX_BUFFER_SIZE, st.st_size);
+
+ assert(AUX_BUFFER_SIZE == st.st_size);
+ ptr = mmap(0, AUX_BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED) {
+ fprintf(stderr, "aux buffer allocation failed!\n");
+ return (void*)-1;
+ }
+ return ptr;
+}
+
+void init_aux_buffer(const char* filename){
+ global_state.auxilary_buffer = (auxilary_buffer_t*)alloc_auxiliary_buffer(filename);
+ init_auxiliary_buffer(global_state.auxilary_buffer);
+}
+
+void set_payload_buffer(uint64_t payload_buffer){
+ assert(global_state.payload_buffer == 0 && global_state.nested == false);
+ global_state.payload_buffer = payload_buffer;
+ global_state.nested = false;
+}
+
+void set_payload_pages(uint64_t* payload_pages, uint32_t pages){
+ assert(global_state.nested_payload_pages == NULL && global_state.nested_payload_pages_num == 0);
+ global_state.nested_payload_pages = (uint64_t*)malloc(sizeof(uint64_t)*pages);
+ global_state.nested_payload_pages_num = pages;
+ memcpy(global_state.nested_payload_pages, payload_pages, sizeof(uint64_t)*pages);
+ global_state.nested = true;
+}
+
+void set_workdir_path(char* workdir){
+ assert(workdir && !global_state.workdir_path);
+ assert(asprintf(&global_state.workdir_path, "%s", workdir) != -1);
+}
\ No newline at end of file
diff --git a/nyx/state.h b/nyx/state/state.h
similarity index 93%
rename from nyx/state.h
rename to nyx/state/state.h
index 79261b0c0b..79d4ec54d7 100644
--- a/nyx/state.h
+++ b/nyx/state/state.h
@@ -43,7 +43,7 @@ enum mem_mode {
mm_64_l5_paging, /* 32 Bit / L5 Paging */
};
-struct state_qemu_pt{
+typedef struct qemu_nyx_state_s{
/* set if FDL backend is used (required to perform some additional runtime tests) */
bool nyx_fdl;
@@ -91,11 +91,16 @@ struct state_qemu_pt{
/* mmap Options (not migratable) */
int shared_bitmap_fd;
- uint32_t shared_bitmap_size;
- uint32_t shared_ijon_bitmap_size;
+ uint32_t shared_bitmap_size; /* size of the shared memory file */
+ uint32_t shared_bitmap_real_size; /* actual size of the bitmap */
+ void* shared_bitmap_ptr;
+
int shared_payload_buffer_fd;
uint32_t shared_payload_buffer_size;
- void* shared_bitmap_ptr;
+
+ int shared_ijon_bitmap_fd;
+ uint32_t shared_ijon_bitmap_size;
+ void* shared_ijon_bitmap_ptr;
/* Intel PT Options (migratable) */
bool pt_ip_filter_configured[4];
@@ -103,7 +108,6 @@ struct state_qemu_pt{
uint64_t pt_ip_filter_b[4];
/* OPTIONS (MIGRATABLE VIA FAST SNAPSHOTS) */
- bool enable_hprintf;
uint64_t parent_cr3;
uint8_t disassembler_word_width;
bool nested;
@@ -132,6 +136,8 @@ struct state_qemu_pt{
bool in_redqueen_reload_mode;
+ uint32_t num_dirty_pages;
+
/* capabilites */
uint8_t cap_timeout_detection;
uint8_t cap_only_reload_mode;
@@ -146,9 +152,9 @@ struct state_qemu_pt{
sharedir_t* sharedir;
QTAILQ_HEAD(, kvm_sw_breakpoint) redqueen_breakpoints;
-};
+} qemu_nyx_state_t;
-extern struct state_qemu_pt global_state;
+extern qemu_nyx_state_t global_state;
#define GET_GLOBAL_STATE() (&global_state)
@@ -169,9 +175,6 @@ void init_redqueen_state(void);
redqueen_t* get_redqueen_state(void);
-void dump_global_state(const char* filename_prefix);
-void load_global_state(const char* filename_prefix);
-
void init_aux_buffer(const char* filename);
void set_fast_reload_pre_path(const char* path);
diff --git a/nyx/synchronization.c b/nyx/synchronization.c
index c3d1423117..ad279dbbbe 100644
--- a/nyx/synchronization.c
+++ b/nyx/synchronization.c
@@ -8,7 +8,7 @@
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "nyx/debug.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include
#include
#include "qemu/main-loop.h"
@@ -214,6 +214,7 @@ static inline bool synchronization_check_page_not_found(void){
kvm_remove_all_breakpoints(qemu_get_cpu(0));
kvm_vcpu_ioctl(qemu_get_cpu(0), KVM_VMX_PT_DISABLE_PAGE_DUMP_CR3);
kvm_vcpu_ioctl(qemu_get_cpu(0), KVM_VMX_PT_DISABLE_MTF);
+ reset_page_not_found_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer);
failure = true;
}
@@ -241,9 +242,6 @@ void synchronization_lock_hprintf(void){
pthread_cond_wait(&synchronization_lock_condition, &synchronization_lock_mutex);
pthread_mutex_unlock(&synchronization_lock_mutex);
-
- flush_hprintf_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer);
-
}
void synchronization_lock(void){
@@ -255,7 +253,8 @@ void synchronization_lock(void){
}
set_exec_done_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer,
GET_GLOBAL_STATE()->timeout_detector.timeout_sec - GET_GLOBAL_STATE()->timeout_detector.arm_timeout.it_value.tv_sec,
- GET_GLOBAL_STATE()->timeout_detector.timeout_usec - (uint32_t)GET_GLOBAL_STATE()->timeout_detector.arm_timeout.it_value.tv_usec);
+ GET_GLOBAL_STATE()->timeout_detector.timeout_usec - (uint32_t)GET_GLOBAL_STATE()->timeout_detector.arm_timeout.it_value.tv_usec,
+ GET_GLOBAL_STATE()->num_dirty_pages);
/*
if(last_timeout){
reset_timeout_detector_timeout(&(GET_GLOBAL_STATE()->timeout_detector));
@@ -291,7 +290,6 @@ void synchronization_lock(void){
pthread_cond_wait(&synchronization_lock_condition, &synchronization_lock_mutex);
pthread_mutex_unlock(&synchronization_lock_mutex);
- flush_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer);
check_auxiliary_config_buffer(GET_GLOBAL_STATE()->auxilary_buffer, &GET_GLOBAL_STATE()->shadow_config);
set_success_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, 1);
@@ -337,25 +335,6 @@ void synchronization_lock_crash_found(void){
in_fuzzing_loop = false;
}
-void synchronization_lock_asan_found(void){
- if(!in_fuzzing_loop){
- fprintf(stderr, "<%d-%ld>\t%s [NOT IN FUZZING LOOP]\n", getpid(), run_counter, __func__);
- set_success_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, 0);
- }
-
- pt_disable(qemu_get_cpu(0), false);
-
- handle_tmp_snapshot_state();
-
- set_asan_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer);
-
- perform_reload();
-
- //synchronization_lock();
-
- in_fuzzing_loop = false;
-}
-
void synchronization_lock_timeout_found(void){
//fprintf(stderr, "<%d>\t%s\n", getpid(), __func__);
diff --git a/nyx/synchronization.h b/nyx/synchronization.h
index 8f378a8c69..7cd7ef902f 100644
--- a/nyx/synchronization.h
+++ b/nyx/synchronization.h
@@ -37,7 +37,6 @@ void synchronization_lock_hprintf(void);
void synchronization_lock(void);
void synchronization_lock_crash_found(void);
-void synchronization_lock_asan_found(void);
void synchronization_lock_timeout_found(void);
void synchronization_lock_shutdown_detected(void);
void synchronization_cow_full_detected(void);
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 2ee9da4aea..5a347cbba4 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -60,7 +60,7 @@
#endif
#ifdef QEMU_NYX
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#endif
#include "disas/capstone.h"
diff --git a/vl.c b/vl.c
index 13301802c9..10149b9f26 100644
--- a/vl.c
+++ b/vl.c
@@ -137,7 +137,7 @@ int main(int argc, char **argv)
#include "nyx/hypercall/hypercall.h"
#include "nyx/synchronization.h"
#include "nyx/fast_vm_reload.h"
-#include "nyx/state.h"
+#include "nyx/state/state.h"
#include "nyx/fast_vm_reload_sync.h"
#endif