diff --git a/nyx/auxiliary_buffer.c b/nyx/auxiliary_buffer.c index d1341b3379..877e7ddf4f 100644 --- a/nyx/auxiliary_buffer.c +++ b/nyx/auxiliary_buffer.c @@ -19,10 +19,11 @@ along with QEMU-PT. If not, see . */ -#include "nyx/auxiliary_buffer.h" #include #include #include +#include "qemu/osdep.h" +#include "nyx/auxiliary_buffer.h" #include "nyx/state/state.h" #include "nyx/debug.h" #include "nyx/trace_dump.h" @@ -234,7 +235,7 @@ 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){ - //should refactor to let caller directly set the result codes + //TODO refactor to let caller directly set the result codes if (success == 2) { VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_starved); } else { diff --git a/nyx/auxiliary_buffer.h b/nyx/auxiliary_buffer.h index 90dda2f31c..ba64ba4b7c 100644 --- a/nyx/auxiliary_buffer.h +++ b/nyx/auxiliary_buffer.h @@ -20,6 +20,7 @@ along with QEMU-PT. If not, see . */ #pragma once + #include #include @@ -49,7 +50,7 @@ enum nyx_result_codes { }; typedef struct auxilary_buffer_header_s{ - uint64_t magic; /* 0x54502d554d4551 */ + uint64_t magic; uint16_t version; uint16_t hash; /* more to come */ diff --git a/nyx/debug.c b/nyx/debug.c index 77416f2fdc..dd2b5b6dd5 100644 --- a/nyx/debug.c +++ b/nyx/debug.c @@ -1,7 +1,10 @@ -#include + #include #include #include +#include + +#include "qemu/osdep.h" #include "nyx/debug.h" #include "signal.h" @@ -19,7 +22,6 @@ void qemu_backtrace(void){ char **strings = backtrace_symbols(buffer, nptrs); if (strings == NULL) { - //perror("backtrace_symbols"); fprintf(stderr, "backtrace_symbols failed!\n"); return; //exit(EXIT_FAILURE); @@ -54,21 +56,7 @@ static void sigint_handler(int signo, siginfo_t *info, void *extra) { exit(0); } -/* -static void aexit_handler(void) { - fprintf(stderr, "ATTEMPT TO CALL EXIT (PID: %d)\n", getpid()); - qemu_backtrace(); - fprintf(stderr, "WAITING FOR GDB ATTACH (PID: %d...\n", getpid()); - while(1){ - sleep(1); - } -} -*/ - void init_crash_handler(void){ - - //qemu_backtrace(); - struct sigaction action; action.sa_flags = SA_SIGINFO; action.sa_sigaction = sigsegfault_handler; @@ -95,12 +83,6 @@ void init_crash_handler(void){ _exit(1); } } - //atexit(aexit_handler); - - /* test */ - //int i = 0; - //((char*)i)[3] = 0; - } void hexdump_kafl(const void* data, size_t size) { diff --git a/nyx/debug.h b/nyx/debug.h index 5ee02cb30e..3accf293f8 100644 --- a/nyx/debug.h +++ b/nyx/debug.h @@ -5,7 +5,6 @@ #include #include -#include "qemu/osdep.h" #include "qemu-common.h" #include "qemu/log.h" #include "qemu/error-report.h" diff --git a/nyx/fast_vm_reload.c b/nyx/fast_vm_reload.c index eab232f36f..4fd0a38881 100644 --- a/nyx/fast_vm_reload.c +++ b/nyx/fast_vm_reload.c @@ -19,55 +19,49 @@ along with QEMU-PT. If not, see . */ -#include "qemu/osdep.h" -#include "sysemu/sysemu.h" -#include "cpu.h" -#include "qemu/main-loop.h" +#include"qemu/osdep.h" -#include "exec/ram_addr.h" -#include "qemu/rcu_queue.h" -#include "migration/migration.h" -#include "migration/register.h" -#include "migration/savevm.h" -#include "migration/qemu-file.h" -#include "migration/global_state.h" +#include +#include +#include +#include +#include -#include -#include -#include -#include -#include -#include -#include +#include"block/qapi.h" +#include"exec/ram_addr.h" -#include "sysemu/kvm_int.h" -#include "sysemu/cpus.h" -#include "sysemu/reset.h" +#include"migration/global_state.h" +#include"migration/migration.h" +#include"migration/qemu-file.h" +#include"migration/register.h" +#include"migration/savevm.h" +#include"migration/vmstate.h" -#include "nyx/fast_vm_reload.h" -#include "nyx/debug.h" -#include "nyx/state/state.h" -#include "nyx/state/snapshot_state.h" +#include"qemu/main-loop.h" +#include"qemu/rcu_queue.h" -#include "sysemu/block-backend.h" -#include "block/qapi.h" -#include "sysemu/runstate.h" -#include "migration/vmstate.h" +#include"sysemu/block-backend.h" +#include"sysemu/cpus.h" +#include"sysemu/kvm_int.h" +#include"sysemu/reset.h" +#include"sysemu/runstate.h" +#include"sysemu/sysemu.h" -#include "nyx/memory_access.h" +#include"nyx/debug.h" +#include"nyx/fast_vm_reload.h" +#include"nyx/state/snapshot_state.h" +#include"nyx/state/state.h" -#include "nyx/helpers.h" +#include"nyx/helpers.h" +#include"nyx/memory_access.h" -#include "nyx/snapshot/helper.h" -#include "nyx/snapshot/memory/block_list.h" -#include "nyx/snapshot/memory/shadow_memory.h" - -#include "nyx/snapshot/memory/backend/nyx_debug.h" -#include "nyx/snapshot/memory/backend/nyx_fdl.h" -#include "nyx/snapshot/memory/nyx_fdl_user.h" -#include "nyx/snapshot/devices/nyx_device_state.h" -#include "nyx/snapshot/block/nyx_block_snapshot.h" +#include"nyx/snapshot/helper.h" +#include"nyx/snapshot/memory/block_list.h" +#include"nyx/snapshot/memory/shadow_memory.h" +#include"nyx/snapshot/block/nyx_block_snapshot.h" +#include"nyx/snapshot/devices/nyx_device_state.h" +#include"nyx/snapshot/memory/backend/nyx_debug.h" FastReloadMemoryMode mode = RELOAD_MEMORY_MODE_DEBUG; @@ -107,7 +101,6 @@ static void fast_snapshot_init_operation(fast_reload_t* self, const char* snapsh } self->fdl_user_state = nyx_fdl_user_init(self->shadow_memory_state); - nyx_fdl_user_enable(self->fdl_user_state); } @@ -148,20 +141,16 @@ static void fast_snapshot_restore_operation(fast_reload_t* self){ case RELOAD_MEMORY_MODE_DIRTY_RING_DEBUG: 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; } 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){ /* flush all pending block writes */ bdrv_drain_all(); - memory_global_dirty_log_sync(); nyx_device_state_switch_incremental(self->device_state); @@ -231,7 +220,7 @@ void fast_reload_init(fast_reload_t* self){ /* fix this */ void fast_reload_destroy(fast_reload_t* self){ - /* complete me */ + /* TODO: complete me */ //close(self->vmx_fdl_fd); //munmap(self->fdl_data, (self->guest_ram_size/0x1000)*8); @@ -249,9 +238,8 @@ inline static void unlock_snapshot(const char* folder){ char* info_file; char* lock_file; - assert(asprintf(&info_file, "%s/INFO.txt", folder) != -1); - /* info file */ + assert(asprintf(&info_file, "%s/INFO.txt", folder) != -1); FILE* f_info = fopen(info_file, "w+b"); if(GET_GLOBAL_STATE()->fast_reload_pre_image){ const char* msg = "THIS IS A NYX PRE IMAGE SNAPSHOT FOLDER!\n"; @@ -264,7 +252,6 @@ inline static void unlock_snapshot(const char* folder){ fclose(f_info); assert(asprintf(&lock_file, "%s/ready.lock", folder) != -1); - int fd = open(lock_file, O_WRONLY | O_CREAT, S_IRWXU); close(fd); @@ -275,7 +262,6 @@ inline static void wait_for_snapshot(const char* folder){ char* lock_file; assert(asprintf(&lock_file, "%s/ready.lock", folder) != -1); - while( access(lock_file, F_OK ) == -1 ) { sleep(1); @@ -284,8 +270,7 @@ inline static void wait_for_snapshot(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); + nyx_trace(); /* sanity check */ if(!folder_exits(folder)){ @@ -312,7 +297,7 @@ void fast_reload_serialize_to_file(fast_reload_t* self, const char* folder, bool static void fast_reload_create_from_snapshot(fast_reload_t* self, const char* folder, bool lock_iothread, bool pre_snapshot){ - //printf("%s called\n", __func__); + nyx_trace(); assert(self != NULL); wait_for_snapshot(folder); @@ -345,26 +330,22 @@ static void fast_reload_create_from_snapshot(fast_reload_t* self, const char* fo if(!pre_snapshot){ nyx_device_state_save_tsc(self->device_state); } - - //fast_reload_restore(self); - //vm_start(); } void fast_reload_create_from_file(fast_reload_t* self, const char* folder, bool lock_iothread){ - //printf("CALL: %s\n", __func__); + nyx_trace(); fast_reload_create_from_snapshot(self, folder, lock_iothread, false); } void fast_reload_create_from_file_pre_image(fast_reload_t* self, const char* folder, bool lock_iothread){ - //printf("CALL: %s\n", __func__); + nyx_trace(); fast_reload_create_from_snapshot(self, folder, lock_iothread, true); } void fast_reload_create_in_memory(fast_reload_t* self){ - assert(self != NULL); nyx_trace(); - nyx_debug_p(RELOAD_PREFIX,"=> CREATING FAST RELOAD SNAPSHOT FROM CURRENT VM STATE"); + assert(self != NULL); rcu_read_lock(); @@ -380,62 +361,28 @@ void fast_reload_create_in_memory(fast_reload_t* self){ rcu_read_unlock(); cpu_synchronize_all_post_init(); - } - - void fast_reload_restore(fast_reload_t* self){ assert(self != NULL); self->dirty_pages = 0; - //rcu_read_lock(); - //cpu_synchronize_all_states(); - //bdrv_drain_all_begin(); - /* flush all pending block writes */ - bdrv_drain_all(); - //bdrv_flush_all(); - + bdrv_drain_all(); memory_global_dirty_log_sync(); - //unset_black_list_pages(self); nyx_block_snapshot_reset(self->block_state); - /* - for(uint32_t i = 0; i < self->cow_cache_array_size; i++){ - //if(!self->tmp_snapshot.enabled) - cow_cache_reset(self->cow_cache_array[i]); - } - */ - - nyx_device_state_restore(self->device_state); - //fdl_fast_reload(self->qemu_state); - //fdl_fast_reload(self->device_state->qemu_state); nyx_block_snapshot_flush(self->block_state); - //GET_GLOBAL_STATE()->cow_cache_full = false; - //call_fast_change_handlers(); - fast_snapshot_restore_operation(self); - //find_dirty_pages_fdl(self); - //fast_reload_qemu_user_fdl_restore(self); - - - //set_tsc_value(self, self->tmp_snapshot.enabled); nyx_device_state_post_restore(self->device_state); kvm_arch_put_registers(qemu_get_cpu(0), KVM_PUT_FULL_STATE_FAST); qemu_get_cpu(0)->vcpu_dirty = false; - //bdrv_drain_all_end(); - //rcu_read_unlock(); - - - //printf("========================= NEXT\n\n"); - return; } @@ -447,7 +394,7 @@ bool read_snapshot_memory(fast_reload_t* self, uint64_t address, void* ptr, size /* fix this */ void* fast_reload_get_physmem_shadow_ptr(fast_reload_t* self, uint64_t physaddr){ - abort(); /* fix this function first -> pc_piix memory split issue */ + abort(); /* TODO: fix this function first -> pc_piix memory split issue */ /* assert(self != NULL); @@ -470,17 +417,16 @@ void fast_reload_blacklist_page(fast_reload_t* self, uint64_t physaddr){ } bool fast_reload_snapshot_exists(fast_reload_t* self){ - if(!self){ // || !self->qemu_state){ + if(!self){ return false; } return true; } void fast_reload_create_tmp_snapshot(fast_reload_t* self){ - assert(self); // && self->qemu_state); + assert(self); self->dirty_pages = 0; - fast_snapshot_pre_create_incremental_operation(self); if(!self->bitmap_copy){ @@ -488,11 +434,6 @@ void fast_reload_create_tmp_snapshot(fast_reload_t* self){ } coverage_bitmap_copy_to_buffer(self->bitmap_copy); - //GET_GLOBAL_STATE()->cow_cache_full = false; - - //self->tmp_snapshot.root_dirty_pages_num = 0; - - fast_snapshot_create_incremental_operation(self); self->incremental_snapshot_enabled = true; } @@ -504,34 +445,18 @@ void fast_reload_discard_tmp_snapshot(fast_reload_t* self){ /* flush all pending block writes */ bdrv_drain_all(); - memory_global_dirty_log_sync(); - //unset_black_list_pages(self); fast_snapshot_restore_operation(self); - //find_dirty_pages_fdl(self); - //fast_reload_qemu_user_fdl_restore(self); - shadow_memory_restore_memory(self->shadow_memory_state); shadow_memory_switch_snapshot(self->shadow_memory_state, false); - //restore_root_memory(self); - - nyx_device_state_disable_incremental(self->device_state); - //fdl_fast_disable_tmp(self->qemu_state); - //fdl_fast_disable_tmp(self->device_state->qemu_state); nyx_block_snapshot_disable_incremental(self->block_state); - /* - for(uint32_t i = 0; i < self->cow_cache_array_size; i++){ - cow_cache_disable_tmp_mode(self->cow_cache_array[i]); - } - */ self->incremental_snapshot_enabled = false; - } bool fast_reload_root_created(fast_reload_t* self){ diff --git a/nyx/fast_vm_reload.h b/nyx/fast_vm_reload.h index 00333c6f24..7edff2669e 100644 --- a/nyx/fast_vm_reload.h +++ b/nyx/fast_vm_reload.h @@ -21,21 +21,19 @@ along with QEMU-PT. If not, see . #pragma once -#include "qemu/osdep.h" -#include "monitor/monitor.h" -#include "qemu-common.h" -#include "sysemu/runstate.h" +#include"monitor/monitor.h" +#include"sysemu/runstate.h" +#include"qemu-common.h" -#include "nyx/snapshot/memory/block_list.h" -#include "nyx/snapshot/memory/shadow_memory.h" -#include "nyx/snapshot/memory/backend/nyx_fdl.h" -#include "nyx/snapshot/memory/nyx_fdl_user.h" -#include "nyx/snapshot/devices/nyx_device_state.h" +#include"nyx/snapshot/block/nyx_block_snapshot.h" +#include"nyx/snapshot/devices/nyx_device_state.h" +#include"nyx/snapshot/memory/backend/nyx_dirty_ring.h" +#include"nyx/snapshot/memory/backend/nyx_fdl.h" +#include"nyx/snapshot/memory/block_list.h" +#include"nyx/snapshot/memory/nyx_fdl_user.h" +#include"nyx/snapshot/memory/shadow_memory.h" -#include "nyx/snapshot/block/nyx_block_snapshot.h" - -#include "nyx/snapshot/memory/backend/nyx_dirty_ring.h" -#include "nyx/helpers.h" +#include"nyx/helpers.h" typedef enum FastReloadMemoryMode { @@ -95,7 +93,7 @@ typedef struct fast_reload_s{ fast_reload_t* fast_reload_new(void); -/* get rid of this */ +/* TODO: get rid of this */ void fast_reload_create_to_file(fast_reload_t* self, const char* folder, bool lock_iothread); void fast_reload_create_from_file(fast_reload_t* self, const char* folder, bool lock_iothread); void fast_reload_create_from_file_pre_image(fast_reload_t* self, const char* folder, bool lock_iothread); diff --git a/nyx/fast_vm_reload_sync.c b/nyx/fast_vm_reload_sync.c index 40b1b12c18..1ca9def223 100644 --- a/nyx/fast_vm_reload_sync.c +++ b/nyx/fast_vm_reload_sync.c @@ -1,20 +1,24 @@ -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "fast_vm_reload_sync.h" -#include -#include -#include -#include "qapi/qapi-types-run-state.h" -#include "qemu-common.h" -#include "exec/memory.h" -#include "qemu/main-loop.h" -#include "sysemu/kvm_int.h" -#include "sysemu/kvm.h" -#include "sysemu/runstate.h" -#include "nyx/state/state.h" -#include "nyx/fast_vm_reload.h" -#include "nyx/debug.h" -#include "nyx/kvm_nested.h" +#include"qemu/osdep.h" + +#include +#include +#include + +#include"exec/memory.h" +#include"qapi/error.h" +#include"qapi/qapi-types-run-state.h" +#include"qemu/main-loop.h" +#include"qemu-common.h" + +#include"sysemu/kvm.h" +#include"sysemu/kvm_int.h" +#include"sysemu/runstate.h" + +#include"fast_vm_reload_sync.h" +#include"nyx/debug.h" +#include"nyx/fast_vm_reload.h" +#include"nyx/kvm_nested.h" +#include"nyx/state/state.h" extern int save_snapshot(const char *name, Error **errp); extern int load_snapshot(const char *name, Error **errp); @@ -147,7 +151,6 @@ static inline void perform_task_no_block_mode(fast_vm_reload_sync_t* self, FastR switch(request){ case REQUEST_SAVE_SNAPSHOT_PRE: 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, true); @@ -158,34 +161,26 @@ static inline void perform_task_no_block_mode(fast_vm_reload_sync_t* self, FastR adjust_rip(env, get_fast_reload_snapshot()); kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE); case REQUEST_SAVE_SNAPSHOT_ROOT: - kvm_arch_get_registers(cpu); vm_stop(RUN_STATE_SAVE_VM); create_root_snapshot(); fast_reload_restore(get_fast_reload_snapshot()); - //call_fast_change_handlers(); break; - case REQUEST_SAVE_SNAPSHOT_TMP_FIX_RIP: adjust_rip(env, get_fast_reload_snapshot()); kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE); case REQUEST_SAVE_SNAPSHOT_TMP: fast_reload_create_tmp_snapshot(get_fast_reload_snapshot()); fast_reload_restore(get_fast_reload_snapshot()); - break; case REQUEST_LOAD_SNAPSHOT_PRE: abort(); break; case REQUEST_LOAD_SNAPSHOT_ROOT: case REQUEST_LOAD_SNAPSHOT_TMP: - - //vm_stop(RUN_STATE_RESTORE_VM); fast_reload_restore(get_fast_reload_snapshot()); - //call_fast_change_handlers(); break; - case REQUEST_SAVE_SNAPSHOT_ROOT_NESTED_FIX_RIP: kvm_arch_get_registers(cpu); @@ -193,20 +188,17 @@ static inline void perform_task_no_block_mode(fast_vm_reload_sync_t* self, FastR set_nested_rip(cpu, env->eip); kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE); - //case REQUEST_SAVE_SNAPSHOT_ROOT_NESTED: kvm_arch_get_registers(cpu); vm_stop(RUN_STATE_SAVE_VM); create_root_snapshot(); fast_reload_restore(get_fast_reload_snapshot()); break; - default: abort(); } vm_start(); - //call_fast_change_handlers(); cpu_resume(cpu); qemu_mutex_unlock_iothread(); } @@ -216,7 +208,6 @@ static inline void perform_task_block_mode(fast_vm_reload_sync_t* self, FastRelo case REQUEST_SAVE_SNAPSHOT_PRE_FIX_RIP: case REQUEST_SAVE_SNAPSHOT_PRE: 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, true); qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); @@ -225,8 +216,7 @@ static inline void perform_task_block_mode(fast_vm_reload_sync_t* self, FastRelo case REQUEST_SAVE_SNAPSHOT_ROOT: /* TODO: fix this */ vm_stop(RUN_STATE_SAVE_VM); - create_root_snapshot(); /* TODO: Fix this -> fucky in ahci mode */ - //fast_reload_create_in_memory(get_fast_reload_snapshot()); + create_root_snapshot(); /* TODO: fix this -> broken in ahci mode */ break; case REQUEST_SAVE_SNAPSHOT_TMP_FIX_RIP: case REQUEST_SAVE_SNAPSHOT_TMP: @@ -241,7 +231,6 @@ static inline void perform_task_block_mode(fast_vm_reload_sync_t* self, FastRelo vm_stop(RUN_STATE_RESTORE_VM); fast_reload_restore(get_fast_reload_snapshot()); break; - default: abort(); } @@ -289,18 +278,12 @@ void reload_request_discard_tmp(fast_vm_reload_sync_t* self){ } bool check_if_relood_request_exists_pre(fast_vm_reload_sync_t* self){ + + /* TODO: always returns false or abort() ? */ if(self->request_exists_pre){ self->request_exists_pre = false; abort(); -/* - qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false); - qemu_clock_enable(QEMU_CLOCK_VIRTUAL_RT, false); - qemu_clock_enable(QEMU_CLOCK_HOST, false); -*/ - - //printf("%s: task found: %d\n", __func__, self->current_request); - CPUState* cpu = qemu_get_cpu(0); X86CPU *x86_cpu = X86_CPU(cpu); CPUX86State *env = &x86_cpu->env; @@ -357,12 +340,6 @@ bool check_if_relood_request_exists_post(fast_vm_reload_sync_t* self){ self->current_request = REQUEST_VOID; perform_task(self, request); -/* - qemu_clock_enable(QEMU_CLOCK_HOST, true); - qemu_clock_enable(QEMU_CLOCK_VIRTUAL_RT, true); - qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true); -*/ - return true; } return false; diff --git a/nyx/fast_vm_reload_sync.h b/nyx/fast_vm_reload_sync.h index d11bffe472..0df77168b0 100644 --- a/nyx/fast_vm_reload_sync.h +++ b/nyx/fast_vm_reload_sync.h @@ -44,12 +44,9 @@ typedef struct fast_vm_reload_sync_s{ bool request_exists; bool request_exists_pre; - FastReloadRequest current_request; - bool debug_mode; - FastReloadMode mode; - + FastReloadRequest current_request; } fast_vm_reload_sync_t; diff --git a/nyx/file_helper.c b/nyx/file_helper.c index 0bb484a7b8..7a9e022565 100644 --- a/nyx/file_helper.c +++ b/nyx/file_helper.c @@ -11,17 +11,17 @@ #include "file_helper.h" -/////////////////////////////////////////////////////////////////////////////////// -// Private Helper Functions Declarations -/////////////////////////////////////////////////////////////////////////////////// +/* + * Private Helper Functions Declarations + */ size_t _count_lines_in_file(FILE* fp); void _parse_addresses_in_file(FILE* fp, size_t num_addrs, uint64_t* addrs); -/////////////////////////////////////////////////////////////////////////////////// -// Public Functions -/////////////////////////////////////////////////////////////////////////////////// +/* + * Public Functions + */ void write_debug_result(char* buf){ int unused __attribute__((unused)); @@ -92,9 +92,9 @@ void delete_redqueen_files(void){ unused = ftruncate(se_fd, 0); } -/////////////////////////////////////////////////////////////////////////////////// -// Private Helper Functions Definitions -/////////////////////////////////////////////////////////////////////////////////// +/* + * Private Helper Functions Definitions + */ size_t _count_lines_in_file(FILE* fp){ size_t val = 0; diff --git a/nyx/helpers.c b/nyx/helpers.c index a950d20113..6af3a57673 100644 --- a/nyx/helpers.c +++ b/nyx/helpers.c @@ -1,19 +1,22 @@ -#include -#include -#include "nyx/helpers.h" #include "qemu/osdep.h" + #include +#include +#include #include #include -#include "qemu-common.h" + #include "exec/memory.h" #include "qemu/main-loop.h" -#include "sysemu/kvm_int.h" #include "sysemu/kvm.h" -#include "nyx/state/state.h" -#include "nyx/memory_access.h" +#include "sysemu/kvm_int.h" +#include "qemu-common.h" + +#include "nyx/helpers.h" #include "nyx/debug.h" #include "nyx/helpers.h" +#include "nyx/memory_access.h" +#include "nyx/state/state.h" void nyx_abort(char* msg){ set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, msg, strlen(msg)); @@ -112,8 +115,6 @@ static void resize_coverage_bitmap(uint32_t new_bitmap_size){ } bool apply_capabilities(CPUState *cpu){ - //X86CPU *cpux86 = X86_CPU(cpu); - //CPUX86State *env = &cpux86->env; nyx_debug("%s: agent supports timeout detection: %d\n", __func__, GET_GLOBAL_STATE()->cap_timeout_detection); nyx_debug("%s: agent supports only-reload mode: %d\n", __func__, GET_GLOBAL_STATE()->cap_only_reload_mode); diff --git a/nyx/helpers.h b/nyx/helpers.h index d6de5140d1..031dac3910 100644 --- a/nyx/helpers.h +++ b/nyx/helpers.h @@ -1,7 +1,5 @@ #pragma once -#include "qemu/osdep.h" - uint64_t get_rip(CPUState *cpu); typedef struct nyx_coverage_bitmap_copy_s{ diff --git a/nyx/hypercall/configuration.c b/nyx/hypercall/configuration.c index bd04f27a42..db465d8317 100644 --- a/nyx/hypercall/configuration.c +++ b/nyx/hypercall/configuration.c @@ -1,4 +1,5 @@ #include "qemu/osdep.h" + #include "nyx/state/state.h" #include "nyx/hypercall/configuration.h" #include "nyx/memory_access.h" @@ -54,7 +55,11 @@ void handle_hypercall_kafl_set_agent_config(struct kvm_run *run, CPUState *cpu, } if (config.agent_version != NYX_AGENT_VERSION){ - fprintf(stderr, "[QEMU-Nyx] Error: NYX_AGENT_VERSION does not match in agent configuration (%d != %d) - You are probably using an outdated agent...\n", config.agent_version, NYX_AGENT_VERSION); + fprintf(stderr, + "[QEMU-Nyx] Error: NYX_AGENT_VERSION does not match in agent " + "configuration (%d != %d) - " + "You are probably using an outdated agent...\n", + config.agent_version, NYX_AGENT_VERSION); exit(1); } @@ -78,9 +83,7 @@ void handle_hypercall_kafl_set_agent_config(struct kvm_run *run, CPUState *cpu, } GET_GLOBAL_STATE()->cap_cr3 = env->cr[3]; - GET_GLOBAL_STATE()->cap_coverage_bitmap_size = config.coverage_bitmap_size; - GET_GLOBAL_STATE()->input_buffer_size = GET_GLOBAL_STATE()->shared_payload_buffer_size; if (config.input_buffer_size){ diff --git a/nyx/hypercall/configuration.h b/nyx/hypercall/configuration.h index a94e92b3f6..f73927f9ba 100644 --- a/nyx/hypercall/configuration.h +++ b/nyx/hypercall/configuration.h @@ -3,7 +3,10 @@ #include "qemu/osdep.h" #include +#include "sysemu/kvm.h" + void handle_hypercall_kafl_get_host_config(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg); + void handle_hypercall_kafl_set_agent_config(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg); diff --git a/nyx/hypercall/debug.c b/nyx/hypercall/debug.c index 38eb2b48ae..e4570d74d1 100644 --- a/nyx/hypercall/debug.c +++ b/nyx/hypercall/debug.c @@ -1,12 +1,14 @@ #include "qemu/osdep.h" + #include +#include "sysemu/kvm.h" + #include "nyx/synchronization.h" #include "nyx/fast_vm_reload.h" #include "nyx/state/state.h" #include "nyx/hypercall/debug.h" //#define NYX_ENABLE_DEBUG_HYPERCALLS - #ifdef NYX_ENABLE_DEBUG_HYPERCALLS static double get_time(void){ @@ -39,18 +41,14 @@ static void print_time_diff(int iterations){ static void meassure_performance(void){ static int perf_counter = 0; if ((perf_counter%1000) == 0){ - //printf("perf_counter -> %d \n", perf_counter); print_time_diff(1000); } perf_counter++; } void handle_hypercall_kafl_debug_tmp_snapshot(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - //X86CPU *x86_cpu = X86_CPU(cpu); - //CPUX86State *env = &x86_cpu->env; static bool first = true; - //printf("CALLED %s: %lx\n", __func__, hypercall_arg); switch(hypercall_arg&0xFFF){ case 0: /* create root snapshot */ if(!fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_ROOT_EXISTS)){ @@ -58,13 +56,11 @@ void handle_hypercall_kafl_debug_tmp_snapshot(struct kvm_run *run, CPUState *cpu } break; case 1: /* create tmp snapshot */ - //printf("%s: create tmp...(RIP: %lx)\n", __func__, get_rip(cpu)); if(!fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_TMP_EXISTS)){ request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_TMP); } break; case 2: /* load root snapshot (+ discard tmp snapshot) */ - //printf("%s: load root...(RIP: %lx)\n", __func__, get_rip(cpu)); if(fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_TMP_EXISTS)){ reload_request_discard_tmp(GET_GLOBAL_STATE()->reload_state); } @@ -89,24 +85,19 @@ void handle_hypercall_kafl_debug_tmp_snapshot(struct kvm_run *run, CPUState *cpu request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_LOAD_SNAPSHOT_ROOT); break; } - /* - case 6: - printf("%s: -> request to add 0x%lx to block-list\n", __func__, hypercall_arg&(~0xFFF)); - CPUX86State *env = &(X86_CPU(cpu))->env; - kvm_arch_get_registers_fast(cpu); - hwaddr phys_addr = (hwaddr) get_paging_phys_addr(cpu, env->cr[3], hypercall_arg&(~0xFFF)); - fast_reload_blacklist_page(get_fast_reload_snapshot(), phys_addr); - - break; - */ default: abort(); } } -#else +#else /* NYX_ENABLE_DEBUG_HYPERCALLS */ + void handle_hypercall_kafl_debug_tmp_snapshot(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - fprintf(stderr, "[QEMU-Nyx] Error: This hypercall (HYPERCALL_KAFL_DEBUG_TMP) is not enabled!\n"); - set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, (char*)"Disabled debug hypercall called...", strlen("Disabled debug hypercall called...")); + + fprintf(stderr, "[QEMU-Nyx] Error: HYPERCALL_KAFL_DEBUG_TMP not enabled!\n"); + set_abort_reason_auxiliary_buffer( + GET_GLOBAL_STATE()->auxilary_buffer, + (char *)"HYPERCALL_KAFL_DEBUG_TMP is not enabled.", + strlen("HYPERCALL_KAFL_DEBUG_TMP is not enabled.")); synchronization_lock(); } #endif \ No newline at end of file diff --git a/nyx/hypercall/debug.h b/nyx/hypercall/debug.h index 3c8b4aa9f6..334bd4ae18 100644 --- a/nyx/hypercall/debug.h +++ b/nyx/hypercall/debug.h @@ -1,3 +1,6 @@ #pragma once +#include +#include "sysemu/kvm.h" + void handle_hypercall_kafl_debug_tmp_snapshot(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg); \ No newline at end of file diff --git a/nyx/hypercall/hypercall.c b/nyx/hypercall/hypercall.c index 3aff428734..3f90d8b10d 100644 --- a/nyx/hypercall/hypercall.c +++ b/nyx/hypercall/hypercall.c @@ -20,21 +20,21 @@ along with QEMU-PT. If not, see . */ #include "qemu/osdep.h" + #include #include #include #include "qemu-common.h" #include "exec/memory.h" #include "qemu/main-loop.h" +#include "qemu-common.h" - +#include "sysemu/cpus.h" +#include "sysemu/kvm.h" #include "sysemu/kvm_int.h" #include "sysemu/runstate.h" -#include "sysemu/kvm_int.h" -#include "sysemu/kvm.h" -#include "sysemu/cpus.h" - #include "sysemu/hw_accel.h" +#include "sysemu/runstate.h" #include "nyx/pt.h" @@ -50,13 +50,12 @@ along with QEMU-PT. If not, see . #include "nyx/helpers.h" #include "nyx/nested_hypercalls.h" #include "nyx/fast_vm_reload_sync.h" - #include "nyx/redqueen.h" #include "nyx/hypercall/configuration.h" #include "nyx/hypercall/debug.h" //#define DEBUG_HPRINTF -#define HPRINTF_SIZE 0x1000 +#define HPRINTF_SIZE 0x1000 /* FIXME: take from nyx.h */ bool hypercall_enabled = false; char hprintf_buffer[HPRINTF_SIZE]; @@ -93,18 +92,11 @@ bool setup_snapshot_once = false; bool handle_hypercall_kafl_next_payload(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - //nyx_trace(); -/* - kvm_arch_get_registers(cpu); - X86CPU *x86_cpu = X86_CPU(cpu); - CPUX86State *env = &x86_cpu->env; + nyx_trace(); - printf("%s: exception_injected: %d\n", __func__, env->exception_injected); -*/ if(hypercall_enabled){ if (init_state){ set_state_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, 2); - //fprintf(stderr, "--------------------\n"); synchronization_lock(); } else { @@ -115,46 +107,26 @@ bool handle_hypercall_kafl_next_payload(struct kvm_run *run, CPUState *cpu, uint } if(!setup_snapshot_once){ - //pt_reset_bitmap(); - - coverage_bitmap_reset(); request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_ROOT_FIX_RIP); setup_snapshot_once = true; for(int i = 0; i < INTEL_PT_MAX_RANGES; i++){ - //printf("=> %d\n", i); - //if(filter_enabled[i]){ if(GET_GLOBAL_STATE()->pt_ip_filter_configured[i]){ pt_enable_ip_filtering(cpu, i, true, false); } } pt_init_decoder(cpu); - request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_LOAD_SNAPSHOT_ROOT); - //printf("DONE!\n"); - /* - qemu_mutex_lock_iothread(); - nyx_debug_p(CORE_PREFIX, "...GOOOOOO!!!!"); - fast_reload_restore(get_fast_reload_snapshot()); - nyx_debug_p(CORE_PREFIX, "...DONE!!!!"); - qemu_mutex_unlock_iothread(); - */ GET_GLOBAL_STATE()->in_fuzzing_mode = true; set_state_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, 3); - - //sigprof_enabled = true; - //reset_timeout_detector(&GET_GLOBAL_STATE()->timeout_detector); } else{ - //set_illegal_payload(); synchronization_lock(); reset_timeout_detector(&GET_GLOBAL_STATE()->timeout_detector); GET_GLOBAL_STATE()->in_fuzzing_mode = true; - - //printf("RIP => %lx\n", get_rip(cpu)); return true; } } @@ -169,25 +141,15 @@ static void acquire_print_once(CPUState *cpu){ if(acquire_print_once_bool){ acquire_print_once_bool = false; kvm_arch_get_registers(cpu); - //X86CPU *x86_cpu = X86_CPU(cpu); - //CPUX86State *env = &x86_cpu->env; nyx_debug("handle_hypercall_kafl_acquire at:%lx\n", get_rip(cpu)); - //disassemble_at_rip(STDERR_FILENO, get_rip(cpu), cpu, env->cr[3]); } } void handle_hypercall_kafl_acquire(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - //return; if(hypercall_enabled){ if (!init_state){ acquire_print_once(cpu); - //init_det_filter(); synchronization_enter_fuzzing_loop(cpu); - /* - if (pt_enable(cpu, false) == 0){ - cpu->pt_enabled = true; - } - */ } } } @@ -231,7 +193,6 @@ static void set_return_value(CPUState *cpu, uint64_t return_value){ static void handle_hypercall_kafl_req_stream_data(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ static uint8_t req_stream_buffer[0x1000]; - if(is_called_in_fuzzing_mode("HYPERCALL_KAFL_REQ_STREAM_DATA")){ return; } @@ -294,7 +255,6 @@ static void handle_hypercall_kafl_req_stream_data_bulk(struct kvm_run *run, CPUS } - //fprintf(stderr, "%s -> %d\n", __func__, bytes); set_return_value(cpu, bytes); } } @@ -336,20 +296,15 @@ static void release_print_once(CPUState *cpu){ if(release_print_once_bool){ release_print_once_bool = false; kvm_arch_get_registers(cpu); - //X86CPU *x86_cpu = X86_CPU(cpu); - //CPUX86State *env = &x86_cpu->env; nyx_debug("handle_hypercall_kafl_release at:%lx\n", get_rip(cpu)); - //disassemble_at_rip(STDERR_FILENO, get_rip(cpu), cpu, env->cr[3]); } } void handle_hypercall_kafl_release(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - //fprintf(stderr, "%s\n", __func__); if(hypercall_enabled){ if (init_state){ init_state = false; } else { - //printf(CORE_PREFIX, "Got STARVED notification (num=%llu)\n", hypercall_arg); if (hypercall_arg > 0) { GET_GLOBAL_STATE()->starved = 1; } else { @@ -386,9 +341,7 @@ void handle_hypercall_kafl_mtf(struct kvm_run *run, CPUState *cpu, uint64_t hype void handle_hypercall_kafl_page_dump_bp(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg, uint64_t page){ //nyx_trace(); kvm_arch_get_registers_fast(cpu); - nyx_debug("%s --> %lx\n", __func__, get_rip(cpu)); - kvm_vcpu_ioctl(cpu, KVM_VMX_PT_DISABLE_MTF); bool success = false; @@ -403,10 +356,8 @@ void handle_hypercall_kafl_page_dump_bp(struct kvm_run *run, CPUState *cpu, uint } else{ nyx_debug("%s: FAIL: %d\n", __func__, success); - //assert(false); kvm_remove_all_breakpoints(cpu); - kvm_vcpu_ioctl(cpu, KVM_VMX_PT_DISABLE_PAGE_DUMP_CR3); kvm_vcpu_ioctl(cpu, KVM_VMX_PT_ENABLE_MTF); } @@ -415,7 +366,7 @@ void handle_hypercall_kafl_page_dump_bp(struct kvm_run *run, CPUState *cpu, uint static inline void set_page_dump_bp(CPUState *cpu, uint64_t cr3, uint64_t addr){ - nyx_debug("\n\n%s %lx %lx\n\n", __func__, cr3, addr); + nyx_debug("%s --> %lx %lx\n", __func__, cr3, addr); kvm_remove_all_breakpoints(cpu); kvm_insert_breakpoint(cpu, addr, 1, 1); kvm_update_guest_debug(cpu, 0); @@ -481,23 +432,11 @@ static void handle_hypercall_kafl_submit_kasan(struct kvm_run *run, CPUState *cp } } -//#define PANIC_DEBUG - void handle_hypercall_kafl_panic(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ static char reason[1024]; if(hypercall_enabled){ -#ifdef PANIC_DEBUG - if(hypercall_arg){ - //fprintf(stderr, "Panic in user mode!\n"); - //nyx_debug_p(CORE_PREFIX, "Panic in user mode!"); - } else{ - nyx_debug("Panic in kernel mode!\n"); - nyx_debug_p(CORE_PREFIX, "Panic in kernel mode!"); - //assert(0); - } -#endif if(fast_reload_snapshot_exists(get_fast_reload_snapshot()) && GET_GLOBAL_STATE()->in_fuzzing_mode){ - + // TODO: either remove or document + and apply for kasan/timeout as well if(hypercall_arg & 0x8000000000000000ULL){ reason[0] = '\x00'; @@ -530,52 +469,16 @@ void handle_hypercall_kafl_panic(struct kvm_run *run, CPUState *cpu, uint64_t hy } static void handle_hypercall_kafl_create_tmp_snapshot(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - //X86CPU *x86_cpu = X86_CPU(cpu); - //CPUX86State *env = &x86_cpu->env; if(!fast_reload_tmp_created(get_fast_reload_snapshot())){ - /* decode PT data */ pt_disable(qemu_get_cpu(0), false); - /* - kvm_arch_get_registers(cpu); - kvm_cpu_synchronize_state(cpu); - //fprintf(stderr, "%s: CREATE at %lx\n", __func__, get_rip(cpu)); - - //env->eip -= 3; // vmcall size - //kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE); - fast_reload_create_tmp_snapshot(get_fast_reload_snapshot()); - //kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE); - - qemu_mutex_lock_iothread(); - fast_reload_restore(get_fast_reload_snapshot()); - qemu_mutex_unlock_iothread(); - - */ - - - - request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_TMP); //_TMP_FIX_RIP); - + request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_TMP); set_tmp_snapshot_created(GET_GLOBAL_STATE()->auxilary_buffer, 1); - //handle_hypercall_kafl_acquire(run, cpu); - //fprintf(stderr, "%s: CREATE DONE at %lx\n", __func__, get_rip(cpu)); - handle_hypercall_kafl_release(run, cpu, hypercall_arg); } else{ - //fprintf(stderr, "%s: LOAD Continue at %lx\n", __func__, get_rip(cpu)); - //fprintf(stderr, "%s: LOAD at %lx\n", __func__, get_rip(cpu)); - - /* - qemu_mutex_lock_iothread(); - fast_reload_restore(get_fast_reload_snapshot()); - qemu_mutex_unlock_iothread(); - - fprintf(stderr, "%s: LOAD Continue at %lx\n", __func__, get_rip(cpu)); - */ - - //handle_hypercall_kafl_acquire(run, cpu); + // TODO: raise an error? } } @@ -594,21 +497,10 @@ static void handle_hypercall_kafl_panic_extended(struct kvm_run *run, CPUState * 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){ - nyx_debug_p(CORE_PREFIX, "ASan notification in user mode!"); - } else{ - nyx_debug_p(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{ nyx_debug_p(CORE_PREFIX, "KASAN detected during initialization of stage 1 or stage 2 loader"); - //hypercall_snd_char(KAFL_PROTO_KASAN); - nyx_debug_p(CORE_PREFIX, "Protocol - SEND: KAFL_PROTO_KASAN"); - } } } @@ -658,7 +550,7 @@ static void handle_hypercall_kafl_user_range_advise(struct kvm_run *run, CPUStat } static void handle_hypercall_kafl_user_submit_mode(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - //printf("%s\n", __func__); + nyx_trace(); if(is_called_in_fuzzing_mode("KVM_EXIT_KAFL_USER_SUBMIT_MODE")){ return; @@ -843,16 +735,14 @@ static void handle_hypercall_kafl_persist_page_past_snapshot(struct kvm_run *run int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall, uint64_t arg){ int ret = -1; //fprintf(stderr, "%s -> %ld\n", __func__, hypercall); + + // FIXME: ret is always 0. no default case. switch(hypercall){ case KVM_EXIT_KAFL_ACQUIRE: - //timeout_reload_pending = false; - //fprintf(stderr, "KVM_EXIT_KAFL_ACQUIRE\n"); handle_hypercall_kafl_acquire(run, cpu, arg); ret = 0; break; case KVM_EXIT_KAFL_GET_PAYLOAD: - // = false; - //fprintf(stderr, "KVM_EXIT_KAFL_GET_PAYLOAD\n"); handle_hypercall_get_payload(run, cpu, arg); ret = 0; break; @@ -865,44 +755,30 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall ret = 0; break; case KVM_EXIT_KAFL_RELEASE: - //timeout_reload_pending = false; - //fprintf(stderr, "KVM_EXIT_KAFL_RELEASE\n"); handle_hypercall_kafl_release(run, cpu, arg); ret = 0; break; case KVM_EXIT_KAFL_SUBMIT_CR3: - //timeout_reload_pending = false; - //fprintf(stderr, "KVM_EXIT_KAFL_SUBMIT_CR3\n"); handle_hypercall_kafl_cr3(run, cpu, arg); ret = 0; break; case KVM_EXIT_KAFL_SUBMIT_PANIC: - //timeout_reload_pending = false; - //fprintf(stderr, "KVM_EXIT_KAFL_SUBMIT_PANIC\n"); handle_hypercall_kafl_submit_panic(run, cpu, arg); 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); ret = 0; break; case KVM_EXIT_KAFL_PANIC: - //timeout_reload_pending = false; - //fprintf(stderr, "KVM_EXIT_KAFL_PANIC\n"); handle_hypercall_kafl_panic(run, cpu, arg); 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); ret = 0; break; case KVM_EXIT_KAFL_LOCK: - //timeout_reload_pending = false; - //fprintf(stderr, "KVM_EXIT_KAFL_LOCK\n"); handle_hypercall_kafl_lock(run, cpu, arg); ret = 0; break; @@ -910,15 +786,11 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall nyx_abort((char*)"Deprecated hypercall called (HYPERCALL_KAFL_INFO)..."); ret = 0; break; - case KVM_EXIT_KAFL_NEXT_PAYLOAD: - //timeout_reload_pending = false; - //fprintf(stderr, "KVM_EXIT_KAFL_NEXT_PAYLOAD\n"); + case KVM_EXIT_KAFL_NEXT_PAYLOAD: handle_hypercall_kafl_next_payload(run, cpu, arg); ret = 0; break; - case KVM_EXIT_KAFL_PRINTF: - //timeout_reload_pending = false; - //fprintf(stderr, "KVM_EXIT_KAFL_PRINTF\n"); + case KVM_EXIT_KAFL_PRINTF: handle_hypercall_kafl_printf(run, cpu, arg); ret = 0; break; @@ -930,20 +802,15 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall nyx_abort((char*)"Deprecated hypercall called (KVM_EXIT_KAFL_PRINTK)..."); ret = 0; break; - - /* user space only exit reasons */ case KVM_EXIT_KAFL_USER_RANGE_ADVISE: - //timeout_reload_pending = false; handle_hypercall_kafl_user_range_advise(run, cpu, arg); ret = 0; break; case KVM_EXIT_KAFL_USER_SUBMIT_MODE: - //timeout_reload_pending = false; handle_hypercall_kafl_user_submit_mode(run, cpu, arg); ret = 0; break; case KVM_EXIT_KAFL_USER_FAST_ACQUIRE: - //timeout_reload_pending = false; if(handle_hypercall_kafl_next_payload(run, cpu, arg)){ handle_hypercall_kafl_cr3(run, cpu, arg); handle_hypercall_kafl_acquire(run, cpu, arg); @@ -951,46 +818,34 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall ret = 0; break; case KVM_EXIT_KAFL_TOPA_MAIN_FULL: - //timeout_reload_pending = false; - //fprintf(stderr, "pt_handle_overflow\n"); pt_handle_overflow(cpu); ret = 0; break; case KVM_EXIT_KAFL_USER_ABORT: - //timeout_reload_pending = false; handle_hypercall_kafl_user_abort(run, cpu, arg); ret = 0; break; case KVM_EXIT_KAFL_NESTED_CONFIG: - //timeout_reload_pending = false; handle_hypercall_kafl_nested_config(run, cpu, arg); ret = 0; break; case KVM_EXIT_KAFL_NESTED_PREPARE: - //timeout_reload_pending = false; handle_hypercall_kafl_nested_prepare(run, cpu, arg); ret = 0; break; case KVM_EXIT_KAFL_NESTED_ACQUIRE: - //timeout_reload_pending = false; handle_hypercall_kafl_nested_acquire(run, cpu, arg); ret = 0; break; - case KVM_EXIT_KAFL_NESTED_RELEASE: - //timeout_reload_pending = false; - //KVM_EXIT_KAFL_NESTED_RELEASE_GOTO: handle_hypercall_kafl_nested_release(run, cpu, arg); - //unlock_reload_pending(cpu); ret = 0; break; - case KVM_EXIT_KAFL_NESTED_HPRINTF: handle_hypercall_kafl_nested_hprintf(run, cpu, arg); ret = 0; break; - case KVM_EXIT_KAFL_PAGE_DUMP_BP: handle_hypercall_kafl_page_dump_bp(run, cpu, arg, run->debug.arch.pc); ret = 0; diff --git a/nyx/hypercall/hypercall.h b/nyx/hypercall/hypercall.h index 544292f98f..091521f0d6 100644 --- a/nyx/hypercall/hypercall.h +++ b/nyx/hypercall/hypercall.h @@ -21,9 +21,12 @@ along with QEMU-PT. If not, see . #pragma once +#include + #define PAYLOAD_BUFFER_SIZE_64 26 #define PAYLOAD_BUFFER_SIZE_32 20 +// FIXME: move to common nyx.h #define KAFL_MODE_64 0 #define KAFL_MODE_32 1 #define KAFL_MODE_16 2 @@ -82,13 +85,6 @@ bool check_bitmap_byte(uint32_t value); */ #define KASAN_PAYLOAD_32 "\xFA\xB8\x1F\x00\x00\x00\xBB\x09\x00\x00\x00\xB9\x00\x00\x00\x00\x0F\x01\xC1\xF4" -/* - * printk Notifier Payload (x86-64) - * 0f 01 c1 vmcall - * c3 retn - */ -#define PRINTK_PAYLOAD "\x0F\x01\xC1\xC3" - void pt_setup_program(void* ptr); void pt_setup_snd_handler(void (*tmp)(char, void*), void* tmp_s); void pt_setup_ip_filters(uint8_t filter_id, uint64_t start, uint64_t end); @@ -98,8 +94,6 @@ void pt_disable_wrapper(CPUState *cpu); void hypercall_submit_address(uint64_t address); bool hypercall_check_tuple(uint64_t current_addr, uint64_t prev_addr); -//void hypercall_check_in_range(uint64_t* addr); - bool hypercall_check_transition(uint64_t value); void hypercall_submit_transition(uint32_t value); diff --git a/nyx/interface.c b/nyx/interface.c index 9a6c1d444b..c191805087 100644 --- a/nyx/interface.c +++ b/nyx/interface.c @@ -20,6 +20,12 @@ along with QEMU-PT. If not, see . */ #include "qemu/osdep.h" + +#include +#include +#include +#include + #include "qapi/error.h" #include "qemu/cutils.h" #include "hw/qdev-properties.h" @@ -38,8 +44,6 @@ along with QEMU-PT. If not, see . #include "sysemu/qtest.h" #include "qapi/visitor.h" #include "exec/ram_addr.h" -#include -#include #include "pt.h" #include "nyx/hypercall/hypercall.h" #include "nyx/interface.h" @@ -47,14 +51,11 @@ along with QEMU-PT. If not, see . #include "nyx/synchronization.h" #include "nyx/snapshot/devices/state_reallocation.h" #include "nyx/memory_access.h" -#include #include "nyx/state/state.h" #include "nyx/sharedir.h" #include "nyx/helpers.h" #include "nyx/trace_dump.h" -#include - #include "redqueen.h" #define CONVERT_UINT64(x) (uint64_t)(strtoull(x, NULL, 16)) @@ -314,16 +315,6 @@ static bool verify_workdir_state(nyx_interface_state *s, Error **errp){ assert(asprintf(&tmp, "%s/aux_buffer_%d", workdir, id) != -1); - /* - if (file_exits(tmp)){ - nyx_debug_p(INTERFACE_PREFIX, "%s does not already exists...", tmp); - free(tmp); - return false; - } - else { - init_aux_buffer(tmp); - } - */ init_aux_buffer(tmp); free(tmp); @@ -406,13 +397,12 @@ static void nyx_realize(DeviceState *dev, Error **errp){ GET_GLOBAL_STATE()->worker_id = s->worker_id; if (!s->workdir || !verify_workdir_state(s, errp)){ - nyx_error("Error: work dir...\n"); + nyx_error("Error: Invalid work dir...\n"); exit(1); } if (!s->sharedir || !verify_sharedir_state(s, errp)){ nyx_error("Warning: Invalid sharedir...\n"); - //abort(); } else{ sharedir_set_dir(GET_GLOBAL_STATE()->sharedir, s->sharedir); @@ -432,11 +422,8 @@ static Property nyx_interface_properties[] = { DEFINE_PROP_CHR("chardev", nyx_interface_state, chr), DEFINE_PROP_STRING("sharedir", nyx_interface_state, sharedir), - - DEFINE_PROP_STRING("workdir", nyx_interface_state, workdir), DEFINE_PROP_UINT32("worker_id", nyx_interface_state, worker_id, 0xFFFF), - DEFINE_PROP_UINT64("cow_primary_size", nyx_interface_state, cow_primary_size, 0), /* * Since DEFINE_PROP_UINT64 is somehow broken (signed/unsigned madness), @@ -463,9 +450,7 @@ static Property nyx_interface_properties[] = { static void nyx_interface_class_init(ObjectClass *klass, void *data){ DeviceClass *dc = DEVICE_CLASS(klass); - //PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); dc->realize = nyx_realize; - //k->class_id = PCI_CLASS_MEMORY_RAM; dc->props = nyx_interface_properties; set_bit(DEVICE_CATEGORY_MISC, dc->categories); dc->desc = "Nyx Interface"; diff --git a/nyx/kvm_nested.c b/nyx/kvm_nested.c index d7a33782ed..f6eca246d1 100644 --- a/nyx/kvm_nested.c +++ b/nyx/kvm_nested.c @@ -1,11 +1,14 @@ +#include "qemu/osdep.h" +#include +#include "sysemu/kvm.h" + +#include "qemu-common.h" #include "nyx/kvm_nested.h" #include "cpu.h" -#include #include "nyx/debug.h" #include "exec/ram_addr.h" #include "qemu/rcu_queue.h" #include "nyx/state/state.h" -#include "sysemu/kvm.h" #include "pt.h" #define PPAGE_SIZE 0x1000 @@ -284,30 +287,12 @@ void print_48_paging(uint64_t cr3){ write_address(0, 0x1000, 0); } -/* -static bool change_page_permissions(uint64_t phys_addr, CPUState *cpu){ - RAMBlock *block; - - //MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - - QLIST_FOREACH_RCU(block, &ram_list.blocks, next) { - if(!memcmp(block->idstr, "pc.ram", 6)){ - printf("FOUND AND MODIFIED! %lx\n", mprotect((void*)(((uint64_t)block->host) + phys_addr), 0x1000, PROT_NONE)); - break; - } - } - - return true; -} -*/ - uint64_t get_nested_guest_rip(CPUState *cpu){ X86CPU *cpux86 = X86_CPU(cpu); CPUX86State *env = &cpux86->env; kvm_vcpu_ioctl(cpu, KVM_GET_NESTED_STATE, env->nested_state); - struct vmcs12* saved_vmcs = (struct vmcs12*)&(env->nested_state->data); return saved_vmcs->guest_rip; @@ -319,7 +304,6 @@ uint64_t get_nested_host_rip(CPUState *cpu){ CPUX86State *env = &cpux86->env; kvm_vcpu_ioctl(cpu, KVM_GET_NESTED_STATE, env->nested_state); - struct vmcs12* saved_vmcs = (struct vmcs12*)&(env->nested_state->data); return saved_vmcs->host_rip; @@ -331,7 +315,6 @@ uint64_t get_nested_host_cr3(CPUState *cpu){ CPUX86State *env = &cpux86->env; kvm_vcpu_ioctl(cpu, KVM_GET_NESTED_STATE, env->nested_state); - struct vmcs12* saved_vmcs = (struct vmcs12*)&(env->nested_state->data); return saved_vmcs->host_cr3; @@ -342,13 +325,9 @@ void set_nested_rip(CPUState *cpu, uint64_t rip){ X86CPU *cpux86 = X86_CPU(cpu); CPUX86State *env = &cpux86->env; - //kvm_vcpu_ioctl(cpu, KVM_GET_NESTED_STATE, env->nested_state); - struct vmcs12* saved_vmcs = (struct vmcs12*)&(env->nested_state->data); saved_vmcs->guest_rip = rip; - - //return saved_vmcs->guest_rip; } void kvm_nested_get_info(CPUState *cpu){ @@ -358,57 +337,13 @@ void kvm_nested_get_info(CPUState *cpu){ kvm_vcpu_ioctl(cpu, KVM_GET_NESTED_STATE, env->nested_state); - struct vmcs12* saved_vmcs = (struct vmcs12*)&(env->nested_state->data); + __attribute__((unused)) struct vmcs12* saved_vmcs = (struct vmcs12*)&(env->nested_state->data); nyx_debug_p(NESTED_VM_PREFIX, "VMCS host_cr3:\t%lx", saved_vmcs->host_cr3); nyx_debug_p(NESTED_VM_PREFIX, "VMCS host_cr4:\t%lx", saved_vmcs->host_cr4); nyx_debug_p(NESTED_VM_PREFIX, "VMCS host_ia32_efer:\t%lx", saved_vmcs->host_ia32_efer); nyx_debug_p(NESTED_VM_PREFIX, "VMCS host_cr0:\t%lx", saved_vmcs->host_cr0); return; - - //cpu->parent_cr3 = saved_vmcs->host_cr3+0x1000; - GET_GLOBAL_STATE()->parent_cr3 = saved_vmcs->host_cr3+0x1000; - fprintf(stderr, "saved_vmcs->guest_cr3: %lx %lx %lx\n", saved_vmcs->guest_cr3, saved_vmcs->host_cr3, env->cr[3]); - pt_set_cr3(cpu, saved_vmcs->host_cr3+0x1000, false); /* USERSPACE */ - //pt_set_cr3(cpu, saved_vmcs->host_cr3+0x1000, false); /* KERNELSPACE QEMU fuzzing fix...fucking kpti (https://gruss.cc/files/kaiser.pdf)!!! */ - - /* let's modify page permissions of our CR3 referencing PTs */ - //change_page_permissions(cpu->parent_cr3, cpu); - - - if (!(saved_vmcs->host_cr0 & CR0_PG_MASK)) { - printf("PG disabled\n"); - } - else{ - if (saved_vmcs->host_cr4 & CR4_PAE_MASK) { - if (saved_vmcs->host_ia32_efer & (1 << 10)) { - if (saved_vmcs->host_cr0 & CR4_LA57_MASK) { - nyx_debug_p(NESTED_VM_PREFIX, "mem_info_la57"); - abort(); - //mem_info_la57(mon, env); - } else { - nyx_debug_p(NESTED_VM_PREFIX, " ==== L1 Page Tables ===="); - print_48_paging(saved_vmcs->host_cr3); - - if(saved_vmcs->ept_pointer){ - nyx_debug_p(NESTED_VM_PREFIX, " ==== L2 Page Tables ===="); - print_48_paging(saved_vmcs->ept_pointer); - } - //mem_info_la48(mon, env); - } - } - else{ - nyx_debug_p(NESTED_VM_PREFIX, "mem_info_pae32"); - abort(); - //mem_info_pae32(mon, env); - } - } - else { - nyx_debug_p(NESTED_VM_PREFIX, "mem_info_32"); - abort(); - //mem_info_32(mon, env); - } - } } #define AREA_DESC_LEN 256 @@ -430,8 +365,6 @@ typedef struct { }config_t; void print_configuration(FILE *stream, void* configuration, size_t size){ -//void print_configuration(void* configuration, size_t size){ - fprintf(stream, "%s: size: %lx\n", __func__, size); assert((size-sizeof(config_t))%sizeof(area_t_export_t) == 0); diff --git a/nyx/kvm_nested.h b/nyx/kvm_nested.h index bf284a7154..a270c2aa60 100644 --- a/nyx/kvm_nested.h +++ b/nyx/kvm_nested.h @@ -1,5 +1,5 @@ #pragma once -#include "qemu/osdep.h" +#include void print_48_paging(uint64_t cr3); void kvm_nested_get_info(CPUState *cpu); diff --git a/nyx/memory_access.c b/nyx/memory_access.c index b177cb807c..53cb8fd037 100644 --- a/nyx/memory_access.c +++ b/nyx/memory_access.c @@ -18,8 +18,11 @@ You should have received a copy of the GNU General Public License along with QEMU-PT. If not, see . */ -#include #include "qemu/osdep.h" + +#include +#include "exec/gdbstub.h" + #include "sysemu/sysemu.h" #include "cpu.h" #include "exec/ram_addr.h" @@ -29,9 +32,7 @@ along with QEMU-PT. If not, see . #include "nyx/hypercall/hypercall.h" #include "debug.h" #include "nyx/fast_vm_reload.h" -#include "exec/gdbstub.h" #include "nyx/state/state.h" -#include "sysemu/kvm.h" #include "nyx/helpers.h" #define INVALID_ADDRESS 0xFFFFFFFFFFFFFFFFULL @@ -141,31 +142,23 @@ bool write_physical_memory(uint64_t address, uint8_t* data, uint32_t size, CPUSt } static void refresh_kvm(CPUState *cpu){ - //int ret = 0; if (!cpu->vcpu_dirty) { - //kvm_arch_get_registers_fast(cpu); kvm_arch_get_registers(cpu); - - //cpu->vcpu_dirty = true; } } static void refresh_kvm_non_dirty(CPUState *cpu){ if (!cpu->vcpu_dirty) { kvm_arch_get_registers_fast(cpu); - //kvm_arch_get_registers(cpu); } } bool remap_payload_slot(uint64_t phys_addr, uint32_t slot, CPUState *cpu){ - //assert(0); /* nested code -> test me later */ - assert(GET_GLOBAL_STATE()->shared_payload_buffer_fd && GET_GLOBAL_STATE()->shared_payload_buffer_size); RAMBlock *block; refresh_kvm_non_dirty(cpu); uint32_t i = slot; - uint64_t phys_addr_ram_offset = address_to_ram_offset(phys_addr); QLIST_FOREACH_RCU(block, &ram_list.blocks, next) { @@ -174,9 +167,6 @@ bool remap_payload_slot(uint64_t phys_addr, uint32_t slot, CPUState *cpu){ munmap((void*)(((uint64_t)block->host) + phys_addr_ram_offset), x86_64_PAGE_SIZE); mmap((void*)(((uint64_t)block->host) + phys_addr_ram_offset), 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, GET_GLOBAL_STATE()->shared_payload_buffer_fd, (i*x86_64_PAGE_SIZE)); - //printf("MMUNMAP: %d\n", munmap((void*)(((uint64_t)block->host) + phys_addr), x86_64_PAGE_SIZE)); - //printf("MMAP: %p\n", mmap((void*)(((uint64_t)block->host) + phys_addr), 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, GET_GLOBAL_STATE()->shared_payload_buffer_fd, (i*x86_64_PAGE_SIZE))); - fast_reload_blacklist_page(get_fast_reload_snapshot(), phys_addr); break; } @@ -186,7 +176,6 @@ bool remap_payload_slot(uint64_t phys_addr, uint32_t slot, CPUState *cpu){ } bool remap_slot(uint64_t addr, uint32_t slot, CPUState *cpu, int fd, uint64_t shm_size, bool virtual, uint64_t cr3){ - //printf("%s ---> \n", __func__); assert(fd && shm_size); assert((slot*x86_64_PAGE_SIZE) < shm_size); @@ -206,8 +195,6 @@ bool remap_slot(uint64_t addr, uint32_t slot, CPUState *cpu, int fd, uint64_t sh } } uint64_t phys_addr_ram_offset = address_to_ram_offset(phys_addr); - - //printf("phys_addr -> %lx\n", phys_addr); nyx_debug("%s: addr => %lx phys_addr => %lx\n", __func__, addr, phys_addr); @@ -223,9 +210,6 @@ bool remap_slot(uint64_t addr, uint32_t slot, CPUState *cpu, int fd, uint64_t sh assert(false); } - //printf("MMUNMAP: %d\n", munmap((void*)(((uint64_t)block->host) + phys_addr), x86_64_PAGE_SIZE)); - //printf("MMAP: %p\n", mmap((void*)(((uint64_t)block->host) + phys_addr), 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, (i*x86_64_PAGE_SIZE))); - fast_reload_blacklist_page(get_fast_reload_snapshot(), phys_addr); break; } @@ -235,8 +219,6 @@ bool remap_slot(uint64_t addr, uint32_t slot, CPUState *cpu, int fd, uint64_t sh } bool remap_payload_slot_protected(uint64_t phys_addr, uint32_t slot, CPUState *cpu){ - //assert(0); /* nested code -> test me later */ - assert(GET_GLOBAL_STATE()->shared_payload_buffer_fd && GET_GLOBAL_STATE()->shared_payload_buffer_size); RAMBlock *block; refresh_kvm_non_dirty(cpu); @@ -252,9 +234,6 @@ bool remap_payload_slot_protected(uint64_t phys_addr, uint32_t slot, CPUState *c munmap((void*)(((uint64_t)block->host) + phys_addr_ram_offset), x86_64_PAGE_SIZE); mmap((void*)(((uint64_t)block->host) + phys_addr_ram_offset), 0x1000, PROT_READ , MAP_SHARED | MAP_FIXED, GET_GLOBAL_STATE()->shared_payload_buffer_fd, (i*x86_64_PAGE_SIZE)); - //printf("MMUNMAP: %d\n", munmap((void*)(((uint64_t)block->host) + phys_addr), x86_64_PAGE_SIZE)); - //printf("MMAP: %p\n", mmap((void*)(((uint64_t)block->host) + phys_addr), 0x1000, PROT_READ , MAP_SHARED | MAP_FIXED, GET_GLOBAL_STATE()->shared_payload_buffer_fd, (i*x86_64_PAGE_SIZE))); - fast_reload_blacklist_page(get_fast_reload_snapshot(), phys_addr); break; } @@ -295,8 +274,6 @@ bool remap_payload_buffer(uint64_t virt_guest_addr, CPUState *cpu){ refresh_kvm_non_dirty(cpu); for(uint32_t i = 0; i < (GET_GLOBAL_STATE()->shared_payload_buffer_size/x86_64_PAGE_SIZE); i++){ - //MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - //hwaddr phys_addr = cpu_get_phys_page_attrs_debug(cpu, ((virt_guest_addr+(i*x86_64_PAGE_SIZE)) & x86_64_PAGE_MASK), &attrs); uint64_t phys_addr = get_paging_phys_addr(cpu, GET_GLOBAL_STATE()->parent_cr3, ((virt_guest_addr+(i*x86_64_PAGE_SIZE)) & x86_64_PAGE_MASK)); assert(phys_addr != INVALID_ADDRESS); @@ -305,17 +282,12 @@ 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_ram_offset), x86_64_PAGE_SIZE) == -1){ nyx_error("munmap failed!\n"); - //exit(1); assert(false); } - //printf("MMAP: %lx\n", mmap((void*)(((uint64_t)block->host) + phys_addr), 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, shared_payload_buffer_fd, (i*x86_64_PAGE_SIZE))); - if(mmap((void*)(((uint64_t)block->host) + phys_addr_ram_offset), 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, GET_GLOBAL_STATE()->shared_payload_buffer_fd, (i*x86_64_PAGE_SIZE)) == MAP_FAILED){ nyx_error("mmap failed!\n"); - //exit(1); assert(false); } @@ -335,7 +307,7 @@ bool remap_payload_buffer(uint64_t virt_guest_addr, CPUState *cpu){ bool write_virtual_memory(uint64_t address, uint8_t* data, uint32_t size, CPUState *cpu) { - /* Todo: later &address_space_memory + phys_addr -> mmap SHARED */ + /* TODO: later &address_space_memory + phys_addr -> mmap SHARED */ int asidx; MemTxAttrs attrs; hwaddr phys_addr; @@ -350,7 +322,6 @@ bool write_virtual_memory(uint64_t address, uint8_t* data, uint32_t size, CPUSta l = counter; refresh_kvm(cpu); - //cpu_synchronize_state(cpu); asidx = cpu_asidx_from_attrs(cpu, MEMTXATTRS_UNSPECIFIED); attrs = MEMTXATTRS_UNSPECIFIED; phys_addr = cpu_get_phys_page_attrs_debug(cpu, (address & x86_64_PAGE_MASK), &attrs); @@ -474,8 +445,6 @@ static int redqueen_update_guest_debug(CPUState *cpu) { } return kvm_vcpu_ioctl(cpu, KVM_SET_GUEST_DEBUG, &data.dbg); - - return 0; } static void redqueen_remove_all_breakpoints(CPUState *cpu) { @@ -558,7 +527,6 @@ int insert_breakpoint(CPUState *cpu, uint64_t addr, uint64_t len){ int remove_breakpoint(CPUState *cpu, uint64_t addr, uint64_t len){ - //fprintf(stderr, "%s %lx\n", __func__, addr); redqueen_remove_breakpoint(cpu, addr, len); redqueen_update_guest_debug(cpu); return 0; @@ -809,7 +777,6 @@ static uint64_t get_48_paging_phys_addr(uint64_t cr3, uint64_t addr, bool read_f bool read_virtual_memory(uint64_t address, uint8_t* data, uint32_t size, CPUState *cpu){ uint8_t tmp_buf[x86_64_PAGE_SIZE]; - //MemTxAttrs attrs; hwaddr phys_addr; int asidx; @@ -825,12 +792,10 @@ bool read_virtual_memory(uint64_t address, uint8_t* data, uint32_t size, CPUStat len_to_copy = x86_64_PAGE_SIZE; asidx = cpu_asidx_from_attrs(cpu, MEMTXATTRS_UNSPECIFIED); - //MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; #ifdef DEBUG_48BIT_WALK phys_addr_2 = cpu_get_phys_page_attrs_debug(cpu, (address & x86_64_PAGE_MASK), &attrs); #endif phys_addr = (hwaddr)get_paging_phys_addr(cpu, env->cr[3], address) & 0xFFFFFFFFFFFFF000ULL;// != 0xFFFFFFFFFFFFFFFFULL) - //nyx_debug_p(MEM_PREFIX, "TRANSLATE: %lx -> %lx == %lx", address, phys_addr, phys_addr_2); #ifdef DEBUG_48BIT_WALK assert(phys_addr == phys_addr_2); diff --git a/nyx/memory_access.h b/nyx/memory_access.h index d7bb09e4b4..9423611833 100644 --- a/nyx/memory_access.h +++ b/nyx/memory_access.h @@ -22,7 +22,6 @@ along with QEMU-PT. If not, see . #ifndef MEMORY_ACCESS_H #define MEMORY_ACCESS_H -#include "qemu/osdep.h" #include #include "qemu-common.h" #include "sysemu/kvm_int.h" diff --git a/nyx/nested_hypercalls.c b/nyx/nested_hypercalls.c index c07cd825fe..bad1c1c736 100644 --- a/nyx/nested_hypercalls.c +++ b/nyx/nested_hypercalls.c @@ -1,3 +1,4 @@ +#include "qemu/osdep.h" #include #include #include "kvm_nested.h" @@ -16,14 +17,11 @@ bool hypercalls_enabled = false; - bool create_snapshot = false; uint64_t htos_cr3 = 0; uint64_t htos_config = 0; -static bool init_state = true; - int nested_once = 0; bool nested_setup_snapshot_once = false; @@ -32,23 +30,13 @@ bool nested_setup_snapshot_once = false; void handle_hypercall_kafl_nested_config(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ /* magic */ -#ifdef DEBUG_NESTED_HYPERCALLS - printf("============> %s\n", __func__); -#endif + nyx_trace(); uint32_t size = 0; read_physical_memory(htos_config, (uint8_t*) &size, sizeof(uint32_t), cpu); - fprintf(stderr, "--> %x\n", size); + void* buffer = malloc(size); read_physical_memory(htos_config+sizeof(uint32_t), buffer, size, cpu); - /* - hexdump_kafl(buffer, size); - - FILE *f = fopen("/tmp/htos_configuration", "w"); - fwrite(buffer, size, 1, f); - fclose(f); - - */ print_configuration(stderr, buffer, size); FILE* f = fopen("/tmp/hypertrash_configration", "w"); @@ -56,34 +44,19 @@ void handle_hypercall_kafl_nested_config(struct kvm_run *run, CPUState *cpu, uin fclose(f); free(buffer); - /* - hexdump_virtual_memory() - _memory(0x38d31000, 0x2000, cpu); - */ } -#define ANSI_COLOR_YELLOW "\x1b[33m" -#define ANSI_COLOR_RESET "\x1b[0m" - void handle_hypercall_kafl_nested_hprintf(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - char hprintf_buffer[0x1000]; -#ifdef DEBUG_NESTED_HYPERCALLS - printf("============> %s\n", __func__); -#endif + nyx_trace(); + char hprintf_buffer[0x1000]; read_physical_memory((uint64_t)run->hypercall.args[0], (uint8_t*)hprintf_buffer, 0x1000, cpu); - //fprintf(stderr, ANSI_COLOR_YELLOW "%s" ANSI_COLOR_RESET, hprintf_buffer); - set_hprintf_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, hprintf_buffer, strnlen(hprintf_buffer, 0x1000)+1); synchronization_lock_hprintf(); - //hexdump_kafl(hprintf_buffer, 0x200); } void handle_hypercall_kafl_nested_prepare(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - //cpu->fast_reload_snapshot = (void*)fast_reload_new(); -#ifdef DEBUG_NESTED_HYPERCALLS - printf("============> %s\n", __func__); -#endif + nyx_trace(); kvm_arch_get_registers(cpu); if((uint64_t)run->hypercall.args[0]){ @@ -92,6 +65,7 @@ void handle_hypercall_kafl_nested_prepare(struct kvm_run *run, CPUState *cpu, ui else{ abort(); } + size_t buffer_size = (size_t)((uint64_t)run->hypercall.args[0] * sizeof(uint64_t)); uint64_t* buffer = malloc(buffer_size); memset(buffer, 0x0, buffer_size); @@ -119,12 +93,12 @@ void handle_hypercall_kafl_nested_prepare(struct kvm_run *run, CPUState *cpu, ui bool acquired = false; void handle_hypercall_kafl_nested_early_release(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ + nyx_trace(); + if(!hypercalls_enabled){ return; } -#ifdef DEBUG_NESTED_HYPERCALLS - printf("============> %s\n", __func__); -#endif + bool state = GET_GLOBAL_STATE()->in_reload_mode; if(!state){ GET_GLOBAL_STATE()->in_reload_mode = true; @@ -137,99 +111,15 @@ void handle_hypercall_kafl_nested_early_release(struct kvm_run *run, CPUState *c } void handle_hypercall_kafl_nested_release(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - hypercalls_enabled = true; - static int rcount = 0; -#ifdef DEBUG_NESTED_HYPERCALLS - printf("============> %s\n", __func__); -#endif - - if((rcount%100) == 0){ - - kvm_arch_get_registers(cpu); - //printf("TRY %s %lx %lx %lx (%d)\n", __func__, get_rip(cpu), get_nested_guest_rip(cpu), get_nested_host_rip(cpu), rcount); - - // sleep(rand()%4); - } - rcount++; - synchronization_disable_pt(cpu); - /* - //vm_stop(RUN_STATE_RESTORE_VM); - qemu_mutex_lock_iothread(); - //load_snapshot("kafl", NULL); - //vm_start(); - fast_reload_restore(get_fast_reload_snapshot()); - qemu_mutex_unlock_iothread(); -*/ - //kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data); - - // printf("DONE %s\n", __func__); - - /* - kvm_arch_get_registers(cpu); - fprintf(stderr, "RELOADING DUDE %d!\n", rcount); - qemu_mutex_lock_iothread(); - fast_reload_restore(get_fast_reload_snapshot()); - qemu_mutex_unlock_iothread(); - */ - //} - //sleep(1); - - - - return; - //assert(false); - nyx_debug_p(CORE_PREFIX, "%s %d", __func__, init_state); - //sleep(10); - - /* magic */ - - //X86CPU *x86_cpu = X86_CPU(cpu); - //CPUX86State *env = &x86_cpu->env; - - - if (init_state){ - printf("INIT STATE\n"); - init_state = false; - - //synchronization_disable_pt(cpu); - - nyx_debug_p(CORE_PREFIX, "Protocol - SEND: KAFL_PROTO_RELEASE"); - - } else { - - - - //if(reload_mode || reload_mode_temp){ - - //} - - //synchronization_disable_pt(cpu); - - - nyx_debug_p(CORE_PREFIX, "%s UNLOCKED", __func__); - - // printf("INTEL PT is disabled!\n"); - - } - - - qemu_mutex_lock_iothread(); - //fast_reload_restore(get_fast_reload_snapshot()); - qemu_mutex_unlock_iothread(); - - nyx_debug_p(CORE_PREFIX, "%s UNLOCKED 2", __func__); - - - //kvm_cpu_synchronize_state(cpu); - - acquired = false; - + nyx_trace(); + // TODO not implemented - see git history for scraps + nyx_error("Not implemented.\n"); + abort(); } static inline void set_page_dump_bp_nested(CPUState *cpu, uint64_t cr3, uint64_t addr){ -#ifdef DEBUG_NESTED_HYPERCALLS - printf("============> %s\n", __func__); -#endif + nyx_trace(); + kvm_remove_all_breakpoints(cpu); kvm_insert_breakpoint(cpu, addr, 1, 1); kvm_update_guest_debug(cpu, 0); @@ -239,15 +129,9 @@ static inline void set_page_dump_bp_nested(CPUState *cpu, uint64_t cr3, uint64_t } void handle_hypercall_kafl_nested_acquire(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ -#ifdef DEBUG_NESTED_HYPERCALLS - printf("============> %s\n", __func__); -#endif + nyx_trace(); + if (!acquired){ - printf("TRY %s\n", __func__); - - - printf("DONE %s\n", __func__); - acquired = true; //create_fast_snapshot(cpu, true); @@ -267,30 +151,15 @@ void handle_hypercall_kafl_nested_acquire(struct kvm_run *run, CPUState *cpu, ui kvm_arch_get_registers(cpu); - X86CPU *x86_cpu = X86_CPU(cpu); - CPUX86State *env = &x86_cpu->env; - - printf("IN FUZZING LOOP! %lx\n", env->eip); GET_GLOBAL_STATE()->in_fuzzing_mode = true; set_state_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, 3); - - /* - if(GET_GLOBAL_STATE()->protect_payload_buffer){ - for(int i = 0; i < GET_GLOBAL_STATE()->nested_payload_pages_num; i++){ - remap_payload_slot_protected(GET_GLOBAL_STATE()->nested_payload_pages[i], i, cpu); - } - } - */ - } synchronization_lock(); - - kvm_arch_get_registers(cpu); + kvm_arch_get_registers(cpu); uint64_t cr3 = get_nested_host_cr3(cpu) & 0xFFFFFFFFFFFFF000ULL; - //fprintf(stderr, "CR3 -> 0x%lx\n", cr3); pt_set_cr3(cpu, cr3, false); GET_GLOBAL_STATE()->parent_cr3 = cr3; diff --git a/nyx/nested_hypercalls.h b/nyx/nested_hypercalls.h index e8e01d7fea..e3104f7f2f 100644 --- a/nyx/nested_hypercalls.h +++ b/nyx/nested_hypercalls.h @@ -1,5 +1,7 @@ #pragma once +#include + /* HyperTrash! */ void handle_hypercall_kafl_nested_hprintf(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg); void handle_hypercall_kafl_nested_prepare(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg); diff --git a/nyx/page_cache.c b/nyx/page_cache.c index 9a19d55406..5e97e9d551 100644 --- a/nyx/page_cache.c +++ b/nyx/page_cache.c @@ -1,6 +1,4 @@ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif +#include "qemu/osdep.h" #include #include #include @@ -10,26 +8,19 @@ #include #include #include -#include "page_cache.h" -#include "debug.h" -#ifndef STANDALONE_DECODER -#include "cpu.h" -#include "memory_access.h" -#include "fast_vm_reload.h" -#include "kvm_nested.h" +#include "nyx/page_cache.h" +#include "nyx/debug.h" +#include "nyx/fast_vm_reload.h" +#include "nyx/memory_access.h" +#include "nyx/helpers.h" #include "nyx/state/state.h" -#endif #define PAGE_CACHE_ADDR_LINE_SIZE sizeof(uint64_t) #define UNMAPPED_PAGE 0xFFFFFFFFFFFFFFFFULL -#ifndef STANDALONE_DECODER static bool reload_addresses(page_cache_t* self){ -#else -bool reload_addresses(page_cache_t* self){ -#endif khiter_t k; int ret; uint64_t addr, offset; @@ -38,8 +29,7 @@ bool reload_addresses(page_cache_t* self){ size_t self_offset = lseek(self->fd_address_file, 0, SEEK_END); if(self_offset != self->num_pages*PAGE_CACHE_ADDR_LINE_SIZE){ - //fprintf(stderr, "Reloading files ...\n"); - + /* reload page cache from disk */ lseek(self->fd_address_file, self->num_pages*PAGE_CACHE_ADDR_LINE_SIZE, SEEK_SET); offset = self->num_pages; while(read(self->fd_address_file, &value, PAGE_CACHE_ADDR_LINE_SIZE)){ @@ -51,30 +41,20 @@ bool reload_addresses(page_cache_t* self){ if(k == kh_end(self->lookup)){ if(value & 0xFFF){ - fprintf(stderr, "Load page: %lx (UMAPPED)\n", addr); - //k = kh_put(PC_CACHE, self->lookup, addr, &ret); - //kh_value(self->lookup, k) = UNMAPPED_PAGE; + fprintf(stderr, "Load page: %lx (UNMAPPED)\n", addr); } else{ - //fprintf(stderr, "Load page: %lx\n", addr); k = kh_put(PC_CACHE, self->lookup, addr, &ret); kh_value(self->lookup, k) = (offset-1)*PAGE_SIZE; } - - /* - k = kh_put(PC_CACHE, self->lookup, addr, &ret); - kh_value(self->lookup, k) = (offset-1)*PAGE_SIZE; - */ } else{ + /* likely a bug / race condition in page_cache itself! */ fprintf(stderr, "----------> Page duplicate found ...skipping! %lx\n", addr); - /* should not be possible ... */ //abort(); } } - //fprintf(stderr, "Old Value: %d - New Value: %ld\n", self->num_pages, (uint32_t)self_offset/PAGE_CACHE_ADDR_LINE_SIZE); - /* reload page dump file */ munmap(self->page_data, self->num_pages*PAGE_SIZE); self->num_pages = self_offset/PAGE_CACHE_ADDR_LINE_SIZE; @@ -86,7 +66,6 @@ bool reload_addresses(page_cache_t* self){ return false; } -#ifndef STANDALONE_DECODER static bool append_page(page_cache_t* self, uint64_t page, uint64_t cr3){ bool success = true; if(!self->num_pages){ @@ -99,87 +78,25 @@ static bool append_page(page_cache_t* self, uint64_t page, uint64_t cr3){ self->page_data = mmap(NULL, (self->num_pages+1)*PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, self->fd_page_file, 0); } - - //if(!dump_page_cr3_snapshot(page, self->page_data+(PAGE_SIZE*self->num_pages), self->cpu, GET_GLOBAL_STATE()->pt_c3_filter)){ - // if(!dump_page_cr3_snapshot(page, self->page_data+(PAGE_SIZE*self->num_pages), self->cpu, GET_GLOBAL_STATE()->parent_cr3)){ if(!dump_page_cr3_ht(page, self->page_data+(PAGE_SIZE*self->num_pages), self->cpu, GET_GLOBAL_STATE()->pt_c3_filter)){ 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); - //memset(self->page_data+(PAGE_SIZE*self->num_pages), 0xff, PAGE_SIZE); - munmap(self->page_data, (self->num_pages+1)*PAGE_SIZE); assert(!ftruncate(self->fd_page_file, (self->num_pages)*PAGE_SIZE)); self->page_data = mmap(NULL, (self->num_pages)*PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, self->fd_page_file, 0); - //qemu_backtrace(); success = false; return success; - //assert(false); } } } - //} - -/* - if(!dump_page_cr3_ht(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); - assert(false); - } -*/ - - /* - //fast_loadvm(); - if(cr3){ - dump_page_cr3_ht(page, self->page_data+(PAGE_SIZE*self->num_pages), self->cpu, GET_GLOBAL_STATE()->parent_cr3); //self->cpu->parent_cr3); - //assert(dump_page_cr3_snapshot(page, self->page_data+(PAGE_SIZE*self->num_pages), self->cpu, GET_GLOBAL_STATE()->parent_cr3)); //self->cpu->parent_cr3); - - //read_virtual_memory_cr3(page, self->page_data+(PAGE_SIZE*self->num_pages), PAGE_SIZE, self->cpu, self->cpu->parent_cr3); - } - else{ - dump_page_ht(page, self->page_data+(PAGE_SIZE*self->num_pages), self->cpu); - //read_virtual_memory(page, self->page_data+(PAGE_SIZE*self->num_pages), PAGE_SIZE, self->cpu); - } - */ fsync(self->fd_page_file); self->num_pages++; return success; } -#else -bool append_page(page_cache_t* self, uint64_t page, uint8_t* ptr){ - self->last_page = 0xFFFFFFFFFFFFFFFF; - self->last_addr = 0xFFFFFFFFFFFFFFFF; - page &= 0xFFFFFFFFFFFFF000ULL; - bool success = true; - if(!self->num_pages){ - assert(!ftruncate(self->fd_page_file, (self->num_pages+1)*PAGE_SIZE)); - self->page_data = mmap(NULL, (self->num_pages+1)*PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, self->fd_page_file, 0); - } - else{ - munmap(self->page_data, self->num_pages*PAGE_SIZE); - assert(!ftruncate(self->fd_page_file, (self->num_pages+1)*PAGE_SIZE)); - self->page_data = mmap(NULL, (self->num_pages+1)*PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, self->fd_page_file, 0); - } - - memcpy(self->page_data+(PAGE_SIZE*self->num_pages), ptr, PAGE_SIZE); - - fsync(self->fd_page_file); - - int ret; - khiter_t k; - k = kh_put(PC_CACHE, self->lookup, page, &ret); - kh_value(self->lookup, k) = self->num_pages*PAGE_SIZE; - assert(write(self->fd_address_file, &page, PAGE_CACHE_ADDR_LINE_SIZE) == PAGE_CACHE_ADDR_LINE_SIZE); - - self->num_pages++; - - return success; -} -#endif static void page_cache_lock(page_cache_t* self){ -#ifndef STANDALONE_DECODER int ret = 0; while (true){ ret = flock(self->fd_lock, LOCK_EX); @@ -194,11 +111,9 @@ static void page_cache_lock(page_cache_t* self){ assert(false); } } -#endif } static void page_cache_unlock(page_cache_t* self){ -#ifndef STANDALONE_DECODER int ret = 0; while (true){ ret = flock(self->fd_lock, LOCK_UN); @@ -213,35 +128,24 @@ static void page_cache_unlock(page_cache_t* self){ assert(false); } } -#endif } static bool update_page_cache(page_cache_t* self, uint64_t page, khiter_t* k){ - - //#define DEBUG_PAGE_CACHE_LOCK - page_cache_lock(self); -#ifdef DEBUG_PAGE_CACHE_LOCK - fprintf(stderr, "%d: LOCKING PAGE CACHE\n", getpid()); -#endif if(reload_addresses(self)){ *k = kh_get(PC_CACHE, self->lookup, page); } - if(*k == kh_end(self->lookup)){ -#ifndef STANDALONE_DECODER int ret; - uint64_t cr3 = GET_GLOBAL_STATE()->parent_cr3; //self->cpu->parent_cr3; - if(!is_addr_mapped_cr3_snapshot(page, self->cpu, GET_GLOBAL_STATE()->parent_cr3) && !is_addr_mapped_cr3_snapshot(page, self->cpu, GET_GLOBAL_STATE()->pt_c3_filter)){ //self->cpu->parent_cr3)){ - //fprintf(stderr, "PAGE NOT FOUND in SNAPSHOT %lx\n", page); - //assert(false); + uint64_t cr3 = GET_GLOBAL_STATE()->parent_cr3; + if(!is_addr_mapped_cr3_snapshot(page, self->cpu, GET_GLOBAL_STATE()->parent_cr3) && !is_addr_mapped_cr3_snapshot(page, self->cpu, GET_GLOBAL_STATE()->pt_c3_filter)){ + /* TODO! */ } *k = kh_get(PC_CACHE, self->lookup, page); - if(*k == kh_end(self->lookup) && reload_addresses(self)){ /* reload sucessful */ *k = kh_get(PC_CACHE, self->lookup, page); @@ -255,31 +159,13 @@ 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"); page_cache_unlock(self); return false; - /* - uint64_t new_page = page | 0xFFF; - assert(write(self->fd_address_file, &new_page, PAGE_CACHE_ADDR_LINE_SIZE) == PAGE_CACHE_ADDR_LINE_SIZE); - kh_value(self->lookup, *k) = UNMAPPED_PAGE; - fprintf(stderr, "APPEND UNMAPPED PAGE %lx!\n", page); - */ } *k = kh_get(PC_CACHE, self->lookup, page); } -#else - //printf("PAGE NOT FOUND: %lx! ABORTING\n", page); - page_cache_unlock(self); - return false; - abort(); -#endif } - -#ifdef DEBUG_PAGE_CACHE_LOCK - fprintf(stderr, "%d: UNLOCKING PAGE CACHE\n", getpid()); -#endif - page_cache_unlock(self); return true; } @@ -287,40 +173,21 @@ static bool update_page_cache(page_cache_t* self, uint64_t page, khiter_t* k){ uint64_t page_cache_fetch(page_cache_t* self, uint64_t page, bool* success, bool test_mode){ page &= 0xFFFFFFFFFFFFF000ULL; - /* - if(test_mode){ - *success = false; - return 0; - } - */ - - //if(page == 0x7ffca45b5000) - // return UNMAPPED_PAGE; - //printf("%s %lx\n", __func__, page); - - //if (page == 0x0434000) - // return 0; - if (self->last_page == page){ *success = true; return self->last_addr; } - - //nyx_debug_p(PAGE_CACHE_PREFIX, "page_cache_fetch %lx", page); khiter_t k; k = kh_get(PC_CACHE, self->lookup, page); if(k == kh_end(self->lookup)){ if(test_mode || update_page_cache(self, page, &k) == false){ - //fprintf(stderr, "%s: fail!\n", __func__); *success = false; - //abort(); return 0; } } self->last_page = page; - //fprintf(stderr, "[%d]\tkh_n_buckets: %d %d\n", getpid(), kh_n_buckets(self->lookup), k); if(kh_value(self->lookup, k) == UNMAPPED_PAGE){ self->last_addr = UNMAPPED_PAGE; @@ -329,25 +196,16 @@ uint64_t page_cache_fetch(page_cache_t* self, uint64_t page, bool* success, bool self->last_addr = (uint64_t)self->page_data+kh_value(self->lookup, k); } - - - //fprintf(stderr, "try to unlock flock!\n"); - //fprintf(stderr, "flock unlocked!\n"); - *success = true; return self->last_addr; } -/* fix this */ +/* FIXME */ uint64_t page_cache_fetch2(page_cache_t* self, uint64_t page, bool* success){ return page_cache_fetch(self, page, success, false); } -#ifndef STANDALONE_DECODER page_cache_t* page_cache_new(CPUState *cpu, const char* cache_file){ -#else -page_cache_t* page_cache_new(const char* cache_file, uint8_t disassembler_word_width){ -#endif page_cache_t* self = malloc(sizeof(page_cache_t)); char* tmp1; @@ -357,21 +215,13 @@ page_cache_t* page_cache_new(const char* cache_file, uint8_t disassembler_word_w assert(asprintf(&tmp2, "%s.addr", cache_file) != -1); assert(asprintf(&tmp3, "%s.lock", cache_file) != -1); - self->lookup = kh_init(PC_CACHE); self->fd_page_file = open(tmp1, O_CLOEXEC | O_RDWR, S_IRWXU); self->fd_address_file = open(tmp2, O_CLOEXEC | O_RDWR, S_IRWXU); -#ifndef STANDALONE_DECODER self->cpu = cpu; self->fd_lock = open(tmp3, O_CLOEXEC); assert(self->fd_lock > 0); -#else - if(self->fd_page_file == -1 || self->fd_address_file == -1){ - printf("[ ] Page cache files not found...\n"); - exit(1); - } -#endif memset(self->disassemble_cache, 0x0, 16); @@ -381,11 +231,7 @@ page_cache_t* page_cache_new(const char* cache_file, uint8_t disassembler_word_w self->last_page = 0xFFFFFFFFFFFFFFFF; self->last_addr = 0xFFFFFFFFFFFFFFFF; -#ifndef STANDALONE_DECODER nyx_debug_p(PAGE_CACHE_PREFIX, "%s (%s - %s)", __func__, tmp1, tmp2); -#else - nyx_debug_p(PAGE_CACHE_PREFIX, "%s (%s - %s) WORD_WIDTH: %d", __func__, tmp1, tmp2, disassembler_word_width); -#endif free(tmp3); free(tmp2); @@ -407,35 +253,6 @@ page_cache_t* page_cache_new(const char* cache_file, uint8_t disassembler_word_w return self; } -#ifdef STANDALONE_DECODER -void page_cache_destroy(page_cache_t* self){ - munmap(self->page_data, self->num_pages * 0x1000); - kh_destroy(PC_CACHE, self->lookup); - - cs_close(&self->handle_16); - cs_close(&self->handle_32); - cs_close(&self->handle_64); - free(self); -} -#endif - - -/* -static bool page_cache_load(uint64_t virtual_addr){ - - - return true; -} -*/ - -/* - -static bool page_cache_load_cr3(uint64_t virtual_addr, uint64_t cr3){ - return true; -} - -*/ - bool page_cache_disassemble(page_cache_t* self, uint64_t address, cs_insn **insn){ return true; } @@ -454,26 +271,16 @@ cs_insn* page_cache_cs_malloc(page_cache_t* self, disassembler_mode_t mode){ return NULL; } -//#define EXPERIMENTAL_PAGE_FETCH - bool page_cache_disassemble_iter(page_cache_t* self, uint64_t* address, cs_insn *insn, uint64_t* failed_page, disassembler_mode_t mode){ - - //printf("%s %lx\n", __func__, *address); - *failed_page = 0xFFFFFFFFFFFFFFFFULL; bool success = true; size_t code_size = 16; -#if defined(STANDALONE_DECODER) || !defined(EXPERIMENTAL_PAGE_FETCH) uint8_t* code = (uint8_t*)page_cache_fetch(self, *address, &success, false); -#else - uint8_t* code = (uint8_t*)page_cache_fetch(self, *address, &success, true); -#endif uint8_t* code_ptr = 0; - //disassembler_mode_t mode = mode_16; csh* current_handle = NULL; switch(mode){ @@ -491,54 +298,30 @@ bool page_cache_disassemble_iter(page_cache_t* self, uint64_t* address, cs_insn } if (code == (void*)UNMAPPED_PAGE || success == false){ - *failed_page = *address;// & 0xFFFFFFFFFFFFF000ULL; - //printf("FAIL???? (0x%lx) %lx %d\n", *address, code, success); + *failed_page = *address; return false; } if ((*address & 0xFFF) >= (0x1000-16)){ - //printf("-------------> Disassemble between pages...%lx (%lx %lx %lx)\n", *address, (*address&0xFFF), (0x1000-16), 0xf-(0xfff-(*address&0xfff))); memcpy((void*)self->disassemble_cache, (void*)((uint64_t)code+(0x1000-16)), 16); code_ptr = self->disassemble_cache + 0xf-(0xfff-(*address&0xfff)); - -#if defined(STANDALONE_DECODER) || !defined(EXPERIMENTAL_PAGE_FETCH) code = (uint8_t*)page_cache_fetch(self, *address+0x1000, &success, false); -#else - code = (uint8_t*)page_cache_fetch(self, *address+0x1000, &success, true); -#endif - /* broken AF */ if(success == true){ - //printf("=> A\n"); - //*failed_page = (*address+0x1000) & 0xFFFFFFFFFFFFF000ULL; - //return false; - //printf("=> %lx %lx\n", (0xfff-(*address&0xfff)), *address); memcpy((void*)(self->disassemble_cache+16), (void*)code, 16); - //code_size = 16; return cs_disasm_iter(*current_handle, (const uint8_t**) &code_ptr, &code_size, address, insn); } else{ - //printf("=> B\n"); code_size = (0xfff-(*address&0xfff)); - //printf("%lx\n", code_size); - //abort(); - //*failed_page = *address; if(!cs_disasm_iter(*current_handle, (const uint8_t**) &code_ptr, &code_size, address, insn)){ *failed_page = (*address+0x1000) & 0xFFFFFFFFFFFFF000ULL; - //fprintf(stderr, "%s FAIL: %lx %lx\n", __func__, *address, *failed_page); - //if(*address != 0x555555554ffe && *address != 0x7ffff7478ffc && *address != 0x7ffff7820ff6 && *address != 0x7ffff7822ffa) - // abort(); return false; } return true; - //return cs_disasm_iter(self->handle, (const uint8_t**) &code_ptr, &code_size, address, insn); } } else { - //printf("=> C\n"); code_ptr = code + (*address&0xFFF); - - //printf("Disassemble...(%lx %x)\n", code_ptr, *code_ptr); return cs_disasm_iter(*current_handle, (const uint8_t**) &code_ptr, &code_size, address, insn); } } diff --git a/nyx/page_cache.h b/nyx/page_cache.h index 861522ee74..2434266f4b 100644 --- a/nyx/page_cache.h +++ b/nyx/page_cache.h @@ -2,18 +2,16 @@ #include #include -#ifndef STANDALONE_DECODER -#include "qemu/osdep.h" -#endif #include "khash.h" #include +#include "qemu-common.h" +#include "khash.h" + KHASH_MAP_INIT_INT64(PC_CACHE, uint64_t) typedef struct page_cache_s{ -#ifndef STANDALONE_DECODER CPUState *cpu; -#endif khash_t(PC_CACHE) *lookup; int fd_page_file; int fd_address_file; @@ -30,14 +28,7 @@ typedef struct page_cache_s{ uint64_t last_addr; } page_cache_t; -#ifndef STANDALONE_DECODER page_cache_t* page_cache_new(CPUState *cpu, const char* cache_file); -#else -page_cache_t* page_cache_new(const char* cache_file, uint8_t disassembler_word_width); -void page_cache_destroy(page_cache_t* self); -bool append_page(page_cache_t* self, uint64_t page, uint8_t* ptr); -#endif - uint64_t page_cache_fetch(page_cache_t* self, uint64_t page, bool* success, bool test_mode); bool page_cache_disassemble(page_cache_t* self, uint64_t address, cs_insn **insn); @@ -45,5 +36,4 @@ bool page_cache_disassemble_iter(page_cache_t* self, uint64_t* address, cs_insn cs_insn* page_cache_cs_malloc(page_cache_t* self, disassembler_mode_t mode); - uint64_t page_cache_fetch2(page_cache_t* self, uint64_t page, bool* success); \ No newline at end of file diff --git a/nyx/patcher.c b/nyx/patcher.c index b1c070364f..c7a44a30c1 100644 --- a/nyx/patcher.c +++ b/nyx/patcher.c @@ -7,10 +7,9 @@ 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]; -/////////////////////////////////////////////////////////////////////////////////// -// Private Helper Functions Declarations -/////////////////////////////////////////////////////////////////////////////////// -// +/* + * Private Helper Functions Declarations + */ static void _patcher_apply_patch(patcher_t *self, size_t index); static void _patcher_restore_patch(patcher_t *self, size_t index); @@ -26,9 +25,9 @@ static void _patcher_free_patch_infos(patcher_t *self); static redqueen_t* _redq_ptr(patcher_t *self); -/////////////////////////////////////////////////////////////////////////////////// -// Public Functions -/////////////////////////////////////////////////////////////////////////////////// +/* + * Public Functions + */ patcher_t* patcher_new(CPUState *cpu){ patcher_t *res = malloc(sizeof(patcher_t)); @@ -118,10 +117,9 @@ bool patcher_validate_patches(patcher_t *self){ } -/////////////////////////////////////////////////////////////////////////////////// -// Private Helper Functions Definitions -/////////////////////////////////////////////////////////////////////////////////// - +/* + * Private Helper Functions Definitions + */ static void _patcher_apply_patch(patcher_t *self, size_t index) { abort(); // deprecated function -> remove this code later diff --git a/nyx/patcher.h b/nyx/patcher.h index 5fc6c24207..997d29d135 100644 --- a/nyx/patcher.h +++ b/nyx/patcher.h @@ -10,8 +10,11 @@ #include "qemu/osdep.h" #define MAX_INSTRUCTION_SIZE 64 -//Patch used to replace cmp instructions. It encodes CMP AL, AL a comparision which always evaluates to true. This can -//be used to remove hash checks that we suspsect can later on be patched. +/* + * Patch used to replace cmp instructions. It encodes CMP AL, AL a comparison + * which always evaluates to true. This can be used to remove hash checks that + * we suspsect can later on be patched. + */ extern const uint8_t* cmp_patch; typedef struct patch_info_s{ diff --git a/nyx/pt.c b/nyx/pt.c index 0655aecde8..1e66510112 100644 --- a/nyx/pt.c +++ b/nyx/pt.c @@ -20,32 +20,36 @@ along with QEMU-PT. If not, see . */ #include "qemu/osdep.h" + +#include #include #include #include + +#include "exec/memory.h" +#include "sysemu/cpus.h" +#include "sysemu/kvm.h" +#include "sysemu/kvm_int.h" #include "qemu-common.h" #include "target/i386/cpu.h" -#include "nyx/pt.h" -#include "exec/memory.h" -#include "sysemu/kvm_int.h" -#include "sysemu/kvm.h" -#include "sysemu/cpus.h" -#include "nyx/hypercall/hypercall.h" -#include "nyx/memory_access.h" -#include "nyx/interface.h" + #include "nyx/debug.h" #include "nyx/file_helper.h" +#include "nyx/helpers.h" +#include "nyx/hypercall/hypercall.h" +#include "nyx/interface.h" +#include "nyx/memory_access.h" +#include "nyx/page_cache.h" +#include "nyx/pt.h" +#include "nyx/redqueen_trace.h" +#include "nyx/state/state.h" +#include "nyx/trace_dump.h" + #ifdef CONFIG_REDQUEEN +#include "nyx/patcher.h" #include "nyx/redqueen.h" #include "nyx/redqueen_patch.h" -#include "nyx/patcher.h" #endif -#include "nyx/page_cache.h" -#include "nyx/state/state.h" -#include -#include "nyx/helpers.h" -#include "nyx/trace_dump.h" -#include "nyx/redqueen_trace.h" #define PT_BUFFER_MMAP_ADDR 0x3ffff0000000 @@ -83,39 +87,10 @@ static inline int pt_ioctl(int fd, unsigned long request, unsigned long arg){ return ioctl(fd, request, arg); } -#ifdef DUMP_AND_DEBUG_PT -void dump_pt_trace(void* buffer, int bytes){ - static FILE* f = NULL; - static int fcounter = 0; - static size_t size = 0; - char filename[256]; - - - - if(!f){ - snprintf(filename, 256, "/tmp/trace_data/data_%d", fcounter); - f = fopen(filename, "wb"); - } - - size += fwrite(buffer, bytes , 1, f) * bytes; - - if(size >= 0x80000000){ // 2GB - fclose(f); - fcounter++; - size = 0; - snprintf(filename, 256, "/tmp/trace_data/data_%d", fcounter); - f = fopen(filename, "wb"); - } -} -#endif - void pt_dump(CPUState *cpu, int bytes){ - //pt_write_pt_dump_file(cpu->pt_mmap, bytes); - if(!(GET_GLOBAL_STATE()->redqueen_state && GET_GLOBAL_STATE()->redqueen_state->intercept_mode)){ if (GET_GLOBAL_STATE()->in_fuzzing_mode && GET_GLOBAL_STATE()->decoder_page_fault == false && GET_GLOBAL_STATE()->decoder && !GET_GLOBAL_STATE()->dump_page){ GET_GLOBAL_STATE()->pt_trace_size += bytes; - //dump_pt_trace(cpu->pt_mmap, bytes); pt_write_pt_dump_file(cpu->pt_mmap, bytes); decoder_result_t result = libxdc_decode(GET_GLOBAL_STATE()->decoder, cpu->pt_mmap, bytes); switch(result){ @@ -154,17 +129,16 @@ int pt_enable(CPUState *cpu, bool hmp_mode){ } int pt_disable(CPUState *cpu, bool hmp_mode){ - //printf("%s\n", __func__); int r = pt_cmd(cpu, KVM_VMX_PT_DISABLE, hmp_mode); return r; } int pt_set_cr3(CPUState *cpu, uint64_t val, bool hmp_mode){ + int r = 0; + if (val == GET_GLOBAL_STATE()->pt_c3_filter){ return 0; // nothing changed } - //fprintf(stderr, "=========== %s %lx ============\n", __func__, val); - int r = 0; if (cpu->pt_enabled){ return -EINVAL; @@ -215,7 +189,7 @@ int pt_enable_ip_filtering(CPUState *cpu, uint8_t addrn, bool redqueen, bool hmp void pt_init_decoder(CPUState *cpu){ uint64_t filters[4][2] = {0}; - /* it's time to clean up this code -.- */ + /* TODO time to clean up this code -.- */ filters[0][0] = GET_GLOBAL_STATE()->pt_ip_filter_a[0]; filters[0][1] = GET_GLOBAL_STATE()->pt_ip_filter_b[0]; filters[1][0] = GET_GLOBAL_STATE()->pt_ip_filter_a[1]; @@ -261,10 +235,6 @@ void pt_kvm_init(CPUState *cpu){ cpu->pt_fd = 0; cpu->pt_decoder_state = NULL; - //cpu->redqueen_state=NULL; - //cpu->redqueen_patch_state = patcher_new(cpu); - - //init_redqueen_patch_state(); cpu->reload_pending = false; cpu->intel_pt_run_trashed = false; @@ -295,27 +265,22 @@ void pt_pre_kvm_run(CPUState *cpu){ } - //if(cpu->redqueen_enable_pending){ if(GET_GLOBAL_STATE()->redqueen_enable_pending){ //nyx_debug_p(REDQUEEN_PREFIX, "rq enable"); if (GET_GLOBAL_STATE()->redqueen_state){ enable_rq_intercept_mode(GET_GLOBAL_STATE()->redqueen_state); } - //cpu->redqueen_enable_pending = false; GET_GLOBAL_STATE()->redqueen_enable_pending = false; - //qemu_cpu_kick_self(); } - //if(cpu->redqueen_disable_pending){ if(GET_GLOBAL_STATE()->redqueen_disable_pending){ //nyx_debug_p(REDQUEEN_PREFIX, "rq disable"); if (GET_GLOBAL_STATE()->redqueen_state){ disable_rq_intercept_mode(GET_GLOBAL_STATE()->redqueen_state); } - //cpu->redqueen_disable_pending = false; GET_GLOBAL_STATE()->redqueen_disable_pending = false; - //qemu_cpu_kick_self(); } + if(GET_GLOBAL_STATE()->pt_trace_mode || GET_GLOBAL_STATE()->pt_trace_mode_force){ if (!cpu->pt_fd) { cpu->pt_fd = kvm_vcpu_ioctl(cpu, KVM_VMX_PT_SETUP_FD, (unsigned long)0); @@ -324,9 +289,12 @@ void pt_pre_kvm_run(CPUState *cpu){ cpu->pt_mmap = mmap((void*)PT_BUFFER_MMAP_ADDR, ret, PROT_READ|PROT_WRITE, MAP_SHARED, cpu->pt_fd, 0); assert(cpu->pt_mmap != (void*)0xFFFFFFFFFFFFFFFF); - assert(mmap(cpu->pt_mmap+ret, 0x1000, PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, -1, 0) == (void*)(cpu->pt_mmap+ret)); //;!= (void*)0xFFFFFFFFFFFFFFFF); // add an extra page to have enough space for an additional PT_TRACE_END byte - - nyx_debug("\t\t============> pt_mmap:%p - %p\n", cpu->pt_mmap, cpu->pt_mmap+ret); + // add an extra page to have enough space for an additional PT_TRACE_END byte + assert(mmap(cpu->pt_mmap + ret, 0x1000, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, -1, + 0) == (void *)(cpu->pt_mmap + ret)); + + nyx_debug("=> pt_mmap: %p - %p\n", cpu->pt_mmap, cpu->pt_mmap + ret); memset(cpu->pt_mmap+ret, 0x55, 0x1000); } @@ -334,8 +302,6 @@ void pt_pre_kvm_run(CPUState *cpu){ if (cpu->pt_cmd){ switch(cpu->pt_cmd){ case KVM_VMX_PT_ENABLE: - //fprintf(stderr, "=========== KVM_VMX_PT_ENABLE ============\n"); - if (cpu->pt_fd){ /* dump for the very last time before enabling VMX_PT ... just in case */ ioctl(cpu->pt_fd, KVM_VMX_PT_CHECK_TOPA_OVERFLOW, (unsigned long)0); @@ -346,8 +312,6 @@ void pt_pre_kvm_run(CPUState *cpu){ } break; case KVM_VMX_PT_DISABLE: - //fprintf(stderr, "=========== KVM_VMX_PT_DISABLE ============\n"); - if (cpu->pt_fd){ ret = ioctl(cpu->pt_fd, cpu->pt_cmd, 0); if (ret > 0){ @@ -374,13 +338,9 @@ void pt_pre_kvm_run(CPUState *cpu){ ret = pt_ioctl(cpu->pt_fd, cpu->pt_cmd, (unsigned long)0); break; case KVM_VMX_PT_CONFIGURE_CR3: - //fprintf(stderr, "=========== KVM_VMX_PT_CONFIGURE_CR3 ============\n"); - ret = pt_ioctl(cpu->pt_fd, cpu->pt_cmd, GET_GLOBAL_STATE()->pt_c3_filter); break; case KVM_VMX_PT_ENABLE_CR3: - //fprintf(stderr, "=========== KVM_VMX_PT_ENABLE_CR3 ============\n"); - ret = pt_ioctl(cpu->pt_fd, cpu->pt_cmd, (unsigned long)0); break; default: @@ -391,7 +351,6 @@ void pt_pre_kvm_run(CPUState *cpu){ } cpu->pt_cmd = 0; cpu->pt_ret = 0; - //kvm_cpu_synchronize_state(cpu); } } pthread_mutex_unlock(&pt_dump_mutex); @@ -401,26 +360,13 @@ void pt_handle_overflow(CPUState *cpu){ pthread_mutex_lock(&pt_dump_mutex); int overflow = ioctl(cpu->pt_fd, KVM_VMX_PT_CHECK_TOPA_OVERFLOW, (unsigned long)0); if (overflow > 0){ - //cpu->overflow_counter++; pt_dump(cpu, overflow); } - - /*else{ - printf("CPU NOT ENABLED?!\n"); - assert(false); - } - */ pthread_mutex_unlock(&pt_dump_mutex); } void pt_post_kvm_run(CPUState *cpu){ if(GET_GLOBAL_STATE()->pt_trace_mode || GET_GLOBAL_STATE()->pt_trace_mode_force){ - - //printf("%s\n", __func__); - //int overflow; - //if (cpu->pt_enabled){ pt_handle_overflow(cpu); - //unlock_reload_pending(cpu); - //} } } diff --git a/nyx/redqueen.c b/nyx/redqueen.c index 9592717ff3..7224049a89 100644 --- a/nyx/redqueen.c +++ b/nyx/redqueen.c @@ -19,18 +19,21 @@ along with QEMU-PT. If not, see . */ +#include "qemu/osdep.h" + #include -#include "nyx/redqueen.h" -#include "nyx/memory_access.h" -#include "nyx/interface.h" -#include -#include "file_helper.h" -#include "patcher.h" -#include "debug.h" -#include "redqueen_trace.h" -#include "nyx/state/state.h" #include #include +#include + +#include "nyx/redqueen.h" +#include "debug.h" +#include "file_helper.h" +#include "nyx/interface.h" +#include "nyx/memory_access.h" +#include "nyx/state/state.h" +#include "patcher.h" +#include "redqueen_trace.h" redqueen_workdir_t redqueen_workdir = {0}; @@ -61,11 +64,6 @@ redqueen_t* new_rq_state(CPUState *cpu, page_cache_t* page_cache){ res->trace_state=redqueen_trace_new(); - //FILE* pt_file = fopen("/tmp/redqueen_vm.img", "wb"); - //delete_redqueen_files(); - //fwrite(&start_range, sizeof(uint64_t), 1, pt_file); - //fwrite(code, sizeof(uint8_t), end_range-start_range, pt_file); - //fclose(pt_file); return res; } @@ -232,7 +230,7 @@ void destroy_rq_state(redqueen_t* self){ static void redqueen_set_addr_flags(redqueen_t* self, uint64_t addr, uint32_t flags){ int unused = 0; - //fprintf(stderr, "%s\n", __func__); + khiter_t k = kh_get(RQ, self->lookup, addr); if(k == kh_end(self->lookup)){ k = kh_put(RQ, self->lookup, addr, &unused); @@ -276,17 +274,8 @@ static uint32_t redqueen_update_addr_count(redqueen_t* self, uint64_t addr){ return value & 0xFF000000UL; } -/* -static void set_rq_trace_enabled_bp(redqueen_t* self, uint64_t addr){ - redqueen_set_addr_flags(self, addr, CMP_BITMAP_TRACE_ENABLED); -} -*/ - void set_rq_instruction(redqueen_t* self, uint64_t addr){ - //fprintf(stderr, "%s\n", __func__); if( !redqueen_check_addr_flags(self, addr, CMP_BITMAP_BLACKLISTED)){ - //fprintf(stderr, "%s +2\n", __func__); - redqueen_set_addr_flags(self, addr, CMP_BITMAP_RQ_INSTRUCTION); } } @@ -296,7 +285,6 @@ void set_rq_blacklist(redqueen_t* self, uint64_t addr){ } static void insert_hooks_whitelist(redqueen_t* self){ - fprintf(stderr, "%s\n", __func__); for(size_t i = 0; i < self->num_breakpoint_whitelist; i++){ insert_breakpoint(self->cpu, self->breakpoint_whitelist[i], 1); } @@ -304,17 +292,13 @@ static void insert_hooks_whitelist(redqueen_t* self){ static void insert_hooks_bitmap(redqueen_t* self){ uint64_t c = 0; - //fprintf(stderr, "%s\n", __func__); - uint64_t addr; uint32_t value __attribute__((unused)); uint32_t mode = GET_GLOBAL_STATE()->redqueen_instrumentation_mode; - //uint32_t mode = self->cpu->redqueen_instrumentation_mode; + kh_foreach(self->lookup, addr, value, { - //fprintf(stderr, "%s %lx %x\n", __func__, addr, value); if(redqueen_check_addr_flags(self, addr, CMP_BITMAP_BLACKLISTED)){ continue; } - //bool should_hook_se = (mode == REDQUEEN_SE_INSTRUMENTATION) && redqueen_check_addr_flags(self, addr, CMP_BITMAP_SHOULD_HOOK_SE); bool should_hook_rq = (mode == REDQUEEN_LIGHT_INSTRUMENTATION ) && redqueen_check_addr_flags(self, addr, CMP_BITMAP_SHOULD_HOOK_RQ); if( should_hook_rq ){ @@ -325,11 +309,9 @@ static void insert_hooks_bitmap(redqueen_t* self){ } void redqueen_insert_hooks(redqueen_t* self){ - // fprintf(stderr, "%s %x\n", __func__, self->cpu->redqueen_instrumentation_mode); nyx_debug_p(REDQUEEN_PREFIX, "insert hooks"); assert(!self->hooks_applied); - //switch(self->cpu->redqueen_instrumentation_mode){ switch(GET_GLOBAL_STATE()->redqueen_instrumentation_mode){ case(REDQUEEN_LIGHT_INSTRUMENTATION): insert_hooks_bitmap(self); @@ -347,7 +329,6 @@ void redqueen_insert_hooks(redqueen_t* self){ void redqueen_remove_hooks(redqueen_t* self){ nyx_debug_p(REDQUEEN_PREFIX, "remove hooks"); - // fprintf(stderr, "remove hooks\n"); assert(self->hooks_applied); remove_all_breakpoints(self->cpu); @@ -361,6 +342,7 @@ void redqueen_remove_hooks(redqueen_t* self){ static uint64_t get_segment_register(x86_reg reg) { X86CPU *cpu = X86_CPU(qemu_get_cpu(0)); CPUX86State *env = &cpu->env; + switch(reg){ case X86_REG_GS: return env->segs[R_GS].base; case X86_REG_FS: return env->segs[R_FS].base; @@ -524,6 +506,7 @@ static void print_comp_result(uint64_t addr, const char* type, uint64_t val1, ui char result_buf[256]; const char *format = NULL; + uint8_t pos = 0; pos += snprintf(result_buf+pos, 256-pos, "%lx\t\t %s", addr, type); //nyx_debug_p(REDQUEEN_PREFIX, "got size: %ld", size); @@ -650,7 +633,7 @@ static uint64_t read_stack(uint64_t word_index){ rsp = limit_to_word_width(rsp); uint64_t res = 0; uint64_t stack_ptr = rsp + word_index * word_width_to_bytes(); - /* todo @ sergej */ + /* TODO @ sergej */ assert(read_virtual_memory(stack_ptr, (uint8_t*)(&res), 8, qemu_get_cpu(0))); return limit_to_word_width(res); } @@ -676,14 +659,14 @@ static void format_strcmp(uint8_t* buf1, uint8_t* buf2){ static bool test_strchr(uint64_t arg1, uint64_t arg2){ CPUState *cpu = qemu_get_cpu(0); - /* todo @ sergej */ + /* TODO @ sergej */ if(!is_addr_mapped(arg1, cpu) || arg2 & (~0xff)){ return false; } uint8_t buf1[REDQUEEN_MAX_STRCMP_LEN]; uint8_t buf2[REDQUEEN_MAX_STRCMP_LEN]; - /* todo @ sergej */ + /* TODO @ sergej */ assert(read_virtual_memory(arg1, &buf1[0], REDQUEEN_MAX_STRCMP_LEN, cpu)); if(!memchr(buf1,'\0',REDQUEEN_MAX_STRCMP_LEN) ){return false;} memset(buf2,'\0',REDQUEEN_MAX_STRCMP_LEN); @@ -700,7 +683,7 @@ static bool test_strcmp(uint64_t arg1, uint64_t arg2){ //nyx_debug_p(REDQUEEN_PREFIX,"valid ptrs"); uint8_t buf1[REDQUEEN_MAX_STRCMP_LEN]; uint8_t buf2[REDQUEEN_MAX_STRCMP_LEN]; - /* todo @ sergej */ + /* TODO @ sergej */ assert(read_virtual_memory(arg1, &buf1[0], REDQUEEN_MAX_STRCMP_LEN, cpu)); assert(read_virtual_memory(arg2, &buf2[0], REDQUEEN_MAX_STRCMP_LEN, cpu)); format_strcmp(buf1,buf2); @@ -742,19 +725,6 @@ static void extract_call_params(void){ test_strcmp_sys_v(); } -/* -static bool is_memory_access(redqueen_t* self, cs_insn* insn){ - return insn->id != X86_INS_LEA && strstr(insn->op_str,"["); -} - -static bool is_trace_entry_point(redqueen_t* self, uint64_t addr){ - //if(addr >= self->address_range_start && addr <= self->address_range_end){ - return redqueen_check_addr_flags(self, addr, CMP_BITMAP_TRACE_ENABLED); - //} - return false; -} -*/ - static void handle_hook_redqueen_light(redqueen_t* self, uint64_t ip, cs_insn *insn){ if(insn->id == X86_INS_CMP || insn->id == X86_INS_XOR){ //handle original redqueen case get_cmp_value(insn, "CMP"); @@ -770,9 +740,6 @@ static void handle_hook_redqueen_light(redqueen_t* self, uint64_t ip, cs_insn *i } static uint8_t handle_hook_breakpoint(redqueen_t* self, bool write_data){ - //fprintf(stderr, "%s\n", __func__); - //printf("%s\n", __func__); - X86CPU *cpu = X86_CPU(self->cpu); CPUX86State *env = &cpu->env; @@ -821,112 +788,12 @@ static uint8_t handle_hook_breakpoint(redqueen_t* self, bool write_data){ return ins_size; } -/* -static void debug_print_disasm(char* desc, uint64_t ip, CPUState* cpu_state){ - //uint64_t cs_address = ip; - uint8_t code[64]; - csh handle; - cs_insn *insn; - read_virtual_memory(ip, &code[0], 64, cpu_state); - if (cs_open(CS_ARCH_X86, get_capstone_mode(cpu_state->disassembler_word_width), &handle) == CS_ERR_OK){ - cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); - size_t count = cs_disasm(handle, &code[0], 64, ip, 1, &insn); - if(count > 0){ - nyx_debug_p(REDQUEEN_PREFIX,"%s\t %lx: %s %s",desc, ip, insn->mnemonic, insn->op_str); - } else { - nyx_debug_p(REDQUEEN_PREFIX,"%s\t Failed to disassemble at: %lx",desc, ip); - } - cs_close(&handle); - cs_free(insn, count); - } else { - nyx_debug_p(REDQUEEN_PREFIX,"%s\t Failed to create capstone instance at: %lx",desc, ip); - } -} -*/ - -/* -static void debug_print_state(char* desc, CPUState* cpu_state){ - X86CPU *cpu = X86_CPU(cpu_state); - CPUX86State *env = &cpu->env; - debug_print_disasm(desc, env->eip, cpu_state); - nyx_debug_p(REDQUEEN_PREFIX,"ECX: %lx", get_reg_cpu(cpu_state, (char*)"rcx")); -} -*/ - -/* -int trace_debug = false; - -void handle_hook(redqueen_t* self){ - X86CPU *cpu = X86_CPU(self->cpu); - CPUX86State *env = &cpu->env; - - uint8_t ins; - - read_virtual_memory(env->eip, (uint8_t*)&ins, 1, self->cpu); - - if(ins == 0xcc && self->cpu->singlestep_enabled){ - fprintf(stderr, "fix... %lx\n", env->eip); - self->cpu->singlestep_enabled = false; - self->singlestep_enabled = false; - //kvm_insert_breakpoint(self->cpu, self->last_rip, 1, 0); - kvm_update_guest_debug(self->cpu, 0); - self->last_rip = 0; - return; - } - - if(!self->cpu->singlestep_enabled){ - fprintf(stderr, "HOOK %lx\n", env->eip); - - if(self->last_rip != 0) abort(); - self->last_rip = env->eip; - - read_virtual_memory(env->eip, (uint8_t*)&ins, 1, self->cpu); - if(ins != 0xcc) abort(); - kvm_remove_breakpoint(self->cpu, env->eip, 1, 0); - self->cpu->singlestep_enabled = true; - self->singlestep_enabled = true; - if(self->cpu->pt_enabled && self->cpu->pt_c3_filter == env->cr[3]){ - handle_hook_breakpoint(self); - } - kvm_update_guest_debug(self->cpu, 0); - - } else{ - fprintf(stderr, "HOOK %lx SINGLETEP\n", env->eip); - - - if(self->last_rip == 0) abort(); - - - - - - self->cpu->singlestep_enabled = false; - self->singlestep_enabled = false; - if(self->counter_bitmap[self->last_rip-self->address_range_start]++ < REDQUEEN_TRAP_LIMIT){ - fprintf(stderr, "TRAP INSTALLED\n"); - read_virtual_memory(env->eip, (uint8_t*)&ins, 1, self->cpu); - if(ins == 0xcc) abort(); - - if(ins != 0xcc) - kvm_insert_breakpoint(self->cpu, self->last_rip, 1, 0); - } - else { - fprintf(stderr, "TRAP INSTALLED nOPE %lx %lx\n", self->counter_bitmap[self->last_rip-self->address_range_start], self->counter_bitmap); - } - kvm_update_guest_debug(self->cpu, 0); - self->last_rip = 0; - } -} -*/ - - void handle_hook(redqueen_t* self){ X86CPU *cpu = X86_CPU(self->cpu); CPUX86State *env = &cpu->env; if (self->next_rip){ - //fprintf(stderr, "REMOVE %lx at %lx\n", self->next_rip, env->eip); remove_breakpoint(self->cpu, self->next_rip, 1); if(self->last_rip && redqueen_update_addr_count(self, self->last_rip) < REDQUEEN_TRAP_LIMIT){ @@ -941,11 +808,9 @@ void handle_hook(redqueen_t* self){ if(redqueen_check_addr(self, env->eip)){ - //fprintf(stderr, "INSERT %lx\n", env->eip); self->last_rip = env->eip; remove_breakpoint(self->cpu, env->eip, 1); - //if(self->cpu->pt_enabled && self->cpu->pt_c3_filter == env->cr[3]){ if(self->cpu->pt_enabled && GET_GLOBAL_STATE()->pt_c3_filter == env->cr[3]){ self->next_rip = handle_hook_breakpoint(self, true); } @@ -953,25 +818,18 @@ void handle_hook(redqueen_t* self){ self->next_rip = handle_hook_breakpoint(self, true); } } - else { - //fprintf(stderr, "NOPE %lx\n", env->eip); - } } static void _redqueen_update_whitelist(redqueen_t* self){ - //if(self->cpu->redqueen_instrumentation_mode == REDQUEEN_WHITELIST_INSTRUMENTATION){ - if(GET_GLOBAL_STATE()->redqueen_instrumentation_mode == REDQUEEN_WHITELIST_INSTRUMENTATION){ - //size_t num_addrs = 0; - //uint64_t *addrs; + if(GET_GLOBAL_STATE()->redqueen_instrumentation_mode == REDQUEEN_WHITELIST_INSTRUMENTATION){ free(self->breakpoint_whitelist); parse_address_file(redqueen_workdir.breakpoint_white, &self->num_breakpoint_whitelist, &self->breakpoint_whitelist); } } static void _redqueen_update_blacklist(redqueen_t* self){ - //if(self->cpu->redqueen_update_blacklist){ if(GET_GLOBAL_STATE()->redqueen_update_blacklist){ size_t num_addrs = 0; uint64_t *addrs; @@ -986,7 +844,6 @@ static void _redqueen_update_blacklist(redqueen_t* self){ void enable_rq_intercept_mode(redqueen_t* self){ if(!self->intercept_mode){ delete_redqueen_files(); - //unlink("/tmp/redqueen_result.txt"); _redqueen_update_whitelist(self); _redqueen_update_blacklist(self); redqueen_insert_hooks(self); diff --git a/nyx/redqueen.h b/nyx/redqueen.h index 636b60fdc0..a9881a5787 100644 --- a/nyx/redqueen.h +++ b/nyx/redqueen.h @@ -19,21 +19,20 @@ along with QEMU-PT. If not, see . */ -#ifndef REDQUEEN_H -#define REDQUEEN_H +#pragma once +#include "qemu/osdep.h" #include #include #include #include #include -#include "qemu/osdep.h" #include #include #include -#include "redqueen_trace.h" -#include "khash.h" -#include "page_cache.h" +#include "nyx/redqueen_trace.h" +#include "nyx/khash.h" +#include "nyx/page_cache.h" //#define RQ_DEBUG @@ -120,4 +119,3 @@ void redqueen_remove_hooks(redqueen_t* self); void redqueen_callback(void* opaque, disassembler_mode_t mode, uint64_t start_addr, uint64_t end_addr); -#endif diff --git a/nyx/redqueen_patch.c b/nyx/redqueen_patch.c index b0908af4ab..64f4bdea3a 100644 --- a/nyx/redqueen_patch.c +++ b/nyx/redqueen_patch.c @@ -1,18 +1,19 @@ +#include "qemu/osdep.h" #include "redqueen_patch.h" #include "redqueen.h" #include "patcher.h" #include "file_helper.h" #include "debug.h" -/////////////////////////////////////////////////////////////////////////////////// -// Private Helper Functions Declarations -/////////////////////////////////////////////////////////////////////////////////// +/* + * Private Helper Functions Declarations + */ void _load_and_set_patches(patcher_t* self); -/////////////////////////////////////////////////////////////////////////////////// -// Public Functions -/////////////////////////////////////////////////////////////////////////////////// +/* + * Public Functions + */ void pt_enable_patches(patcher_t *self){ _load_and_set_patches(self); @@ -24,9 +25,9 @@ void pt_disable_patches(patcher_t *self){ } -/////////////////////////////////////////////////////////////////////////////////// -// Private Helper Functions Definitions -/////////////////////////////////////////////////////////////////////////////////// +/* + * Private Helper Functions Definitions + */ void _load_and_set_patches(patcher_t* self){ diff --git a/nyx/redqueen_patch.h b/nyx/redqueen_patch.h index 07c8849fc9..2ef11f66f7 100644 --- a/nyx/redqueen_patch.h +++ b/nyx/redqueen_patch.h @@ -1,11 +1,8 @@ -#ifndef __GUARD_REDQUEEN_PATCH__ -#define __GUARD_REDQUEEN_PATCH__ +#pragma once -#include "qemu/osdep.h" -#include +#include "sysemu/kvm.h" #include "nyx/patcher.h" void pt_enable_patches(patcher_t *self); void pt_disable_patches(patcher_t *self); -#endif diff --git a/nyx/redqueen_trace.c b/nyx/redqueen_trace.c index 4c9dacbef8..48d51305f8 100644 --- a/nyx/redqueen_trace.c +++ b/nyx/redqueen_trace.c @@ -1,3 +1,4 @@ +#include "qemu/osdep.h" #include #include #include diff --git a/nyx/redqueen_trace.h b/nyx/redqueen_trace.h index a4fdc17b3e..1f527814aa 100644 --- a/nyx/redqueen_trace.h +++ b/nyx/redqueen_trace.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include @@ -5,8 +7,7 @@ #include "qemu/osdep.h" -#pragma once -#include "khash.h" +#include "nyx/khash.h" #include typedef unsigned __int128 uint128_t; @@ -19,11 +20,13 @@ typedef uint128_t khint128_t; @param key The integer [khint64_t] @return The hash value [khint_t] */ -#define kh_int128_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11) ^ (((key>>64))>>33^((key>>64))^((key>>64))<<11) +#define kh_int128_hash_func(key) \ + (khint32_t)((key) >> 33 ^ (key) ^ (key) << 11) ^ (((key >> 64)) >> 33 ^ ((key >> 64)) ^ ((key >> 64)) << 11) /*! @function @abstract 64-bit integer comparison function */ #define kh_int128_hash_equal(a, b) ((a) == (b)) + /*! @function @abstract Instantiate a hash map containing 64-bit integer keys @param name Name of the hash table [symbol] diff --git a/nyx/sharedir.c b/nyx/sharedir.c index 40e94e3365..91a1491b78 100644 --- a/nyx/sharedir.c +++ b/nyx/sharedir.c @@ -1,12 +1,15 @@ -#include "sharedir.h" +#include "qemu/osdep.h" + #include -#include #include #include -#include +#include #include +#include #include + #include "nyx/debug.h" +#include "sharedir.h" //#define SHAREDIR_DEBUG @@ -98,7 +101,6 @@ static sharedir_file_t* sharedir_get_object(sharedir_t* self, const char* file){ obj->mod_time = get_file_mod_time(obj->path); /* put into hash_list */ - char* new_file = NULL; assert(asprintf(&new_file, "%s", file) != -1); k = kh_put(SHAREDIR_LOOKUP, self->lookup, new_file, &ret); diff --git a/nyx/sharedir.h b/nyx/sharedir.h index f6a0d20a5f..7ced681329 100644 --- a/nyx/sharedir.h +++ b/nyx/sharedir.h @@ -1,8 +1,8 @@ #pragma once -#include -#include "khash.h" -#include +#include +#include +#include "khash.h" typedef struct sharedir_file_s{ char* file; diff --git a/nyx/snapshot/block/block_cow.c b/nyx/snapshot/block/block_cow.c index e0188fbb43..7fb0652df2 100644 --- a/nyx/snapshot/block/block_cow.c +++ b/nyx/snapshot/block/block_cow.c @@ -1,6 +1,9 @@ +#include "qemu/osdep.h" + #include #include #include + #include "nyx/snapshot/block/block_cow.h" #include "sysemu/block-backend.h" #include "nyx/state/state.h" @@ -8,7 +11,6 @@ //#define COW_CACHE_DEBUG - //#define COW_CACHE_VERBOSE #define CHUNK_SIZE 0x1000 @@ -31,8 +33,6 @@ static inline uint64_t get_global_cow_cache_primary_size(void){ cow_cache_t* cow_cache_new(const char* filename){ - //printf("%s: \"%s\"\n", __func__, filename); - cow_cache_t* self = malloc(sizeof(cow_cache_t)); self->lookup_primary = kh_init(COW_CACHE); self->lookup_secondary = kh_init(COW_CACHE); @@ -41,7 +41,6 @@ cow_cache_t* cow_cache_new(const char* filename){ self->cow_primary_size = COW_CACHE_PRIMARY_MINIMUM_SIZE; self->data_primary = mmap(NULL, self->cow_primary_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); assert(self->data_primary != MAP_FAILED); - //memset(self->data_primary, COW_CACHE_PRIMARY_MINIMUM_SIZE/CHUNK_SIZE, CHUNK_SIZE); self->data_secondary = mmap(NULL, COW_CACHE_SECONDARY_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); assert(self->data_secondary != MAP_FAILED); @@ -88,7 +87,6 @@ static char* gen_file_name(cow_cache_t* self, const char* filename_prefix, const } assert(asprintf(&tmp1, "%s_%s.%s", filename_prefix, tmp2, filename_postfix) != -1); - free(tmp2); return tmp1; @@ -98,18 +96,12 @@ void read_primary_buffer(cow_cache_t* self, const char* filename_prefix, bool sw assert(!self->enabled_fuzz); global_cow_primary_size_adjustable = false; - //printf("%s: %s\n", __func__, self->filename); - char* tmp1; char* tmp2; - //assert(asprintf(&tmp1, "%s_%s.khash", filename_prefix, self->filename) != -1); - //assert(asprintf(&tmp2, "%s_%s.pcow", filename_prefix, self->filename) != -1); - tmp1 = gen_file_name(self, filename_prefix, "khash"); tmp2 = gen_file_name(self, filename_prefix, "pcow"); - //printf("%s\n", tmp1); kh_destroy(COW_CACHE, self->lookup_primary); struct stat buffer; @@ -129,7 +121,6 @@ void read_primary_buffer(cow_cache_t* self, const char* filename_prefix, bool sw int fd = open(tmp2, O_RDONLY); - //printf("TRY TO MMAP : %lx\n", buffer.st_size); if(switch_mode){ munmap(self->data_primary, self->cow_primary_size); self->cow_primary_size = get_global_cow_cache_primary_size(); @@ -150,11 +141,9 @@ void read_primary_buffer(cow_cache_t* self, const char* filename_prefix, bool sw memcpy(self->data_primary, ptr, buffer.st_size); munmap(ptr, COW_CACHE_PRIMARY_MINIMUM_SIZE); } - //printf("self->data_primary -> %p\n", self->data_primary ); close(fd); self->offset_primary = buffer.st_size; - //fprintf(stderr, "self->offset_primary: %lx\n", self->offset_primary); if(switch_mode){ switch_to_fuzz_mode(self); @@ -162,27 +151,17 @@ void read_primary_buffer(cow_cache_t* self, const char* filename_prefix, bool sw free(tmp1); free(tmp2); - - //printf("DONE!\n"); - } void dump_primary_buffer(cow_cache_t* self, const char* filename_prefix){ assert(self->enabled_fuzz); - //printf("%s: %s\n", __func__, self->filename); - - char* tmp1; char* tmp2; - //assert(asprintf(&tmp1, "%s_%s.khash", filename_prefix, self->filename) != -1); - //assert(asprintf(&tmp2, "%s_%s.pcow", filename_prefix, self->filename) != -1); - tmp1 = gen_file_name(self, filename_prefix, "khash"); tmp2 = gen_file_name(self, filename_prefix, "pcow"); - //printf("%s\n", tmp1); if(self->offset_primary){ kh_write(COW_CACHE, self->lookup_primary, tmp1); } @@ -194,33 +173,16 @@ void dump_primary_buffer(cow_cache_t* self, const char* filename_prefix){ if(fp == NULL) { fprintf(stderr, "[%s] Could not open file %s.\n", __func__, tmp2); assert(false); - //exit(EXIT_FAILURE); } if(self->offset_primary){ fwrite(self->data_primary, CHUNK_SIZE, self->offset_primary/CHUNK_SIZE, fp); } - //fprintf(stderr, "self->offset_primary: %lx\n", self->offset_primary); - fclose(fp); free(tmp1); free(tmp2); - - //printf("DONE!\n"); - - -/* - - qemu_mutex_unlock_iothread(); - fast_reload_t* snapshot = fast_reload_new(); - fast_reload_create(snapshot); - qemu_mutex_lock_iothread(); - - printf("CREATED!\n"); -*/ - } void cow_cache_reset(cow_cache_t* self){ @@ -229,9 +191,6 @@ void cow_cache_reset(cow_cache_t* self){ /* TODO */ assert(self->enabled_fuzz); - //fprintf(stderr, "RESETING COW STUFF YO %s (%lx)\n", self->filename, self->offset_secondary); - - if(self->enabled_fuzz){ #ifdef DEBUG_COW_LAYER @@ -315,7 +274,6 @@ static inline void read_from_primary_buffer(cow_cache_t* self, BlockBackend *blk #ifdef COW_CACHE_DEBUG printf("[PRE ] READ DIRTY COW PAGE: ADDR: %lx IOVEC OFFSET: %lx DATA OFFSET: %lx\n", offset_addr, iov_offset, self->offset_primary); #endif - //iov_from_buf_full_register(qiov->iov, qiov->niov, iov_offset, self->data_primary + kh_value(self->lookup_primary, k), CHUNK_SIZE); qemu_iovec_from_buf(qiov, iov_offset, self->data_primary + kh_value(self->lookup_primary, k), CHUNK_SIZE); } return; @@ -332,7 +290,6 @@ static inline void read_from_secondary_buffer(cow_cache_t* self, BlockBackend *b #ifdef COW_CACHE_DEBUG printf("[FTMP] READ DIRTY COW PAGE: ADDR: %lx IOVEC OFFSET: %lx DATA OFFSET: %lx\n", offset_addr, iov_offset, self->offset_secondary); #endif - //iov_from_buf_full_register(qiov->iov, qiov->niov, iov_offset, self->data_secondary_tmp + kh_value(self->lookup_secondary_tmp, k), CHUNK_SIZE); qemu_iovec_from_buf(qiov, iov_offset, self->data_secondary_tmp + kh_value(self->lookup_secondary_tmp, k), CHUNK_SIZE); return; } @@ -344,7 +301,6 @@ static inline void read_from_secondary_buffer(cow_cache_t* self, BlockBackend *b #ifdef COW_CACHE_DEBUG printf("[FUZZ] READ DIRTY COW PAGE: ADDR: %lx IOVEC OFFSET: %lx DATA OFFSET: %lx\n", offset_addr, iov_offset, self->offset_secondary); #endif - //iov_from_buf_full_register(qiov->iov, qiov->niov, iov_offset, self->data_secondary + kh_value(self->lookup_secondary, k), CHUNK_SIZE); qemu_iovec_from_buf(qiov, iov_offset, self->data_secondary + kh_value(self->lookup_secondary, k), CHUNK_SIZE); return; } @@ -355,7 +311,6 @@ static inline void read_from_secondary_buffer(cow_cache_t* self, BlockBackend *b #ifdef COW_CACHE_DEBUG printf("[PRE ] READ DIRTY COW PAGE: ADDR: %lx IOVEC OFFSET: %lx DATA OFFSET: %lx\n", offset_addr, iov_offset, self->offset_primary); #endif - //iov_from_buf_full_register(qiov->iov, qiov->niov, iov_offset, self->data_primary + kh_value(self->lookup_primary, k), CHUNK_SIZE); qemu_iovec_from_buf(qiov, iov_offset, self->data_primary + kh_value(self->lookup_primary, k), CHUNK_SIZE); } } @@ -373,9 +328,6 @@ static int cow_cache_read(cow_cache_t* self, BlockBackend *blk, int64_t offset, } } #endif - - //iov_from_buf_full_register(qiov->iov, qiov->niov, offset, NULL, bytes); - blk_co_preadv(blk, offset, bytes, qiov, flags); if ((qiov->size%CHUNK_SIZE)){ @@ -411,7 +363,6 @@ static inline void write_to_primary_buffer(cow_cache_t* self, BlockBackend *blk, k = kh_get(COW_CACHE, self->lookup_primary, offset_addr); if(unlikely(k == kh_end(self->lookup_primary))){ /* create page */ - k = kh_put(COW_CACHE, self->lookup_primary, offset_addr, &ret); #ifdef COW_CACHE_DEBUG printf("ADD NEW COW PAGE: ADDR: %lx IOVEC OFFSET: %lx DATA OFFSET: %lx\n", offset_addr, iov_offset, self->offset_primary); @@ -436,23 +387,11 @@ static inline void write_to_primary_buffer(cow_cache_t* self, BlockBackend *blk, /* write to cached page */ qemu_iovec_to_buf(qiov, iov_offset, self->data_primary + kh_value(self->lookup_primary, k), CHUNK_SIZE); - - - /* - if(self->offset_primary >= 0xA00000){ - printf("SWITCH TO SECONDARY\n"); - switch_to_fuzz_mode(self); - dump_primary_buffer(self, "/tmp/cow_dump"); - } - */ - } static inline void write_to_secondary_buffer(cow_cache_t* self, BlockBackend *blk, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags, uint64_t offset_addr, uint64_t iov_offset){ int ret; - //assert((offset_addr&(CHUNK_SIZE-1)) == 0); - if(!self->enabled_fuzz_tmp){ /* L2 mode */ @@ -471,7 +410,6 @@ static inline void write_to_secondary_buffer(cow_cache_t* self, BlockBackend *bl self->offset_secondary += CHUNK_SIZE; } - //printf("WRITE -> %lx\n", kh_value(self->lookup_secondary, k_secondary)); /* write to cache */ qemu_iovec_to_buf(qiov, iov_offset, self->data_secondary + kh_value(self->lookup_secondary, k_secondary), CHUNK_SIZE); } @@ -494,14 +432,12 @@ static inline void write_to_secondary_buffer(cow_cache_t* self, BlockBackend *bl } /* write to cache */ - //printf("WRITE TO L2 TMP -> %lx\n", self->data_secondary_tmp + kh_value(self->lookup_secondary_tmp, k_secondary_tmp)); qemu_iovec_to_buf(qiov, iov_offset, self->data_secondary_tmp + kh_value(self->lookup_secondary_tmp, k_secondary_tmp), CHUNK_SIZE); } } /* write data to cow cache */ static int cow_cache_write(cow_cache_t* self, BlockBackend *blk, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags){ - //khiter_t k; #ifdef DEBUG_COW_LAYER if(self->enabled_fuzz){ @@ -520,7 +456,6 @@ static int cow_cache_write(cow_cache_t* self, BlockBackend *blk, int64_t offset, #endif return 0; } - //printf("qiov->size: %lx %lx\n", qiov->size, CHUNK_SIZE); if((qiov->size%CHUNK_SIZE) && GET_GLOBAL_STATE()->in_fuzzing_mode){ GET_GLOBAL_STATE()->cow_cache_full = true; fprintf(stderr, "WARNING: %s write in %lx CHUNKSIZE\n", __func__, qiov->size); @@ -560,12 +495,8 @@ void cow_cache_read_entry(void* opaque){ printf("%s %lx %lx\n", __func__, rwco->offset, acb->bytes); #endif - - //printf("rwco->ret: %lx %lx\n", rwco->ret, acb->bytes); rwco->ret = cow_cache_read( *((cow_cache_t**)(rwco->blk)), rwco->blk, rwco->offset, acb->bytes, rwco->qiov, rwco->flags); - //last_read = PAGE_MASK; - blk_aio_complete(acb); } diff --git a/nyx/snapshot/block/block_cow.h b/nyx/snapshot/block/block_cow.h index c94eb5e64e..55a65226da 100644 --- a/nyx/snapshot/block/block_cow.h +++ b/nyx/snapshot/block/block_cow.h @@ -3,11 +3,11 @@ #include #include -#include "nyx/khash.h" #include "qemu/osdep.h" #include "block/block.h" +#include "nyx/khash.h" #include "nyx/redqueen_trace.h" //#define DEBUG_COW_LAYER @@ -57,9 +57,6 @@ typedef struct cow_cache_s{ cow_cache_t* cow_cache_new(const char* filename); void cow_cache_reset(cow_cache_t* self); -//int coroutine_fn cow_cache_read(cow_cache_t* self, BlockBackend *blk, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags); -//int coroutine_fn cow_cache_write(cow_cache_t* self, BlockBackend *blk, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags); - void switch_to_fuzz_mode(cow_cache_t* self); diff --git a/nyx/snapshot/block/nyx_block_snapshot.c b/nyx/snapshot/block/nyx_block_snapshot.c index 3727983a76..9186ec153f 100644 --- a/nyx/snapshot/block/nyx_block_snapshot.c +++ b/nyx/snapshot/block/nyx_block_snapshot.c @@ -1,16 +1,14 @@ - #include "qemu/osdep.h" -#include "sysemu/sysemu.h" -#include "cpu.h" -#include "qemu/main-loop.h" -#include "sysemu/block-backend.h" #include "block/qapi.h" -#include "sysemu/runstate.h" #include "migration/vmstate.h" +#include "qemu/main-loop.h" +#include "sysemu/block-backend.h" +#include "sysemu/runstate.h" +#include "sysemu/sysemu.h" -#include "nyx/snapshot/block/nyx_block_snapshot.h" #include "nyx/debug.h" +#include "nyx/snapshot/block/nyx_block_snapshot.h" #include "nyx/state/state.h" typedef struct fast_reload_cow_entry_s{ @@ -109,39 +107,6 @@ nyx_block_t* nyx_block_snapshot_init(void){ return self; } -/* - - -static void fast_reload_serialize_cow(fast_reload_t* self, const char* folder){ - fast_reload_cow_entry_t entry; - - char* tmp1; - char* tmp2; - - assert(asprintf(&tmp1, "%s/fs_cache.meta", folder) != -1); - assert(asprintf(&tmp2, "%s/fs_drv", folder) != -1); - - - FILE* f = fopen (tmp1, "w"); - - fwrite(&(self->cow_cache_array_size), sizeof(uint32_t), 1, f); - - for(uint32_t i = 0; i < self->cow_cache_array_size; i++){ - entry.id = i; - printf("%d -> %s\n", i, (const char*)self->cow_cache_array[i]->filename); - strncpy((char*)&entry.idstr, (const char*)self->cow_cache_array[i]->filename, 256); - fwrite(&entry, sizeof(fast_reload_cow_entry_t), 1, f); - - dump_primary_buffer(self->cow_cache_array[i], tmp2); - } - fclose(f); - - free(tmp1); - free(tmp2); -} - -*/ - void nyx_block_snapshot_flush(nyx_block_t* self){ GET_GLOBAL_STATE()->cow_cache_full = false; } @@ -181,7 +146,6 @@ void nyx_block_snapshot_serialize(nyx_block_t* self, const char* snapshot_folder for(uint32_t i = 0; i < self->cow_cache_array_size; i++){ entry.id = i; - //printf("%d -> %s\n", i, (const char*)self->cow_cache_array[i]->filename); strncpy((char*)&entry.idstr, (const char*)self->cow_cache_array[i]->filename, 255); fwrite(&entry, sizeof(fast_reload_cow_entry_t), 1, f); diff --git a/nyx/snapshot/devices/nyx_device_state.c b/nyx/snapshot/devices/nyx_device_state.c index e387642e5a..3fd170eadd 100644 --- a/nyx/snapshot/devices/nyx_device_state.c +++ b/nyx/snapshot/devices/nyx_device_state.c @@ -1,44 +1,34 @@ - #include "qemu/osdep.h" -#include "sysemu/sysemu.h" -#include "cpu.h" -#include "qemu/main-loop.h" -#include "exec/ram_addr.h" -#include "qemu/rcu_queue.h" -#include "migration/migration.h" -#include "migration/register.h" -#include "migration/savevm.h" -#include "migration/qemu-file.h" -#include "migration/qjson.h" -#include "migration/global_state.h" - -#include "nyx/snapshot/devices/nyx_device_state.h" -#include "nyx/debug.h" - -#include "sysemu/block-backend.h" -#include "block/qapi.h" -#include "sysemu/runstate.h" -#include "migration/vmstate.h" - -#include "nyx/snapshot/devices/state_reallocation.h" - -#include -#include -#include -#include -#include #include #include +#include +#include -#include "sysemu/kvm_int.h" +#include "qemu/main-loop.h" +#include "qemu/rcu_queue.h" + +#include "block/qapi.h" +#include "exec/ram_addr.h" +#include "migration/global_state.h" +#include "migration/migration.h" +#include "migration/qemu-file.h" +#include "migration/qjson.h" +#include "migration/register.h" +#include "migration/savevm.h" +#include "migration/vmstate.h" +#include "sysemu/block-backend.h" #include "sysemu/cpus.h" +#include "sysemu/kvm.h" #include "sysemu/reset.h" +#include "sysemu/runstate.h" +#include "sysemu/sysemu.h" +#include "nyx/debug.h" +#include "nyx/snapshot/devices/nyx_device_state.h" +#include "nyx/snapshot/devices/state_reallocation.h" #include "nyx/snapshot/devices/vm_change_state_handlers.h" - - #define STATE_BUFFER 0x8000000 /* up to 128MB */ extern void enable_fast_snapshot_rtc(void); @@ -67,7 +57,7 @@ static void save_tsc_value(nyx_device_state_t* self, bool incremental_mode){ CPUX86State *env = &cpu->env; if(incremental_mode){ - self->tsc_value_incremental = env->tsc; // - 0x200000; /* fml */ + self->tsc_value_incremental = env->tsc; } else{ self->tsc_value = env->tsc; @@ -342,7 +332,6 @@ nyx_device_state_t* nyx_device_state_init_from_snapshot(const char* snapshot_fol uint8_t ret = global_state_store(); assert(!ret); - /* Testing Stuff */ struct stat buffer; assert(stat (qemu_state_file, &buffer) == 0); @@ -353,7 +342,7 @@ nyx_device_state_t* nyx_device_state_init_from_snapshot(const char* snapshot_fol fclose(f); fast_savevm_opaque.buf = state_buf2; - fast_savevm_opaque.f = NULL;//fopen("/tmp/qemu_state", "w"); + fast_savevm_opaque.f = NULL; fast_savevm_opaque.pos = 0; QEMUFile* file_dump = qemu_fopen_ops(&fast_savevm_opaque, &fast_loadvm_ops); @@ -390,16 +379,14 @@ nyx_device_state_t* nyx_device_state_init(void){ Error *local_err = NULL; struct fast_savevm_opaque_t fast_savevm_opaque, fast_loadvm_opaque; - //state_reallocation_t* qemu_state; void* tmp_buf = malloc(1024*1024*16); - //memset(self->state_buf, 0, STATE_BUFFER); fast_savevm_opaque.output_buffer = self->state_buf; fast_savevm_opaque.output_buffer_size = &self->state_buf_size; - fast_savevm_opaque.buf = tmp_buf;//self->state_buf; - fast_savevm_opaque.f = NULL; //fopen("/tmp/delta", "w"); + fast_savevm_opaque.buf = tmp_buf; + fast_savevm_opaque.f = NULL; fast_savevm_opaque.pos = 0; uint8_t ret = global_state_store(); @@ -407,31 +394,21 @@ nyx_device_state_t* nyx_device_state_init(void){ QEMUFile* f = qemu_fopen_ops(&fast_savevm_opaque, &fast_savevm_ops_to_buffer); ret = fast_qemu_savevm_state(f, &local_err); - //qemu_fflush(f); - - fast_loadvm_opaque.buf = tmp_buf; //self->state_buf; + fast_loadvm_opaque.buf = tmp_buf; fast_loadvm_opaque.f = NULL; fast_loadvm_opaque.pos = 0; QEMUFile* file_dump = qemu_fopen_ops(&fast_loadvm_opaque, &fast_loadvm_ops); - //qemu_mutex_lock_iothread(); - //qemu_devices_reset(); self->qemu_state = state_reallocation_new(file_dump); - //qemu_mutex_unlock_iothread(); qemu_fclose(file_dump); - - //sleep(1); qemu_fclose(f); free(tmp_buf); - enable_fast_snapshot_mode(); save_tsc_value(self, false); return self; - - //return qemu_state; } void nyx_device_state_switch_incremental(nyx_device_state_t* self){ diff --git a/nyx/snapshot/devices/state_reallocation.c b/nyx/snapshot/devices/state_reallocation.c index 9bcd958c2b..9a1a17b7b0 100644 --- a/nyx/snapshot/devices/state_reallocation.c +++ b/nyx/snapshot/devices/state_reallocation.c @@ -19,21 +19,22 @@ along with QEMU-PT. If not, see . */ #include "qemu/osdep.h" -#include "sysemu/sysemu.h" -#include "target/i386/cpu.h" -#include "qemu/main-loop.h" -#include "sysemu/kvm_int.h" -#include "migration/vmstate.h" +#include "qemu/main-loop.h" +#include "sysemu/sysemu.h" + +#include "migration/qemu-file.h" #include "migration/register.h" #include "migration/savevm.h" -#include "migration/qemu-file.h" +#include "migration/vmstate.h" +#include "sysemu/kvm_int.h" + #include "nyx/debug.h" -#include "nyx/snapshot/devices/state_reallocation.h" #include "nyx/snapshot/devices/nyx_device_state.h" +#include "nyx/snapshot/devices/state_reallocation.h" +//#define VERBOSE_DEBUG -//uint32_t fpos = 0; #define QEMU_VM_SUBSECTION 0x05 typedef struct CompatEntry { @@ -85,20 +86,13 @@ static void fast_timer_get(void* data, size_t size, void* opaque) { QEMUTimer *ts = (QEMUTimer*) opaque; uint64_t expire_time = *((uint64_t*)data); - //fprintf(stderr, "%s: VALUE IS: %lx\n", __func__, expire_time); - if (expire_time != -1) { timer_mod_ns(ts, expire_time); } else { timer_del(ts); } - //fprintf(stderr, "%s: DONE!\n", __func__); - } - - - static SaveStateEntry *fdl_find_se(const char *idstr, int instance_id) { SaveStateEntry *se; @@ -107,7 +101,6 @@ static SaveStateEntry *fdl_find_se(const char *idstr, int instance_id) if (!strcmp(se->idstr, idstr) && (instance_id == se->instance_id || instance_id == se->alias_id)){ - //printf("FOUND 1\n"); return se; } /* Migrating from an older version? */ @@ -115,12 +108,10 @@ static SaveStateEntry *fdl_find_se(const char *idstr, int instance_id) if (!strcmp(se->compat->idstr, idstr) && (instance_id == se->compat->instance_id || instance_id == se->alias_id)){ - //printf("FOUND 2\n"); return se; } } } - printf("NOPE\n"); return NULL; } @@ -131,9 +122,7 @@ static inline VMStateDescription* fdl_vmstate_get_subsection(VMStateDescription { while (sub && *sub && (*sub)->needed) { if (strcmp(idstr, (*sub)->name) == 0) { - //printf("SUB %p\n", &sub); - //sub_vmsd_ptr = ⊂ - return *sub; /* don't dereference...return ptr */ + return *sub; } sub++; } @@ -150,9 +139,7 @@ static int fdl_vmstate_subsection_load(state_reallocation_t* self, QEMUFile *f, len = qemu_peek_byte(f, 1); if (len < strlen(vmsd->name) + 1) { - /* subsection name has be be "section_name/a" */ - //fprintf(stderr, "%s: exit\n", __func__); - + /* subsection name has to be "section_name/a" */ return 0; } size = qemu_peek_buffer(f, (uint8_t **)&idstr_ret, len, 2); @@ -164,7 +151,6 @@ static int fdl_vmstate_subsection_load(state_reallocation_t* self, QEMUFile *f, if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) { /* it doesn't have a valid subsection name */ - //fprintf(stderr, "%s: exit\n", __func__); return 0; } sub_vmsd = fdl_vmstate_get_subsection((VMStateDescription **)vmsd->subsections, idstr); @@ -199,8 +185,6 @@ static void add_post_fptr(state_reallocation_t* self, void* fptr, uint32_t versi if(!self){ return; } - //printf("%s: %s\n", __func__, name); - if(!strcmp("I440FX", name)){ return; @@ -271,7 +255,7 @@ static void add_post_fptr(state_reallocation_t* self, void* fptr, uint32_t versi self->fast_state_fptr_pos++; if(self->fast_state_fptr_pos >= self->fast_state_fptr_size){ - printf("RESIZE %s\n", __func__); + nyx_debug("RESIZE %s\n", __func__); self->fast_state_fptr_size += REALLOC_SIZE; self->fptr = realloc(self->fptr, self->fast_state_fptr_size * sizeof(void*)); self->opaque = realloc(self->opaque, self->fast_state_fptr_size * sizeof(void*)); @@ -482,36 +466,26 @@ static inline int get_handler(state_reallocation_t* self, QEMUFile* f, void* cur add_mblock(self, vmsd_name, field->name, field->offset, (uint64_t)curr_elem, 8); } else if(!strcmp(field->info->name, "CPU_Double_U")){ - //fprintf(stderr, "type: %s (size: %x)\n", field->info->name, size); assert(0); add_mblock(self, vmsd_name, field->name, field->offset, (uint64_t)curr_elem, 8); } else if(!strcmp(field->info->name, "buffer")){ - //fprintf(stderr, "type: %s (size: %x)\n", field->info->name, size); add_mblock(self, vmsd_name, field->name, field->offset, (uint64_t)curr_elem, size); } else if(!strcmp(field->info->name, "unused_buffer")){ - //fprintf(stderr, "type: %s (size: %x)\n", field->info->name, size); /* save nothing */ } else if(!strcmp(field->info->name, "tmp")){ - //fprintf(stderr, "type: %s (size: %x)\n", field->info->name, size); add_mblock(self, vmsd_name, field->name, field->offset, (uint64_t)curr_elem, size); - /* save nothing */ } else if(!strcmp(field->info->name, "bitmap")){ - //fprintf(stderr, "type: %s (size: %x)\n", field->info->name, size); assert(0); } else if(!strcmp(field->info->name, "qtailq")){ - //fprintf(stderr, "type: %s (size: %x)\n", field->info->name, size); assert(0); } else if(!strcmp(field->info->name, "timer")){ - //fprintf(stderr, "type: %s (size: %x)\n", field->info->name, size); - //printf("%s time\n", vmsd_name); - //add_mblock(self, vmsd_name, field->name, field->offset, (uint64_t)curr_elem, sizeof(QEMUTimer)); add_get(self, (void*) field->info->get, curr_elem, size, (void*) field, f, field->info->name); } else if(!strcmp(field->info->name, "fpreg")){ @@ -520,56 +494,32 @@ static inline int get_handler(state_reallocation_t* self, QEMUFile* f, void* cur add_get(self, (void*) field->info->get, curr_elem, size, (void*) field, f, field->info->name); } else if(!strcmp(field->info->name, "pci config")){ - //fprintf(stderr, "type: %s (size: %lx)\n", field->info->name, size); add_get(self, (void*) field->info->get, curr_elem, size, (void*) field, f, field->info->name); } else if(!strcmp(field->info->name, "pci irq state")){ - //fprintf(stderr, "type: %s (size: %lx)\n", field->info->name, size); add_get(self, (void*) field->info->get, curr_elem, size, (void*) field, f, field->info->name); } else if(!strcmp(field->info->name, "virtio")){ add_get(self, (void*) field->info->get, curr_elem, size, (void*) field, f, field->info->name); - //fprintf(stderr, "[QEMU-PT] %s: WARNING no handler for %s, type %s, size %lx!\n", - // __func__, vmsd_name, field->info->name, size); } else{ fprintf(stderr, "[QEMU-PT] %s: WARNING no handler for %s, type %s, size %lx!\n", __func__, vmsd_name, field->info->name, size); assert(0); } - return ret; } - - -//migration_obj_t* obj; -//void* base_opaque; - -//#define VERBOSE_DEBUG - -/* todo: modify opaque_ptr */ +/* TODO: modify opaque_ptr */ static int fdl_vmstate_load_state(state_reallocation_t* self, QEMUFile *f, const VMStateDescription *vmsd, void *opaque, int version_id, uintptr_t* opaque_ptr) { #ifdef VERBOSE_DEBUG printf("---------------------------------\nVMSD: %p\t%s\n", opaque, vmsd->name); #endif - //fprintf(stderr, "---------------------------------\nVMSD: %p\t%s\n", opaque, vmsd->name); - VMStateField *field = (VMStateField *)vmsd->fields; int ret = 0; - /* - bool alloc_later = false; - if(alloc_block){ - base_opaque = opaque; - alloc_block = false; - alloc_later = true; - obj = alloc_migration_obj(); - } - */ - uint64_t total_size = 0; if (version_id > vmsd->version_id) { @@ -594,31 +544,14 @@ static int fdl_vmstate_load_state(state_reallocation_t* self, QEMUFile *f, const printf("\tPRELOAD Function\n"); #endif /* TODO ADD PRE FPTR FOR SERIAL */ - //add_pre_fptr(self, vmsd->pre_load, opaque, vmsd->name); //fprintf(stderr, "PRELOAD RUN: %s\n", vmsd->name); //add_pre_fptr(self, vmsd->pre_load, opaque, vmsd->name); add_post_fptr(self, vmsd->pre_load, 1337, opaque, vmsd->name); - //int ret = 0; - //return; - - - - /* - int ret = vmsd->pre_load(opaque); - if (ret) { - return ret; - } - */ - - } while (field->name) { #ifdef VERBOSE_DEBUG printf("Field: %s %s %s\n", __func__, vmsd->name, field->name); #endif - //fprintf(stderr, "Field: %s %s %s\n", __func__, vmsd->name, field->name); - - //printf("Field: %s %s %s\n", __func__, vmsd->name, field->name); if ((field->field_exists && field->field_exists(opaque, version_id)) || (!field->field_exists && @@ -627,8 +560,6 @@ static int fdl_vmstate_load_state(state_reallocation_t* self, QEMUFile *f, const int i, n_elems = vmstate_n_elems(opaque, field); int size = vmstate_size(opaque, field); - //printf("\t\t%s %d\n", field->name, size); - #ifdef VERBOSE_DEBUG printf("-----------------> vmstate_handle_alloc\n"); #endif @@ -640,33 +571,16 @@ static int fdl_vmstate_load_state(state_reallocation_t* self, QEMUFile *f, const #endif // printf("Field-Offset 0x%lx-0x%lx\n", opaque+field->offset, opaque+field->offset+(size*n_elems)); - /* fix me */ - /* broken af */ - //printf("add_translatable_block: %lx %lx %ld\n", *(void **)first_elem, first_elem, n_elems*size); - /* - if((n_elems*size)){ - add_translatable_block((void*)(*(void **)first_elem), (void*)first_elem, (uint64_t)(n_elems*size), field->name, 0, (void*) NULL, (void*) NULL); - } - */ - - //fprintf(stderr, "FIX ME VMS_POINTER\n"); first_elem = *(void **)first_elem; assert(first_elem || !n_elems || !size); } + for (i = 0; i < n_elems; i++) { uint64_t* tmp_opaque_ptr = 0; total_size += size; void *curr_elem = first_elem + size * i; - //if (!(field->flags & VMS_POINTER)) { - // tmp_opaque_ptr = 0; - //} - //assert(!(field->flags & VMS_POINTER) || n_elems == 1); - if (field->flags & VMS_ARRAY_OF_POINTER) { - //printf("VMS_ARRAY_OF_POINTER\n"); - //add_mblock((uint64_t)(curr_elem), (uint64_t)(size)); - //add_mblock((uint64_t)(field->offset + (opaque)), (uint64_t)(size*n_elems)); #ifdef VERBOSE_DEBUG printf("Field-Offset 1 0x%lx-0x%lx\n", (uint64_t)(field->offset + (opaque)), (uint64_t)(field->offset+(size*n_elems) + (opaque))); printf("=VMS_ARRAY_OF_POINTER 1= %lx %x\n", *((uint64_t*)curr_elem), size); @@ -684,9 +598,6 @@ static int fdl_vmstate_load_state(state_reallocation_t* self, QEMUFile *f, const if (!curr_elem && size) { // if null pointer check placeholder and do not follow assert(field->flags & VMS_ARRAY_OF_POINTER); - //printf("=================vmstate_info_nullptr\n");# - //add_mblock((uint64_t)(curr_elem), (uint64_t)(size)); - //add_mblock((uint64_t)(field->offset + (opaque)), (uint64_t)(size*n_elems)); #ifdef VERBOSE_DEBUG printf("Field-Offset 2 0x%lx-0x%lx\n", (uint64_t)(field->offset + (opaque)), (uint64_t)(field->offset+(size*n_elems) + (opaque))); printf("=VMS_ARRAY_OF_POINTER 2= %lx %x\n", *((uint64_t*)curr_elem), size); @@ -706,8 +617,7 @@ static int fdl_vmstate_load_state(state_reallocation_t* self, QEMUFile *f, const printf("=VMS_STRUCT= %lx %x\n", *((uint64_t*)curr_elem), size); //hexDump((void*)field->name, curr_elem, size); #endif - /* fix me */ - //ret = vmstate_load_state(f, field->vmsd, curr_elem, field->vmsd->version_id); + /* FIXME */ ret = fdl_vmstate_load_state(self, f, field->vmsd, curr_elem, field->vmsd->version_id, tmp_opaque_ptr); #ifdef VERBOSE_DEBUG //hexDump((void*)field->name, curr_elem, size); @@ -719,9 +629,6 @@ static int fdl_vmstate_load_state(state_reallocation_t* self, QEMUFile *f, const ret = get_handler(self, f, curr_elem, size, field, (char*)vmsd->name); } if (ret >= 0) { - //printf("FILE ERROR\n"); - //fprintf(stderr, "FILE ERROR\n"); - //assert(0); ret = qemu_file_get_error(f); } if (ret < 0) { @@ -739,28 +646,18 @@ static int fdl_vmstate_load_state(state_reallocation_t* self, QEMUFile *f, const field++; } - /* fix me */ + /* FIXME */ ret = fdl_vmstate_subsection_load(self, f, vmsd, opaque); - //ret = fdl_vmstate_subsection_load(f, vmsd, opaque, opaque_ptr); if (ret != 0) { return ret; } - /* - if(alloc_later){ - add_opaque_block(obj, opaque, total_size); - } - */ - - //printf("------\n"); - if (vmsd->post_load) { #ifdef VERBOSE_DEBUG printf("\tPOSTLOAD Function\n"); #endif add_post_fptr(self, vmsd->post_load, version_id, opaque, vmsd->name); - //ret = 0; ret = vmsd->post_load(opaque, version_id); } #ifdef VERBOSE_DEBUG @@ -772,24 +669,17 @@ static int fdl_vmstate_load_state(state_reallocation_t* self, QEMUFile *f, const static int fdl_vmstate_load(state_reallocation_t* self, QEMUFile *f, SaveStateEntry *se, int version_id) { - //trace_vmstate_load(se->idstr, se->vmsd ? se->vmsd->name : "(old)"); if (!se->vmsd) { /* Old style */ - //fprintf(stderr, "\t<<>>\n"); return se->ops->load_state(f, se->opaque, version_id); } - //fprintf(stderr, "NEW Style\n"); - uintptr_t* t = (uintptr_t*)&(se->opaque); - //printf("------>\n"); - //printf("VMSD1: %s\n", (VMStateDescription *)(se->vmsd)->name); - - //printf("SE:\t%p %p %p %p\n", se, se->opaque, &(se->opaque) ,t); - return fdl_vmstate_load_state(self, f, se->vmsd, se->opaque, version_id, (uintptr_t*)t); + + uintptr_t *t = (uintptr_t *)&(se->opaque); + return fdl_vmstate_load_state(self, f, se->vmsd, se->opaque, version_id, (uintptr_t *)t); } static int fdl_enumerate_section(state_reallocation_t* self, QEMUFile *f, MigrationIncomingState *mis){ uint32_t instance_id, version_id, section_id; SaveStateEntry *se; - //LoadStateEntry *le = NULL; char idstr[256]; int ret; @@ -803,11 +693,8 @@ static int fdl_enumerate_section(state_reallocation_t* self, QEMUFile *f, Migrat instance_id = qemu_get_be32(f); version_id = qemu_get_be32(f); - //printf("%s %s %d\n", __func__, idstr, instance_id); - /* Find savevm section */ se = fdl_find_se(idstr, instance_id); - //printf("se %p\n", se); if (se == NULL) { printf("Unknown savevm section or instance '%s' %d", idstr, instance_id); return -EINVAL; @@ -818,15 +705,6 @@ static int fdl_enumerate_section(state_reallocation_t* self, QEMUFile *f, Migrat printf("savevm: unsupported version %d for '%s' v%d", version_id, idstr, se->version_id); return -EINVAL; } - /* Add entry */ - /* - le = g_malloc0(sizeof(*le)); - le->se = se; - //printf("\tSE:%s\n", se); - le->section_id = section_id; - le->version_id = version_id; - QLIST_INSERT_HEAD(&mis->loadvm_handlers, le, entry); - */ se->load_version_id = version_id; se->load_section_id = section_id; @@ -878,12 +756,9 @@ static int fdl_enumerate_section(state_reallocation_t* self, QEMUFile *f, Migrat } else{ nyx_debug("---------------------------------\nVMSD2: %p\n", (void*)se->vmsd); - //abort(); - //fprintf(stderr, "---------------------------------\nVMSD2: %s\n", (VMStateDescription *)(se->vmsd)->name); ret = vmstate_load(f, se); } - //ret = vmstate_load(f, se); if (ret < 0) { printf("error while loading state for instance 0x%x of device '%s'", instance_id, idstr); return ret; @@ -915,9 +790,6 @@ static void fdl_enumerate_global_states(state_reallocation_t* self, QEMUFile *f) switch (section_type) { case QEMU_VM_SECTION_START: case QEMU_VM_SECTION_FULL: - //if(!fpos){ - // fpos = qemu_ftell(f); - //} fdl_enumerate_section(self, f, mis); break; default: @@ -971,15 +843,7 @@ state_reallocation_t* state_reallocation_new(QEMUFile *f){ return self; } -/* -void state_reallocation_new_no_fdl(QEMUFile *f){ - fdl_enumerate_global_states(NULL, f); -} -*/ - void fdl_fast_reload(state_reallocation_t* self){ - //uint64_t count = 0; - for(uint32_t i = 0; i < self->fast_state_fptr_pos; i++){ if((self->version[i]) == 1337){ @@ -989,14 +853,11 @@ void fdl_fast_reload(state_reallocation_t* self){ if(!self->tmp_snapshot.enabled){ for(uint32_t i = 0; i < self->fast_state_pos; i++){ - //count += self->size[i]; memcpy(self->ptr[i], self->copy[i], self->size[i]); } } else{ - //fprintf(stderr, "====== %s TMP MODE ====== \n", __func__); for(uint32_t i = 0; i < self->fast_state_pos; i++){ - //count += self->size[i]; memcpy(self->ptr[i], self->tmp_snapshot.copy[i], self->size[i]); } } diff --git a/nyx/snapshot/devices/state_reallocation.h b/nyx/snapshot/devices/state_reallocation.h index 539ff49095..dc53ee8cdc 100644 --- a/nyx/snapshot/devices/state_reallocation.h +++ b/nyx/snapshot/devices/state_reallocation.h @@ -19,17 +19,12 @@ along with QEMU-PT. If not, see . */ -#ifndef STATE_REALLOCATION -#define STATE_REALLOCATION - +#pragma once #include "qemu/osdep.h" #include "monitor/monitor.h" -//#include "qemu-common.h" #include "migration/migration.h" #include "nyx/khash.h" - - #define IO_BUF_SIZE 32768 struct QEMUFile_tmp { @@ -40,10 +35,9 @@ struct QEMUFile_tmp { int64_t bytes_xfer; int64_t xfer_limit; - int64_t pos; /* start of buffer when writing, end of buffer - when reading */ + int64_t pos; // buffer start on write, end on read volatile int buf_index; - int buf_size; /* 0 when writing */ + int buf_size; // 0 when writing uint8_t buf[IO_BUF_SIZE]; }; @@ -88,8 +82,6 @@ typedef struct state_reallocation_s{ size_t *get_size; void **get_data; - //QEMUFile** file; - uint32_t fast_state_get_fptr_size; uint32_t fast_state_get_fptr_pos; @@ -103,11 +95,8 @@ typedef struct state_reallocation_s{ state_reallocation_t* state_reallocation_new(QEMUFile *f); -//void fdl_enumerate_global_states(QEMUFile *f); void fdl_fast_reload(state_reallocation_t* self); void fdl_fast_create_tmp(state_reallocation_t* self); void fdl_fast_enable_tmp(state_reallocation_t* self); void fdl_fast_disable_tmp(state_reallocation_t* self); - -#endif \ No newline at end of file diff --git a/nyx/snapshot/devices/vm_change_state_handlers.c b/nyx/snapshot/devices/vm_change_state_handlers.c index 87de854da1..40dcdaeb1a 100644 --- a/nyx/snapshot/devices/vm_change_state_handlers.c +++ b/nyx/snapshot/devices/vm_change_state_handlers.c @@ -2,7 +2,6 @@ #include #include "qemu/osdep.h" #include "sysemu/sysemu.h" -#include "cpu.h" #include "qemu/main-loop.h" #include "nyx/snapshot/devices/vm_change_state_handlers.h" @@ -26,7 +25,8 @@ void call_fast_change_handlers(void){ change_cpu_handler(change_cpu_opaque, 1, RUN_STATE_RUNNING); return; - /* check if necessary */ + + /* TODO: check if necessary */ if(change_ide_core_handler){ for(uint8_t i = 0; i < change_ide_core_opaque_num; i++){ change_ide_core_handler(change_ide_core_opaque[i], 1, RUN_STATE_RUNNING); diff --git a/nyx/snapshot/helper.h b/nyx/snapshot/helper.h index 870291b2f0..cb5b7340b0 100644 --- a/nyx/snapshot/helper.h +++ b/nyx/snapshot/helper.h @@ -2,11 +2,8 @@ #include -/* don't! */ -#define MAX_REGIONS 8 - #ifndef PAGE_SIZE -#define PAGE_SIZE 0x1000 +#define PAGE_SIZE qemu_real_host_page_size #endif #define BITMAP_SIZE(x) ((x/PAGE_SIZE)/8) diff --git a/nyx/snapshot/memory/backend/nyx_debug.c b/nyx/snapshot/memory/backend/nyx_debug.c index 224bff27c7..3d7efbffc2 100644 --- a/nyx/snapshot/memory/backend/nyx_debug.c +++ b/nyx/snapshot/memory/backend/nyx_debug.c @@ -1,6 +1,5 @@ #include "qemu/osdep.h" #include "sysemu/sysemu.h" -#include "cpu.h" #include "qemu/main-loop.h" #include "exec/ram_addr.h" diff --git a/nyx/snapshot/memory/backend/nyx_debug.h b/nyx/snapshot/memory/backend/nyx_debug.h index 653d4ee1a0..676deb7690 100644 --- a/nyx/snapshot/memory/backend/nyx_debug.h +++ b/nyx/snapshot/memory/backend/nyx_debug.h @@ -1,5 +1,6 @@ #pragma once +#include #include "nyx/fast_vm_reload.h" void nyx_snapshot_debug_pre_init(void); diff --git a/nyx/snapshot/memory/backend/nyx_dirty_ring.c b/nyx/snapshot/memory/backend/nyx_dirty_ring.c index 296d7b47a1..920eabb674 100644 --- a/nyx/snapshot/memory/backend/nyx_dirty_ring.c +++ b/nyx/snapshot/memory/backend/nyx_dirty_ring.c @@ -1,10 +1,13 @@ + +#include "qemu/osdep.h" +#include + #include "nyx/snapshot/memory/backend/nyx_dirty_ring.h" #include "nyx/snapshot/helper.h" #include "sysemu/kvm.h" #include "sysemu/kvm_int.h" -#include #include #define FAST_IN_RANGE(address, start, end) (address < end && address >= start) @@ -221,7 +224,7 @@ nyx_dirty_ring_t* nyx_dirty_ring_init(shadow_memory_t* shadow_memory){ } } - /* +#ifdef DEBUG__PRINT_DIRTY_RING for(int i = 0; i < self->kvm_region_slots_num; i++){ printf("[%d].enabled = %d\n", i, self->kvm_region_slots[i].enabled); printf("[%d].bitmap = %p\n", i, self->kvm_region_slots[i].bitmap); @@ -236,7 +239,7 @@ nyx_dirty_ring_t* nyx_dirty_ring_init(shadow_memory_t* shadow_memory){ printf("[%d].region_offset = -\n", i); } } - */ +#endif dirty_ring_flush(kvm_get_vm_fd(kvm_state)); return self; @@ -318,20 +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)]; - - 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; - - if((perf_counter%1000) == 0){ - fprintf(stderr, "perf_counter -> %d\n", perf_counter); //, self->test_total, self->test); - } - - perf_counter++; -*/ - dirty_ring_flush_and_collect(self, shadow_memory_state, blocklist, kvm_get_vm_fd(kvm_state)); return restore_memory(self, shadow_memory_state, blocklist); } @@ -342,11 +332,6 @@ void nyx_snapshot_nyx_dirty_ring_save_root_pages(nyx_dirty_ring_t* self, shadow_ save_root_pages(self, shadow_memory_state, blocklist); } -/* enable operation */ - -/* restore operation */ - - void nyx_snapshot_nyx_dirty_ring_flush(void){ dirty_ring_flush(kvm_get_vm_fd(kvm_state)); } diff --git a/nyx/snapshot/memory/backend/nyx_dirty_ring.h b/nyx/snapshot/memory/backend/nyx_dirty_ring.h index fa9fab40a3..431cf0e611 100644 --- a/nyx/snapshot/memory/backend/nyx_dirty_ring.h +++ b/nyx/snapshot/memory/backend/nyx_dirty_ring.h @@ -1,5 +1,6 @@ #pragma once +#include #include "nyx/snapshot/memory/block_list.h" #include "nyx/snapshot/memory/shadow_memory.h" @@ -37,7 +38,9 @@ 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); 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); + void nyx_snapshot_nyx_dirty_ring_flush_and_collect(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist); diff --git a/nyx/snapshot/memory/backend/nyx_fdl.c b/nyx/snapshot/memory/backend/nyx_fdl.c index 31649a3348..b048fa020c 100644 --- a/nyx/snapshot/memory/backend/nyx_fdl.c +++ b/nyx/snapshot/memory/backend/nyx_fdl.c @@ -1,6 +1,5 @@ #include "qemu/osdep.h" #include "sysemu/sysemu.h" -#include "cpu.h" #include "qemu/main-loop.h" #include "exec/ram_addr.h" @@ -29,7 +28,8 @@ nyx_fdl_t* nyx_fdl_init(shadow_memory_t* shadow_memory){ static bool fdl_created = false; - assert(fdl_created == false); /* not sure if we're able to create another FDL instance -> probably not */ + /* not sure if we're able to create another FDL instance -> probably not */ + assert(fdl_created == false); fdl_created = true; nyx_fdl_t* self = malloc(sizeof(nyx_fdl_t)); @@ -45,11 +45,10 @@ nyx_fdl_t* nyx_fdl_init(shadow_memory_t* shadow_memory){ self->vmx_fdl_fd = kvm_vm_ioctl(kvm_state, KVM_VMX_FDL_SETUP_FD, (unsigned long)0); configuration.num = 0; - //memset(&self->fdl_data2, 0, sizeof(struct fdl_data_t2)); for(uint8_t i = 0; i < shadow_memory->ram_regions_num; i++){ - configuration.areas[configuration.num].base_address = shadow_memory->ram_regions[i].base; // block->mr->addr; - configuration.areas[configuration.num].size = shadow_memory->ram_regions[i].size; //MEM_SPLIT_START; //block->used_length; + configuration.areas[configuration.num].base_address = shadow_memory->ram_regions[i].base; + configuration.areas[configuration.num].size = shadow_memory->ram_regions[i].size; configuration.num++; } @@ -95,10 +94,8 @@ nyx_fdl_t* nyx_fdl_init(shadow_memory_t* shadow_memory){ return self; } -#define MEMSET_BITMAP - -#ifdef MEMSET_BITMAP -static uint32_t nyx_snapshot_nyx_fdl_restore_new(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){ +/* restore operation */ +uint32_t nyx_snapshot_nyx_fdl_restore(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; @@ -153,135 +150,12 @@ static uint32_t nyx_snapshot_nyx_fdl_restore_new(nyx_fdl_t* self, shadow_memory_ return num_dirty_pages; } -#endif - -/* restore operation */ -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 - return nyx_snapshot_nyx_fdl_restore_new(self, shadow_memory_state, blocklist); -#else - return nyx_snapshot_nyx_fdl_restore_old(self, shadow_memory_state, blocklist); -#endif - -} - -/* -void nyx_snapshot_nyx_fdl_restore(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){ - - void* current_region = NULL; - - struct fdl_result result; - memset(&result, 0, sizeof(struct fdl_result)); - int res = ioctl(self->vmx_fdl_fd, KVM_VMX_FDL_GET_INDEX, &result); - assert(!res); - - //nyx_snapshot_nyx_fdl_unset_blocklisted_pages(self, shadow_memory_state, blocklist); - - - for(uint8_t i = 0; i < result.num; i++){ -#ifdef SHOW_NUM_DIRTY_PAGES - printf("Kernel -> [%d] %ld \t%ldKB\n", i, result.values[i], (0x1000*result.values[i])>>0x10); -#endif - - if(shadow_memory_state->tmp_snapshot.enabled){ - current_region = shadow_memory_state->ram_regions[i].incremental_region_ptr; - } - else{ - current_region = shadow_memory_state->ram_regions[i].snapshot_region_ptr; - } - - for(uint64_t j = 0; j < result.values[i]; j++){ - - uint64_t physical_addr = self->fdl_data2.entry[i].fdl_stack[j]; - uint64_t entry_offset_addr = physical_addr - shadow_memory_state->ram_regions[i].base; - - void* host_addr = shadow_memory_state->ram_regions[i].host_region_ptr + entry_offset_addr; - void* snapshot_addr = current_region + entry_offset_addr; - - - // optimize this - if(test_and_clear_bit((long)(entry_offset_addr>>12), (unsigned long*)self->fdl_data2.entry[i].fdl_bitmap) == 0 && snapshot_page_blocklist_check_phys_addr(blocklist, physical_addr) == true){ -#ifdef DEBUG_VERFIY_BITMAP - if(!is_black_listed_addr(self, entry_offset_addr)){ - printf("WARNING: %s: -> %lx is not blacklisted\n", __func__, entry_offset_addr); - abort(); - } -#endif - printf("SKIP\n"); - continue; // blacklisted page - } - - memcpy(host_addr, snapshot_addr, TARGET_PAGE_SIZE); - } - } -#ifdef RESET_VRAM - //nyx_snapshot_nyx_fdl_restore_vram(self, shadow_memory_state); -#endif -} -*/ - -/* -void nyx_snapshot_nyx_fdl_restore2(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){ - nyx_snapshot_nyx_fdl_unset_blocklisted_pages(self, shadow_memory_state, blocklist); - - struct fdl_result result; - memset(&result, 0, sizeof(struct fdl_result)); - int res = ioctl(self->vmx_fdl_fd, KVM_VMX_FDL_GET_INDEX, &result); - assert(!res); - - - for(uint8_t i = 0; i < result.num; i++){ -#ifdef SHOW_NUM_DIRTY_PAGES - printf("Kernel -> [%d] %ld \t%ldKB\n", i, result.values[i], (0x1000*result.values[i])>>0x10); -#endif - for(uint64_t j = 0; j < result.values[i]; j++){ - uint64_t addr = self->fdl_data2.entry[i].fdl_stack[j]; - uint64_t offset_addr = addr - self->shadow_memory_state[i].base; - - - if(test_and_clear_bit((long)(offset_addr>>12), (unsigned long*)self->fdl_data2.entry[i].fdl_bitmap) == 0){ -#ifdef DEBUG_VERFIY_BITMAP - if(!is_black_listed_addr(self, offset_addr)){ - printf("WARNING: %s: -> %lx is not blacklisted\n", __func__, offset_addr); - abort(); - } -#endif - continue; // blacklisted page - } - - //assert(test_and_clear_bit(offset_addr>>12, fdl_data2.entry[i].fdl_bitmap)); - //fdl_data2.entry[i].fdl_bitmap[(offset_addr/0x1000)/8] = 0; - - //printf("DIRTY -> 0x%lx [BITMAP: %d] [%d]\n", addr, fdl_data2.entry[i].fdl_bitmap[(offset_addr/0x1000)/8], test_bit(offset_addr>>12, fdl_data2.entry[i].fdl_bitmap)); - - - if(shadow_memory_state->incremental_enabled){ - //memcpy((void*)(fdl_data2.entry[i].host_ptr+offset_addr), (void*)(self->tmp_snapshot.shadow_memory[i]+offset_addr), TARGET_PAGE_SIZE); - memcpy((void*)(self->fdl_data2.entry[i].host_ptr+offset_addr), (void*)(self->fdl_data2.entry[i].tmp_shadow_ptr+offset_addr), TARGET_PAGE_SIZE); - } - else{ - memcpy((void*)(self->fdl_data2.entry[i].host_ptr+offset_addr), (void*)(self->fdl_data2.entry[i].shadow_ptr+offset_addr), TARGET_PAGE_SIZE); - } - } - } -#ifdef RESET_VRAM - //nyx_snapshot_nyx_fdl_restore_vram(self, shadow_memory_state); -#endif -} -*/ - - - void nyx_snapshot_nyx_fdl_save_root_pages(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){ struct fdl_result result; memset(&result, 0, sizeof(struct fdl_result)); int res = ioctl(self->vmx_fdl_fd, KVM_VMX_FDL_GET_INDEX, &result); assert(!res); - //nyx_snapshot_nyx_fdl_unset_blocklisted_pages(self, shadow_memory_state, blocklist); - for(uint8_t i = 0; i < result.num; i++){ #ifdef SHOW_NUM_DIRTY_PAGES printf("Kernel -> [%d] %ld \t%ldKB\n", i, result.values[i], (0x1000*result.values[i])>>0x10); @@ -294,7 +168,6 @@ void nyx_snapshot_nyx_fdl_save_root_pages(nyx_fdl_t* self, shadow_memory_t* shad void* host_addr = shadow_memory_state->ram_regions[i].host_region_ptr + entry_offset_addr; void* incremental_addr = shadow_memory_state->ram_regions[i].incremental_region_ptr + entry_offset_addr; - //void* snapshot_addr = shadow_memory_state->ram_regions[i].snapshot_region_ptr + entry_offset_addr; if(snapshot_page_blocklist_check_phys_addr(blocklist, physical_addr) == true){ #ifdef DEBUG_VERFIY_BITMAP @@ -303,10 +176,8 @@ void nyx_snapshot_nyx_fdl_save_root_pages(nyx_fdl_t* self, shadow_memory_t* shad abort(); } #endif - //printf("SKIP\n"); - continue; // blacklisted page + continue; // skip blacklisted page } - //printf("%s -> %p <-- %p\n", __func__, incremental_addr, host_addr); clear_bit(entry_offset_addr>>12, (void*)self->entry[i].bitmap); shadow_memory_track_dirty_root_pages(shadow_memory_state, entry_offset_addr, i); diff --git a/nyx/snapshot/memory/backend/nyx_fdl.h b/nyx/snapshot/memory/backend/nyx_fdl.h index be81fdcc5c..3346c3e465 100644 --- a/nyx/snapshot/memory/backend/nyx_fdl.h +++ b/nyx/snapshot/memory/backend/nyx_fdl.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "nyx/snapshot/memory/block_list.h" #include "nyx/snapshot/memory/shadow_memory.h" diff --git a/nyx/snapshot/memory/block_list.c b/nyx/snapshot/memory/block_list.c index 669c76a4a4..448b65e922 100644 --- a/nyx/snapshot/memory/block_list.c +++ b/nyx/snapshot/memory/block_list.c @@ -1,6 +1,5 @@ #include "qemu/osdep.h" #include "sysemu/sysemu.h" -#include "cpu.h" #include "qemu/main-loop.h" #include "exec/ram_addr.h" @@ -23,12 +22,8 @@ snapshot_page_blocklist_t* snapshot_page_blocklist_init(void){ snapshot_page_blocklist_t* self = malloc(sizeof(snapshot_page_blocklist_t)); uint64_t ram_size = get_ram_size(); - //printf("%s: ram_size: 0x%lx\n", __func__, ram_size); - self->phys_area_size = ram_size <= MEM_SPLIT_START ? ram_size : ram_size + (MEM_SPLIT_END-MEM_SPLIT_START); - //printf("%s: phys_area_size: 0x%lx\n", __func__, self->phys_area_size); - self->phys_bitmap = malloc(BITMAP_SIZE(self->phys_area_size)); memset(self->phys_bitmap, 0x0, BITMAP_SIZE(self->phys_area_size)); diff --git a/nyx/snapshot/memory/block_list.h b/nyx/snapshot/memory/block_list.h index ad4de1bd72..acc7e30577 100644 --- a/nyx/snapshot/memory/block_list.h +++ b/nyx/snapshot/memory/block_list.h @@ -22,9 +22,6 @@ typedef struct snapshot_page_blocklist_s{ uint64_t phys_area_size; }snapshot_page_blocklist_t; - -//snapshot_page_blocklist_t* snapshot_page_blocklist_init(shadow_memory_t* snapshot); - void snapshot_page_blocklist_add(snapshot_page_blocklist_t* self, uint64_t phys_addr); /* returns true if phys_addr is on the blocklis */ diff --git a/nyx/snapshot/memory/nyx_fdl_user.c b/nyx/snapshot/memory/nyx_fdl_user.c index db6aee78c8..68ee0af228 100644 --- a/nyx/snapshot/memory/nyx_fdl_user.c +++ b/nyx/snapshot/memory/nyx_fdl_user.c @@ -1,10 +1,8 @@ #include "qemu/osdep.h" #include "sysemu/sysemu.h" -#include "target/i386/cpu.h" #include "qemu/main-loop.h" #include "exec/ram_addr.h" -#include "qemu/rcu_queue.h" #include "migration/migration.h" #include "nyx/memory_access.h" @@ -32,7 +30,6 @@ nyx_fdl_user_t* nyx_fdl_user_init(shadow_memory_t* shadow_memory_state){ self->entry[i].stack = malloc(DIRTY_STACK_SIZE(shadow_memory_state->ram_regions[i].size)); self->entry[i].bitmap = malloc(BITMAP_SIZE(shadow_memory_state->ram_regions[i].size)); } - //printf("%s -> %p\n", __func__, self); return self; } @@ -132,8 +129,6 @@ void nyx_fdl_user_set(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state break; } - //ram_area = FAST_IN_RANGE(addr, fdl_data2.entry[0].base, fdl_data2.entry[0].base+(fdl_data2.entry[0].size-1)) ? 0 : ram_area; - if(ram_area == 0xff){ printf("ERROR: %s %lx [%d]\n", __func__, addr, ram_area); abort(); @@ -149,7 +144,7 @@ void nyx_fdl_user_set(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state assert(self->entry[ram_area].bitmap); - /* todo -> better handling of nyx_fdl_state */ + /* TODO -> better handling of nyx_fdl_state */ if(!test_bit(pfn, (const unsigned long*)self->entry[ram_area].bitmap)){ set_bit(pfn, (unsigned long*)self->entry[ram_area].bitmap); @@ -185,7 +180,6 @@ void nyx_snapshot_nyx_fdl_user_save_root_pages(nyx_fdl_user_t* self, shadow_memo #ifdef DEBUG_USER_FDL printf("%s -> %p <-- %p\n", __func__, incremental_addr, host_addr); #endif - //printf("%s -> %p <-- %p\n", __func__, incremental_addr, host_addr); clear_bit(entry_offset_addr>>12, (void*)self->entry[i].bitmap); shadow_memory_track_dirty_root_pages(shadow_memory_state, entry_offset_addr, i); diff --git a/nyx/snapshot/memory/nyx_fdl_user.h b/nyx/snapshot/memory/nyx_fdl_user.h index 391a879aef..c59eba1055 100644 --- a/nyx/snapshot/memory/nyx_fdl_user.h +++ b/nyx/snapshot/memory/nyx_fdl_user.h @@ -6,6 +6,8 @@ #include "nyx/snapshot/memory/shadow_memory.h" #include "nyx/snapshot/memory/backend/nyx_fdl.h" +#define MAX_REGIONS 8 /* don't */ + typedef struct nyx_fdl_user_s{ struct { uint64_t* stack; @@ -18,8 +20,11 @@ typedef struct nyx_fdl_user_s{ }nyx_fdl_user_t; 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); 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 d43c1736fb..a3dfca402c 100644 --- a/nyx/snapshot/memory/shadow_memory.c +++ b/nyx/snapshot/memory/shadow_memory.c @@ -1,7 +1,6 @@ #include "qemu/osdep.h" #include "sysemu/sysemu.h" -#include "cpu.h" #include "qemu/main-loop.h" #include "exec/ram_addr.h" @@ -62,8 +61,6 @@ shadow_memory_t* shadow_memory_init(void){ assert(!ftruncate(self->snapshot_ptr_fd, self->memory_size)); fcntl(self->snapshot_ptr_fd, F_ADD_SEALS, F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL); - //printf("MMAP -> 0x%lx\n", self->memory_size); - self->snapshot_ptr = mmap(NULL, self->memory_size, PROT_READ | PROT_WRITE , MAP_SHARED , self->snapshot_ptr_fd, 0); madvise(self->snapshot_ptr, self->memory_size, MADV_RANDOM | MADV_MERGEABLE); @@ -76,8 +73,6 @@ shadow_memory_t* shadow_memory_init(void){ uint8_t regions_num = 0; QLIST_FOREACH_RCU(block, &ram_list.blocks, next) { nyx_debug_p(RELOAD_PREFIX, "%lx %lx %lx\t%s\t%p", block->offset, block->used_length, block->max_length, block->idstr, block->host); - //printf("%lx %lx %lx\t%s\t%p\n", block->offset, block->used_length, block->max_length, block->idstr, block->host); - block_array[i] = block; memcpy(self->snapshot_ptr+offset, block->host, block->used_length); @@ -108,7 +103,6 @@ shadow_memory_t* shadow_memory_init(void){ self->ram_regions[self->ram_regions_num].size = block->used_length-MEM_SPLIT_START; self->ram_regions[self->ram_regions_num].offset = (snapshot_ptr_offset_array[i] + MEM_SPLIT_START) - snapshot_ptr_offset_array[0]; self->ram_regions[self->ram_regions_num].host_region_ptr = block->host+MEM_SPLIT_START; - //self->ram_regions[self->ram_regions_num].snapshot_region_ptr = self->ptr+self->ram_regions[self->ram_regions_num].offset; self->ram_regions[self->ram_regions_num].snapshot_region_ptr = snapshot_ptr_offset_array[i]+MEM_SPLIT_START; self->ram_regions[self->ram_regions_num].idstr = malloc(strlen(block->idstr) + 1); memset(self->ram_regions[self->ram_regions_num].idstr, 0, strlen(block->idstr) + 1); @@ -169,9 +163,7 @@ shadow_memory_t* shadow_memory_init_from_snapshot(const char* snapshot_folder, b FILE* file_mem_meta = fopen (path_meta, "r"); assert(file_mem_meta != NULL); - assert(fread(&head, sizeof(fast_reload_dump_head_t), 1, file_mem_meta) == 1); - fclose(file_mem_meta); if(self->ram_regions_num != head.shadow_memory_regions){ @@ -202,13 +194,10 @@ shadow_memory_t* shadow_memory_init_from_snapshot(const char* snapshot_folder, b } assert(self->memory_size == ftell(file_mem_dump)); fseek(file_mem_dump, 0L, SEEK_SET); - fclose(file_mem_dump); self->snapshot_ptr_fd = open(path_dump, O_RDONLY); - //printf("self->snapshot_ptr_fd: %d\n", self->snapshot_ptr_fd); self->snapshot_ptr = mmap(0, self->memory_size, PROT_READ, MAP_SHARED, self->snapshot_ptr_fd, 0); - //printf("TRY TO MMAP : %p\n", self->snapshot_ptr); assert(self->snapshot_ptr != (void*)-1); madvise(self->snapshot_ptr, self->memory_size, MADV_MERGEABLE); @@ -219,7 +208,6 @@ shadow_memory_t* shadow_memory_init_from_snapshot(const char* snapshot_folder, b uint8_t regions_num = 0; QLIST_FOREACH_RCU(block, &ram_list.blocks, next) { nyx_debug_p(RELOAD_PREFIX, "%lx %lx %lx\t%s\t%p", block->offset, block->used_length, block->max_length, block->idstr, block->host); - //printf("%lx %lx %lx\t%s\t%p\n", block->offset, block->used_length, block->max_length, block->idstr, block->host); block_array[i] = block; snapshot_ptr_offset_array[i++] = self->snapshot_ptr+offset; @@ -250,7 +238,6 @@ shadow_memory_t* shadow_memory_init_from_snapshot(const char* snapshot_folder, b self->ram_regions[self->ram_regions_num].size = block->used_length-MEM_SPLIT_START; self->ram_regions[self->ram_regions_num].offset = (snapshot_ptr_offset_array[i] + MEM_SPLIT_START) - snapshot_ptr_offset_array[0]; self->ram_regions[self->ram_regions_num].host_region_ptr = block->host+MEM_SPLIT_START; - //self->ram_regions[self->ram_regions_num].snapshot_region_ptr = self->ptr+self->ram_regions[self->ram_regions_num].offset; self->ram_regions[self->ram_regions_num].snapshot_region_ptr = snapshot_ptr_offset_array[i]+MEM_SPLIT_START; self->ram_regions[self->ram_regions_num].idstr = malloc(strlen(block->idstr) + 1); memset(self->ram_regions[self->ram_regions_num].idstr, 0, strlen(block->idstr) + 1); @@ -272,21 +259,21 @@ shadow_memory_t* shadow_memory_init_from_snapshot(const char* snapshot_folder, b } } +#ifdef DEBUG_SHADOW_MEMCPY_VERSION /* memcpy version */ - /* for(uint8_t i = 0; i < self->ram_regions_num; i++){ void* host_addr = self->ram_regions[i].host_region_ptr + 0; void* snapshot_addr = self->ram_regions[i].snapshot_region_ptr + 0; memcpy(host_addr, snapshot_addr, self->ram_regions[i].size); } - */ - +#else /* munmap + mmap version */ for(uint8_t i = 0; i < self->ram_regions_num; i++){ void* host_addr = self->ram_regions[i].host_region_ptr + 0; assert(munmap(host_addr, self->ram_regions[i].size) != EINVAL); assert(mmap(host_addr, self->ram_regions[i].size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_FIXED, self->snapshot_ptr_fd, self->ram_regions[i].offset) != MAP_FAILED); } +#endif shadow_memory_init_generic(self); return self; @@ -348,31 +335,6 @@ void shadow_memory_serialize(shadow_memory_t* self, const char* snapshot_folder) FILE* file_mem_meta = fopen(tmp1, "w+b"); FILE* file_mem_data = fopen(tmp2, "w+b"); - //} FILE* file_ptr_meta, FILE* file_ptr_data){ - - //assert(self); - //assert(file_ptr_meta); - //assert(file_ptr_data); - /* - nyx_debug("black_list_pages_num: %lx\n", self->black_list_pages_num); - nyx_debug("black_list_pages_size: %lx\n", self->black_list_pages_size); - nyx_debug("black_list_pages ...\n"); - for (uint64_t i = 0; i < self->black_list_pages_num; i++ ){ - nyx_debug("self->black_list_pages[%ld] = %lx\n", i, self->black_list_pages[i]); - } - */ - - //printf("shadow_memory_regions: %d\n", self->ram_regions_num); - //nyx_debug("ram_region_index: %d\n", self->ram_region_index); - - /* - for (uint32_t i = 0; i < self->ram_regions_num; i++){ - printf("self->shadow_memory[%d] = %lx %s\n", i, self->ram_regions[i].base, self->ram_regions[i].idstr); - } - - printf("ram_size: %lx\n", self->memory_size); - */ - fast_reload_dump_head_t head; fast_reload_dump_entry_t entry; diff --git a/nyx/snapshot/memory/shadow_memory.h b/nyx/snapshot/memory/shadow_memory.h index f4f3e718cf..a71626b62c 100644 --- a/nyx/snapshot/memory/shadow_memory.h +++ b/nyx/snapshot/memory/shadow_memory.h @@ -73,8 +73,6 @@ void shadow_memory_switch_snapshot(shadow_memory_t* self, bool incremental); void shadow_memory_restore_memory(shadow_memory_t* self); -//void shadow_memory_prepare_incremental_snapshot(shadow_memory_t* self); - static inline void shadow_memory_track_dirty_root_pages(shadow_memory_t* self, uint64_t address, uint8_t slot){ if(unlikely(self->root_track_pages_num >= self->root_track_pages_size)){ self->root_track_pages_size <<= 2; diff --git a/nyx/state/snapshot_state.c b/nyx/state/snapshot_state.c index f084302c0c..8d61960aa3 100644 --- a/nyx/state/snapshot_state.c +++ b/nyx/state/snapshot_state.c @@ -6,6 +6,7 @@ #include "nyx/state/state.h" #include "nyx/memory_access.h" #include +#include void serialize_state(const char* filename_prefix, bool is_pre_snapshot){ nyx_trace(); @@ -80,7 +81,6 @@ void deserialize_state(const char* filename_prefix){ if(fp == NULL) { nyx_debug("[%s] Could not open file %s.\n", __func__, tmp); assert(false); - //exit(EXIT_FAILURE); } diff --git a/nyx/state/state.c b/nyx/state/state.c index 4c2a1315f0..22680898e3 100644 --- a/nyx/state/state.c +++ b/nyx/state/state.c @@ -19,6 +19,11 @@ along with QEMU-PT. If not, see . */ +#include "qemu/osdep.h" + +#include +#include + #include "nyx/state/state.h" #include "nyx/debug.h" #include "nyx/memory_access.h" @@ -177,9 +182,6 @@ void enable_fast_reloads(void){ 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 - nyx_debug("\n\nINIT PAGE_CACHE => %s\n", path); - #endif } page_cache_t* get_page_cache(void){ @@ -201,8 +203,10 @@ 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); + nyx_debug_p(INTERFACE_PREFIX, "new aux buffer file: (max size: %x) %lx", AUX_BUFFER_SIZE, st.st_size); assert(AUX_BUFFER_SIZE == st.st_size); diff --git a/nyx/synchronization.c b/nyx/synchronization.c index 676bb83c82..e5c23df787 100644 --- a/nyx/synchronization.c +++ b/nyx/synchronization.c @@ -4,7 +4,6 @@ #include "nyx/fast_vm_reload.h" #include "qemu-common.h" #include "qemu/osdep.h" -#include "target/i386/cpu.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" #include "nyx/debug.h" @@ -28,6 +27,7 @@ volatile bool synchronization_kvm_loop_waiting = false; /* SIGALRM based timeout detection */ //#define DEBUG_TIMEOUT_DETECTOR + void init_timeout_detector(timeout_detector_t* timer){ timer->kvm_tid = 0; timer->detection_enabled = false; @@ -100,7 +100,6 @@ void arm_sigprof_timer(timeout_detector_t* timer){ fprintf(stderr, "Attempting to re-arm an expired timer! => reset(%ld.%ld)\n", timer->config.tv_sec, timer->config.tv_usec); reset_timeout_detector(timer); - //return true; } assert(setitimer(ITIMER_REAL, &timer->alarm, NULL) == 0); } @@ -145,7 +144,6 @@ void unblock_signals(void){ sigaddset(&set, SIGSEGV); sigaddset(&set, SIGALRM); sigprocmask(SIG_UNBLOCK, &set, NULL); - //fprintf(stderr, "%s!\n", __func__); } /* -------------------- */ @@ -191,7 +189,6 @@ void synchronization_unlock(void){ pthread_mutex_lock(&synchronization_lock_mutex); pthread_cond_signal(&synchronization_lock_condition); - //hypercall_reset_hprintf_counter(); pthread_mutex_unlock(&synchronization_lock_mutex); } @@ -199,8 +196,6 @@ void synchronization_unlock(void){ uint64_t run_counter = 0; bool in_fuzzing_loop = false; -//bool last_timeout = false; - void synchronization_lock_hprintf(void){ pthread_mutex_lock(&synchronization_lock_mutex); interface_send_char(NYX_INTERFACE_PING); @@ -243,8 +238,6 @@ void synchronization_lock(void){ kvm_vcpu_ioctl(qemu_get_cpu(0), KVM_VMX_PT_DISABLE_PAGE_DUMP_CR3); } - //last_timeout = false; - if(unlikely(GET_GLOBAL_STATE()->in_redqueen_reload_mode)) { fsync_redqueen_files(); } @@ -260,20 +253,12 @@ void synchronization_lock(void){ 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); if (GET_GLOBAL_STATE()->starved == true) set_success_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, 2); else set_success_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, 1); GET_GLOBAL_STATE()->pt_trace_size = 0; - /* - if(GET_GLOBAL_STATE()->dump_page){ - fprintf(stderr, "DISABLING TIMEOUT DETECTION\n"); - disable_timeout_detector(&(GET_GLOBAL_STATE()->timeout_detector)); - } - */ - } static void perform_reload(void){ @@ -303,8 +288,6 @@ void synchronization_lock_crash_found(void){ perform_reload(); - //synchronization_lock(); - in_fuzzing_loop = false; } @@ -322,8 +305,6 @@ void synchronization_lock_asan_found(void){ perform_reload(); - //synchronization_lock(); - in_fuzzing_loop = false; } @@ -360,7 +341,6 @@ void synchronization_lock_shutdown_detected(void){ perform_reload(); in_fuzzing_loop = false; - //synchronization_lock(); } void synchronization_payload_buffer_write_detected(void){ @@ -381,7 +361,6 @@ void synchronization_payload_buffer_write_detected(void){ perform_reload(); in_fuzzing_loop = false; - //synchronization_lock(); } void synchronization_cow_full_detected(void){ @@ -396,20 +375,13 @@ void synchronization_cow_full_detected(void){ perform_reload(); in_fuzzing_loop = false; - //synchronization_lock(); } void synchronization_disable_pt(CPUState *cpu){ - //fprintf(stderr, "==============> %s\n", __func__); + // nyx_trace(); 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); - /* - qemu_backtrace(); - while(1){ - - } - */ } pt_disable(qemu_get_cpu(0), false); @@ -423,9 +395,6 @@ void synchronization_disable_pt(CPUState *cpu){ set_result_pt_trace_size(GET_GLOBAL_STATE()->auxilary_buffer, GET_GLOBAL_STATE()->pt_trace_size); set_result_bb_coverage(GET_GLOBAL_STATE()->auxilary_buffer, GET_GLOBAL_STATE()->bb_coverage); - - - in_fuzzing_loop = false; } diff --git a/nyx/synchronization.h b/nyx/synchronization.h index 204cb6c080..bbae0407bc 100644 --- a/nyx/synchronization.h +++ b/nyx/synchronization.h @@ -1,7 +1,9 @@ #pragma once #include "qemu/osdep.h" -#include + +#include +#include typedef struct timeout_detector_s { int kvm_tid; diff --git a/nyx/trace_dump.c b/nyx/trace_dump.c index f325377441..1dfc731011 100644 --- a/nyx/trace_dump.c +++ b/nyx/trace_dump.c @@ -1,10 +1,13 @@ +#include "qemu/osdep.h" + #include #include #include #include -#include "state/state.h" -#include "trace_dump.h" +#include "nyx/debug.h" +#include "nyx/state/state.h" +#include "nyx/trace_dump.h" /* dump PT trace as returned from HW */ @@ -21,7 +24,7 @@ void pt_trace_dump_init(char* filename) { int test_fd; - //fprintf(stderr, "Enable pt trace dump at %s", filename); + nyx_debug("Enable pt trace dump at %s", filename); pt_dump_initialized = true; test_fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644); @@ -55,7 +58,6 @@ void pt_write_pt_dump_file(uint8_t *data, size_t bytes) return; fd = open(pt_trace_dump_filename, O_APPEND|O_WRONLY, 0644); - //fd = open(pt_trace_dump_filename, O_CREAT|O_TRUNC|O_WRONLY, 0644); if (fd < 0) { fprintf(stderr, "Error writing pt_trace_dump to %s: %s\n", pt_trace_dump_filename, strerror(errno)); assert(0); diff --git a/nyx/trace_dump.h b/nyx/trace_dump.h index fb3235f34b..110550e06d 100644 --- a/nyx/trace_dump.h +++ b/nyx/trace_dump.h @@ -1,5 +1,7 @@ #pragma once +#include + void pt_trace_dump_init(char* filename); void pt_trace_dump_enable(bool enable); void pt_write_pt_dump_file(uint8_t *data, size_t bytes);