From dd9f586327578ee24603584d6fb584a2150856c7 Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Tue, 11 Jan 2022 04:16:34 +0100 Subject: [PATCH] disable unused hypercalls --- accel/kvm/kvm-all.c | 2 +- nyx/hypercall/debug.c | 112 ++++++++++++++++++++ nyx/hypercall/debug.h | 3 + nyx/hypercall/hypercall.c | 216 ++------------------------------------ nyx/printk.c | 2 +- nyx/pt.c | 70 ------------ nyx/pt.h | 1 - nyx/synchronization.c | 14 +-- 8 files changed, 131 insertions(+), 289 deletions(-) create mode 100644 nyx/hypercall/debug.c create mode 100644 nyx/hypercall/debug.h diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 6d500226b7..59d32d2ef1 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -46,7 +46,7 @@ #ifdef QEMU_NYX #include "nyx/pt.h" -#include "nyx/hypercall.h" +#include "nyx/hypercall/hypercall.h" #include "nyx/synchronization.h" #include "nyx/debug.h" #include "nyx/state.h" diff --git a/nyx/hypercall/debug.c b/nyx/hypercall/debug.c new file mode 100644 index 0000000000..a146f58258 --- /dev/null +++ b/nyx/hypercall/debug.c @@ -0,0 +1,112 @@ +#include "qemu/osdep.h" +#include +#include "nyx/synchronization.h" +#include "nyx/fast_vm_reload.h" +#include "nyx/state.h" +#include "nyx/hypercall/debug.h" + +//#define NYX_ENABLE_DEBUG_HYPERCALLS + +#ifdef NYX_ENABLE_DEBUG_HYPERCALLS + +static double get_time(void){ + struct timeval t; + struct timezone tzp; + gettimeofday(&t, &tzp); + return t.tv_sec + t.tv_usec*1e-6; +} + +static void print_time_diff(int iterations){ + + static bool init = true; + static double start_time = 0.0; + static double end_time = 0.0; + + if(init){ + init = false; + printf("start time is zero!\n"); + start_time = get_time(); + } + else{ + end_time = get_time(); + double elapsed_time = end_time - start_time; + printf("Done in %f seconds\n", elapsed_time); + printf("Performance: %f\n", iterations/elapsed_time); + start_time = get_time(); + } +} + +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)){ + request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_ROOT); + } + 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); + } + request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_LOAD_SNAPSHOT_ROOT); + meassure_performance(); + break; + case 3: /* load tmp snapshot */ + if(fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_TMP_EXISTS)){ + request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_LOAD_SNAPSHOT_TMP); + meassure_performance(); + } + break; + case 5: // firefox debug hypercall + if(first){ + first = false; + request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_ROOT); + //request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_TMP); + + break; + } + else{ + 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 +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...")); + synchronization_lock(); +} +#endif \ No newline at end of file diff --git a/nyx/hypercall/debug.h b/nyx/hypercall/debug.h new file mode 100644 index 0000000000..3c8b4aa9f6 --- /dev/null +++ b/nyx/hypercall/debug.h @@ -0,0 +1,3 @@ +#pragma once + +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 23f263836f..79eaa1c0ae 100644 --- a/nyx/hypercall/hypercall.c +++ b/nyx/hypercall/hypercall.c @@ -56,6 +56,7 @@ along with QEMU-PT. If not, see . #include "nyx/redqueen.h" #include "nyx/hypercall/configuration.h" +#include "nyx/hypercall/debug.h" //#define DEBUG_HPRINTF @@ -65,7 +66,6 @@ bool notifiers_enabled = false; bool hypercall_enabled = false; void* program_buffer = NULL; -char info_buffer[INFO_SIZE]; char hprintf_buffer[HPRINTF_SIZE]; static bool init_state = true; @@ -322,47 +322,9 @@ static void handle_hypercall_kafl_range_submit(struct kvm_run *run, CPUState *cp } static void handle_hypercall_get_program(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - - //fprintf(stderr, "%s\n", __func__); - /* - return; - - if(!get_fast_reload_snapshot()->qemu_state){ - fast_reload_create_in_memory(get_fast_reload_snapshot(), true); - } - */ -/* - qemu_mutex_lock_iothread(); - fast_reload_restore(get_fast_reload_snapshot()); - - qemu_mutex_unlock_iothread(); - return; - */ - kvm_arch_get_registers(cpu); - X86CPU *x86_cpu = X86_CPU(cpu); - CPUX86State *env = &x86_cpu->env; - - if(hypercall_enabled){ - if(program_buffer){ - - if (env->cr[4] & CR4_PAE_MASK) { - if (env->hflags & HF_LMA_MASK) { - //fprintf(stderr, "IN 64Bit MODE\n"); - } - else{ - debug_fprintf(stderr, "IN 32Bit PAE MODE\n"); - abort(); - } - } - else{ - debug_fprintf(stderr, "IN 32Bit MODE\n"); - abort(); - } - - //print_48_paging2(env->cr[3]); - write_virtual_memory(hypercall_arg, program_buffer, PROGRAM_SIZE, cpu); - } - } + fprintf(stderr, "[QEMU-Nyx] Error: This hypercall (HYPERCALL_KAFL_GET_PAYLOAD) is deprecated -> use ./hget instead!\n"); + set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, (char*)"Deprecated hypercall called...", strlen("Deprecated hypercall called...")); + synchronization_lock(); } @@ -546,100 +508,6 @@ static void handle_hypercall_kafl_panic(struct kvm_run *run, CPUState *cpu, uint } } -static double get_time(void){ - struct timeval t; - struct timezone tzp; - gettimeofday(&t, &tzp); - return t.tv_sec + t.tv_usec*1e-6; -} - -static void print_time_diff(int iterations){ - - static bool init = true; - static double start_time = 0.0; - static double end_time = 0.0; - - if(init){ - init = false; - printf("start time is zero!\n"); - start_time = get_time(); - } - else{ - end_time = get_time(); - double elapsed_time = end_time - start_time; - printf("Done in %f seconds\n", elapsed_time); - printf("Performance: %f\n", iterations/elapsed_time); - start_time = get_time(); - } -} - -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++; -} -static 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)){ - request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_ROOT); - } - 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); - } - request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_LOAD_SNAPSHOT_ROOT); - //meassure_performance(); - break; - case 3: /* load tmp snapshot */ - if(fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_TMP_EXISTS)){ - request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_LOAD_SNAPSHOT_TMP); - //meassure_performance(); - } - break; - case 5: // firefox debug hypercall - if(first){ - first = false; - request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_ROOT); - //request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_TMP); - - break; - } - else{ - 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(); - } -} - 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; @@ -647,7 +515,6 @@ static void handle_hypercall_kafl_create_tmp_snapshot(struct kvm_run *run, CPUSt /* decode PT data */ pt_disable(qemu_get_cpu(0), false); - pt_sync(); /* kvm_arch_get_registers(cpu); @@ -764,84 +631,23 @@ qemu_mutex_lock_iothread(); } static void handle_hypercall_kafl_info(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - if(setup_snapshot_once) - return; - - debug_printf("%s\n", __func__); -/* - printf("[*] EXEC: %s\t%lx %lx\n", __func__, get_rip(cpu), get_rsp(cpu)); - hexdump_virtual_memory(get_rsp(cpu), 0x100, cpu); - - kvm_arch_get_registers(cpu); - kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE); -*/ - /* - qemu_mutex_lock_iothread(); - //fast_reload_restore((fast_reload_t*)cpu->fast_reload_snapshot); - fast_reload_restore(get_fast_reload_snapshot()); - //kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE); - qemu_mutex_unlock_iothread(); - return; - */ -/* - kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE); - - - printf("[*] EXIT: %s\t%lx %lx\n", __func__, get_rip(cpu), get_rsp(cpu)); - hexdump_virtual_memory(get_rsp(cpu), 0x100, cpu); -*/ -// return; - - read_virtual_memory(hypercall_arg, (uint8_t*)info_buffer, INFO_SIZE, cpu); - FILE* info_file_fd = fopen(INFO_FILE, "w"); - fprintf(info_file_fd, "%s\n", info_buffer); - fclose(info_file_fd); - if(hypercall_enabled){ - //hypercall_snd_char(KAFL_PROTO_INFO); - QEMU_PT_PRINTF_DEBUG("Protocol - SEND: KAFL_PROTO_INFO"); - abort(); - - } - qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); + fprintf(stderr, "[QEMU-Nyx] Error: This hypercall (HYPERCALL_KAFL_INFO) is deprecated -> use hprintf() & ./habort instead!\n"); + set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, (char*)"Deprecated hypercall called...", strlen("Deprecated hypercall called...")); + synchronization_lock(); } void enable_notifies(void){ notifiers_enabled = true; } - -/* -void hprintf(char* msg){ - char file_name[256]; - if(!(hprintf_counter >= HPRINTF_LIMIT) && GET_GLOBAL_STATE()->enable_hprintf){ - if(hypercall_enabled){ - snprintf(file_name, 256, "%s.%d", HPRINTF_FILE, hprintf_counter); - //printf("%s: %s\n", __func__, msg); - FILE* printf_file_fd = fopen(file_name, "w"); - fprintf(printf_file_fd, "%s", msg); - fclose(printf_file_fd); - //hypercall_snd_char(KAFL_PROTO_PRINTF); - QEMU_PT_PRINTF_DEBUG("Protocol - SEND: KAFL_PROTO_PRINTF"); - - } - hprintf_counter++; - - } -} -*/ - static void handle_hypercall_kafl_printf(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){ - //fprintf(stderr, "%s\n", __func__); - //if( /* !(hprintf_counter >= HPRINTF_LIMIT) && */ GET_GLOBAL_STATE()->enable_hprintf){ // && !GET_GLOBAL_STATE()->in_fuzzing_mode){ - read_virtual_memory(hypercall_arg, (uint8_t*)hprintf_buffer, HPRINTF_SIZE, cpu); - //hprintf(hprintf_buffer); + read_virtual_memory(hypercall_arg, (uint8_t*)hprintf_buffer, HPRINTF_SIZE, cpu); #ifdef DEBUG_HPRINTF - fprintf(stderr, "%s %s\n", __func__, hprintf_buffer); + fprintf(stderr, "%s %s\n", __func__, hprintf_buffer); #else - set_hprintf_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, hprintf_buffer, strnlen(hprintf_buffer, HPRINTF_SIZE)+1); - synchronization_lock(); + set_hprintf_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, hprintf_buffer, strnlen(hprintf_buffer, HPRINTF_SIZE)+1); + synchronization_lock(); #endif - //} } diff --git a/nyx/printk.c b/nyx/printk.c index c27ebab902..7f0256ed18 100644 --- a/nyx/printk.c +++ b/nyx/printk.c @@ -2,7 +2,7 @@ #include #include "qemu-common.h" #include "nyx/memory_access.h" -#include "nyx/hypercall.h" +#include "nyx/hypercall/hypercall.h" #include "nyx/printk.h" enum reg_types{RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15, RIP}; diff --git a/nyx/pt.c b/nyx/pt.c index e18d8656d4..66a07eb899 100644 --- a/nyx/pt.c +++ b/nyx/pt.c @@ -44,11 +44,6 @@ along with QEMU-PT. If not, see . #define PT_BUFFER_MMAP_ADDR 0x3ffff0000000 -/* -extern uint32_t kafl_bitmap_size; -uint8_t* bitmap = NULL; -*/ - uint32_t state_byte = 0; uint32_t last = 0; @@ -69,14 +64,6 @@ void pt_trucate_pt_trace_file(void){ } } -void pt_sync(void){ - /* - if(bitmap){ - msync(bitmap, kafl_bitmap_size, MS_SYNC); - } - */ -} - static void pt_set(CPUState *cpu, run_on_cpu_data arg){ asm volatile("" ::: "memory"); } @@ -111,59 +98,12 @@ static inline int pt_ioctl(int fd, unsigned long request, unsigned long arg){ return ioctl(fd, request, arg); } -/* -void pt_setup_bitmap(void* ptr){ - bitmap = (uint8_t*)ptr; -} - -void pt_reset_bitmap(void){ - if(bitmap){ - state_byte = 0; - last = 0; - memset(bitmap, 0x00, kafl_bitmap_size); - } -} -*/ - static inline uint64_t mix_bits(uint64_t v) { v ^= (v >> 31); v *= 0x7fb5d329728ea185; - /* - v ^= (v >> 27); - v *= 0x81dadef4bc2dd44d; - v ^= (v >> 33); - */ return v; } -/* -void pt_bitmap(uint64_t from, uint64_t to){ - - //if(to == 0x400965 || (last == 0x400965 && to == 0x40087A)){ - // last = to; - // state_byte = mix_bits(state_byte)^to; - // bitmap[state_byte & (kafl_bitmap_size-1)]++; - //} - - //printf("from: %lx\tto: %lx\n", from, to); - - uint32_t transition_value = 0; - #ifdef SAMPLE_DECODED - sample_decoded(from,to); - #endif - if(bitmap){ - transition_value = mix_bits(to)^(mix_bits(from)>>1); - // - //if ((from == 0x7ffff7884e8f && to == 0x7ffff7884eff) || (from == 0x7ffff7884f10 && to == 0x7ffff7884f12) || (from == 0x7ffff7884f14 && to == 0x7ffff7884e80)){ - // return; - //} - //fprintf(stderr, "%lx %lx %x\n", from, to, check_bitmap_byte(transition_value & (kafl_bitmap_size-1))); - if (check_bitmap_byte(transition_value & (kafl_bitmap_size-1)) == 0) - bitmap[transition_value & (kafl_bitmap_size-1)]++; - } -} -*/ - #ifdef DUMP_AND_DEBUG_PT void dump_pt_trace(void* buffer, int bytes){ static FILE* f = NULL; @@ -497,13 +437,3 @@ void pt_post_kvm_run(CPUState *cpu){ //} } } - -/* -void pt_sync_kvm_run_lock(void){ - pthread_mutex_lock(&pt_dump_mutex); -} - -void pt_sync_kvm_run_unlock(void){ - pthread_mutex_unlock(&pt_dump_mutex); -} -*/ diff --git a/nyx/pt.h b/nyx/pt.h index 9badf1d96e..51b360c45a 100644 --- a/nyx/pt.h +++ b/nyx/pt.h @@ -24,7 +24,6 @@ along with QEMU-PT. If not, see . void pt_init_decoder(CPUState *cpu); -void pt_sync(void); void pt_reset_bitmap(void); void pt_setup_bitmap(void* ptr); diff --git a/nyx/synchronization.c b/nyx/synchronization.c index 4f7a12cb40..c3d1423117 100644 --- a/nyx/synchronization.c +++ b/nyx/synchronization.c @@ -1,5 +1,5 @@ #include "nyx/synchronization.h" -#include "nyx/hypercall.h" +#include "nyx/hypercall/hypercall.h" #include "nyx/interface.h" #include "nyx/fast_vm_reload.h" #include "qemu-common.h" @@ -237,7 +237,7 @@ bool in_fuzzing_loop = false; void synchronization_lock_hprintf(void){ pthread_mutex_lock(&synchronization_lock_mutex); - interface_send_char(KAFL_PING); + interface_send_char(NYX_INTERFACE_PING); pthread_cond_wait(&synchronization_lock_condition, &synchronization_lock_mutex); pthread_mutex_unlock(&synchronization_lock_mutex); @@ -286,8 +286,7 @@ void synchronization_lock(void){ fsync_all_traces(); } - interface_send_char(KAFL_PING); - //QEMU_PT_PRINTF_DEBUG("Protocol - SEND: KAFL_PING"); + interface_send_char(NYX_INTERFACE_PING); pthread_cond_wait(&synchronization_lock_condition, &synchronization_lock_mutex); pthread_mutex_unlock(&synchronization_lock_mutex); @@ -326,7 +325,6 @@ void synchronization_lock_crash_found(void){ } pt_disable(qemu_get_cpu(0), false); - pt_sync(); handle_tmp_snapshot_state(); @@ -346,7 +344,6 @@ void synchronization_lock_asan_found(void){ } pt_disable(qemu_get_cpu(0), false); - pt_sync(); handle_tmp_snapshot_state(); @@ -369,7 +366,6 @@ void synchronization_lock_timeout_found(void){ } pt_disable(qemu_get_cpu(0), false); - pt_sync(); handle_tmp_snapshot_state(); @@ -388,7 +384,6 @@ void synchronization_lock_shutdown_detected(void){ } pt_disable(qemu_get_cpu(0), false); - pt_sync(); handle_tmp_snapshot_state(); @@ -406,7 +401,6 @@ void synchronization_payload_buffer_write_detected(void){ } pt_disable(qemu_get_cpu(0), false); - pt_sync(); handle_tmp_snapshot_state(); @@ -426,7 +420,6 @@ void synchronization_cow_full_detected(void){ } pt_disable(qemu_get_cpu(0), false); - pt_sync(); handle_tmp_snapshot_state(); @@ -450,7 +443,6 @@ void synchronization_disable_pt(CPUState *cpu){ } pt_disable(qemu_get_cpu(0), false); - pt_sync(); handle_tmp_snapshot_state();