add several improvements:

- Intel PT page dump feature works now
- size of input and bitmap buffers are configurable
- new aux buffer layout
- various bug fixes
This commit is contained in:
Sergej Schumilo 2022-01-18 10:10:04 +01:00
parent 646c85021e
commit 42d434e28f
47 changed files with 731 additions and 924 deletions

View File

@ -49,7 +49,7 @@
#include "nyx/hypercall/hypercall.h"
#include "nyx/synchronization.h"
#include "nyx/debug.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "nyx/interface.h"
#include "nyx/fast_vm_reload_sync.h"
#include "nyx/snapshot/memory/backend/nyx_dirty_ring.h"
@ -2866,11 +2866,6 @@ int kvm_device_access(int fd, int group, uint64_t attr,
return err;
}
#ifdef QEMU_NYX
int kvm_has_vapic(void){
return !kvm_check_extension(kvm_state, KVM_CAP_VAPIC);
}
#endif
bool kvm_has_sync_mmu(void)
{

View File

@ -35,7 +35,7 @@
#include "qemu/error-report.h"
#include "trace.h"
#ifdef QEMU_NYX
#include "nyx/state.h"
#include "nyx/state/state.h"
#endif
//#define DEBUG_SERIAL

View File

@ -36,7 +36,7 @@
#include "migration/vmstate.h"
#ifdef QEMU_NYX
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "nyx/fast_vm_reload.h"
#endif

View File

@ -3,10 +3,9 @@ memory_access.o \
interface.o \
fast_vm_reload.o \
fast_vm_reload_sync.o \
printk.o synchronization.o \
synchronization.o \
page_cache.o \
kvm_nested.o \
state.o \
debug.o \
auxiliary_buffer.o \
mmh3.o \
@ -31,5 +30,7 @@ snapshot/memory/backend/nyx_dirty_ring.o \
hypercall/hypercall.o \
hypercall/configuration.o \
hypercall/debug.o \
state/state.o \
state/snapshot_state.o \
pt.o

View File

@ -23,7 +23,7 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "nyx/debug.h"
/* experimental feature (currently broken)
@ -161,15 +161,11 @@ void check_auxiliary_config_buffer(auxilary_buffer_t* auxilary_buffer, auxilary_
}
void set_crash_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer){
VOLATILE_WRITE_8(auxilary_buffer->result.crash_found, 1);
}
void set_asan_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer){
VOLATILE_WRITE_8(auxilary_buffer->result.asan_found, 1);
VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_crash);
}
void set_timeout_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer){
VOLATILE_WRITE_8(auxilary_buffer->result.timeout_found, 1);
VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_timeout);
}
void set_reload_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer){
@ -180,65 +176,32 @@ void set_pt_overflow_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer)
VOLATILE_WRITE_8(auxilary_buffer->result.pt_overflow, 1);
}
void set_exec_done_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t sec, uint32_t usec){
void set_exec_done_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t sec, uint32_t usec, uint32_t num_dirty_pages){
VOLATILE_WRITE_8(auxilary_buffer->result.exec_done, 1);
VOLATILE_WRITE_8(auxilary_buffer->result.runtime_sec, sec);
VOLATILE_WRITE_32(auxilary_buffer->result.runtime_sec, sec);
VOLATILE_WRITE_32(auxilary_buffer->result.runtime_usec, usec);
VOLATILE_WRITE_32(auxilary_buffer->result.dirty_pages, num_dirty_pages);
}
void flush_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer){
memset(&auxilary_buffer->result.hprintf, 0x0, sizeof(auxilary_buffer_result_t)-2);
//memset(&(auxilary_buffer->result) + offsetof(auxilary_buffer_result_t, hprintf), 0x0, sizeof(auxilary_buffer_result_t) - offsetof(auxilary_buffer_result_t, hprintf));
/*
VOLATILE_WRITE_8(auxilary_buffer->result.exec_done, 0);
VOLATILE_WRITE_8(auxilary_buffer->result.hprintf, 0);
VOLATILE_WRITE_8(auxilary_buffer->result.crash_found, 0);
VOLATILE_WRITE_8(auxilary_buffer->result.asan_found, 0);
VOLATILE_WRITE_8(auxilary_buffer->result.timeout_found, 0);
VOLATILE_WRITE_8(auxilary_buffer->result.reloaded, 0);
VOLATILE_WRITE_8(auxilary_buffer->result.pt_overflow, 0);
VOLATILE_WRITE_8(auxilary_buffer->result.runtime_sec, 0);
VOLATILE_WRITE_32(auxilary_buffer->result.runtime_usec, 0);
VOLATILE_WRITE_8(auxilary_buffer->result.page_not_found, 0);
VOLATILE_WRITE_64(auxilary_buffer->result.page_addr, 0);
VOLATILE_WRITE_8(auxilary_buffer->result.payload_buffer_write_attempt_found, 0);
VOLATILE_WRITE_32(auxilary_buffer->result.dirty_pages, 0);
VOLATILE_WRITE_32(auxilary_buffer->result.pt_trace_size, 0);
*/
}
void set_hprintf_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len){
VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, MISC_SIZE-2));
volatile_memcpy((void*)&auxilary_buffer->misc.data, (void*)msg, (size_t)MIN(len, MISC_SIZE-2));
VOLATILE_WRITE_8(auxilary_buffer->result.hprintf, 1);
VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_hprintf);
}
void set_crash_reason_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len){
VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, MISC_SIZE-2));
volatile_memcpy((void*)&auxilary_buffer->misc.data, (void*)msg, (size_t) MIN(len, MISC_SIZE-2));
VOLATILE_WRITE_8(auxilary_buffer->result.crash_found, 1);
VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_crash);
}
void set_abort_reason_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len){
VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, MISC_SIZE-2));
volatile_memcpy((void*)&auxilary_buffer->misc.data, (void*)msg, (size_t) MIN(len, MISC_SIZE-2));
VOLATILE_WRITE_8(auxilary_buffer->result.abort, 1);
}
void flush_hprintf_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer){
VOLATILE_WRITE_8(auxilary_buffer->result.hprintf, 0);
VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_aborted);
}
void set_state_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t state){
@ -255,14 +218,18 @@ void set_page_not_found_result_buffer(auxilary_buffer_t* auxilary_buffer, uint64
VOLATILE_WRITE_64(auxilary_buffer->result.page_addr, page_addr);
}
void reset_page_not_found_result_buffer(auxilary_buffer_t* auxilary_buffer){
VOLATILE_WRITE_8(auxilary_buffer->result.page_not_found, 0);
}
void set_success_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t success){
VOLATILE_WRITE_8(auxilary_buffer->result.success, success);
VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_success);
}
void set_payload_buffer_write_reason_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len){
VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, MISC_SIZE-2));
volatile_memcpy((void*)&auxilary_buffer->misc.data, (void*)msg, (size_t) MIN(len, MISC_SIZE-2));
VOLATILE_WRITE_8(auxilary_buffer->result.payload_buffer_write_attempt_found, 1);
VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_input_buffer_write);
}

View File

@ -37,6 +37,15 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#define ADD_PADDING(max, type) uint8_t type ## _padding [max - sizeof(type)]
enum nyx_result_codes {
rc_success = 0,
rc_crash = 1,
rc_hprintf = 2,
rc_timeout = 3,
rc_input_buffer_write = 4,
rc_aborted = 5,
};
typedef struct auxilary_buffer_header_s{
uint64_t magic; /* 0x54502d554d4551 */
uint16_t version;
@ -93,40 +102,21 @@ typedef struct auxilary_buffer_result_s{
3 -> ready to fuzz
*/
uint8_t state;
/* snapshot extension */
uint8_t tmp_snapshot_created;
/* FML */
uint8_t padding_1;
uint8_t padding_2;
uint32_t bb_coverage;
uint8_t padding_3;
uint8_t padding_4;
uint8_t hprintf;
uint8_t exec_done;
uint8_t crash_found;
uint8_t asan_found;
uint8_t timeout_found;
uint8_t exec_done;
uint8_t exec_result_code;
uint8_t reloaded;
uint8_t pt_overflow;
uint8_t runtime_sec;
uint8_t page_not_found;
uint8_t success;
uint8_t tmp_snapshot_created; /* incremental snapshot extension */
uint8_t padding_3;
uint32_t runtime_usec;
uint64_t page_addr;
uint32_t dirty_pages;
uint32_t pt_trace_size;
uint8_t payload_buffer_write_attempt_found;
uint8_t abort;
uint32_t pt_trace_size;
uint32_t bb_coverage;
uint32_t runtime_usec;
uint32_t runtime_sec;
/* more to come */
} __attribute__((packed)) auxilary_buffer_result_t;
@ -158,19 +148,16 @@ typedef struct auxilary_buffer_s{
void init_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer);
void check_auxiliary_config_buffer(auxilary_buffer_t* auxilary_buffer, auxilary_buffer_config_t* shadow_config);
void flush_hprintf_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer);
void set_crash_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_asan_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_timeout_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_reload_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_pt_overflow_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void flush_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_exec_done_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t sec, uint32_t usec);
void set_exec_done_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t sec, uint32_t usec, uint32_t num_dirty_pages);
void set_state_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t state);
void set_hprintf_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len);
void set_page_not_found_result_buffer(auxilary_buffer_t* auxilary_buffer, uint64_t page_addr);
void reset_page_not_found_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_success_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t success);
void set_crash_reason_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len);
void set_abort_reason_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len);

View File

@ -47,7 +47,8 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#include "nyx/fast_vm_reload.h"
#include "nyx/debug.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "nyx/state/snapshot_state.h"
#include "sysemu/block-backend.h"
#include "block/qapi.h"
@ -125,33 +126,36 @@ static void fast_snapshot_init_operation(fast_reload_t* self, const char* snapsh
static void fast_snapshot_restore_operation(fast_reload_t* self){
uint32_t num_dirty_pages = 0;
switch(mode){
case RELOAD_MEMORY_MODE_DEBUG:
nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, true);
num_dirty_pages += nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, true);
break;
case RELOAD_MEMORY_MODE_DEBUG_QUIET:
nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, false);
num_dirty_pages += nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, false);
break;
case RELOAD_MEMORY_MODE_FDL:
nyx_snapshot_nyx_fdl_restore(self->fdl_state, self->shadow_memory_state, self->blocklist);
num_dirty_pages += nyx_snapshot_nyx_fdl_restore(self->fdl_state, self->shadow_memory_state, self->blocklist);
break;
case RELOAD_MEMORY_MODE_FDL_DEBUG:
nyx_snapshot_nyx_fdl_restore(self->fdl_state, self->shadow_memory_state, self->blocklist);
nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, true);
num_dirty_pages += nyx_snapshot_nyx_fdl_restore(self->fdl_state, self->shadow_memory_state, self->blocklist);
num_dirty_pages += nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, true);
break;
case RELOAD_MEMORY_MODE_DIRTY_RING:
nyx_snapshot_nyx_dirty_ring_restore(self->dirty_ring_state, self->shadow_memory_state, self->blocklist);
num_dirty_pages += nyx_snapshot_nyx_dirty_ring_restore(self->dirty_ring_state, self->shadow_memory_state, self->blocklist);
break;
case RELOAD_MEMORY_MODE_DIRTY_RING_DEBUG:
nyx_snapshot_nyx_dirty_ring_restore(self->dirty_ring_state, self->shadow_memory_state, self->blocklist);
nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, true);
num_dirty_pages += nyx_snapshot_nyx_dirty_ring_restore(self->dirty_ring_state, self->shadow_memory_state, self->blocklist);
num_dirty_pages += nyx_snapshot_debug_restore(self->shadow_memory_state, self->blocklist, true);
//assert(false);
//sleep(1);
break;
}
nyx_snapshot_user_fdl_restore(self->fdl_user_state, self->shadow_memory_state, self->blocklist);
num_dirty_pages += nyx_snapshot_user_fdl_restore(self->fdl_user_state, self->shadow_memory_state, self->blocklist);
//nyx_device_state_post_restore(self->device_state);
GET_GLOBAL_STATE()->num_dirty_pages = num_dirty_pages;
}
static inline void fast_snapshot_pre_create_incremental_operation(fast_reload_t* self){
@ -279,7 +283,7 @@ inline static void wait_for_snapshot(const char* folder){
free(lock_file);
}
void fast_reload_serialize_to_file(fast_reload_t* self, const char* folder){
void fast_reload_serialize_to_file(fast_reload_t* self, const char* folder, bool is_pre_snapshot){
//printf("================ %s => %s =============\n", __func__, folder);
@ -299,7 +303,7 @@ void fast_reload_serialize_to_file(fast_reload_t* self, const char* folder){
nyx_block_snapshot_serialize(self->block_state, folder);
/* NYX's state */
dump_global_state(folder);
serialize_state(folder, is_pre_snapshot);
/* finalize snapshot */
unlock_snapshot(folder);
@ -332,7 +336,7 @@ static void fast_reload_create_from_snapshot(fast_reload_t* self, const char* fo
rcu_read_unlock();
if(!pre_snapshot){
load_global_state(folder);
deserialize_state(folder);
}
cpu_synchronize_all_post_init();
@ -480,10 +484,7 @@ void fast_reload_create_tmp_snapshot(fast_reload_t* self){
fast_snapshot_pre_create_incremental_operation(self);
if(!self->bitmap_copy){
if(GET_GLOBAL_STATE()->shared_bitmap_size+GET_GLOBAL_STATE()->shared_ijon_bitmap_size){
assert(GET_GLOBAL_STATE()->shared_bitmap_size+GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
self->bitmap_copy = malloc(GET_GLOBAL_STATE()->shared_bitmap_size+GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
}
self->bitmap_copy = new_coverage_bitmaps();
}
coverage_bitmap_copy_to_buffer(self->bitmap_copy);

View File

@ -35,6 +35,7 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#include "nyx/snapshot/block/nyx_block_snapshot.h"
#include "nyx/snapshot/memory/backend/nyx_dirty_ring.h"
#include "nyx/helpers.h"
typedef enum FastReloadMemoryMode {
@ -82,7 +83,7 @@ typedef struct fast_reload_s{
bool incremental_snapshot_enabled;
/* copy of the fuzzing bitmap & ijon state buffer */
void* bitmap_copy;
nyx_coverage_bitmap_copy_t* bitmap_copy;
@ -104,7 +105,7 @@ void fast_reload_create_from_file_pre_image(fast_reload_t* self, const char* fol
void fast_reload_create_in_memory(fast_reload_t* self);
void fast_reload_serialize_to_file(fast_reload_t* self, const char* folder);
void fast_reload_serialize_to_file(fast_reload_t* self, const char* folder, bool is_pre_snapshot);
void fast_reload_restore(fast_reload_t* self);

View File

@ -11,7 +11,7 @@
#include "sysemu/kvm_int.h"
#include "sysemu/kvm.h"
#include "sysemu/runstate.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "nyx/fast_vm_reload.h"
#include "nyx/debug.h"
#include "nyx/kvm_nested.h"
@ -127,7 +127,7 @@ static inline void create_root_snapshot(void){
debug_printf("===> GET_GLOBAL_STATE()->fast_reload_mode: FALSE\n");
/* store the current state as a snapshot folder */
fast_reload_create_in_memory(get_fast_reload_snapshot());
fast_reload_serialize_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_path);
fast_reload_serialize_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_path, false);
}
}
else{
@ -149,7 +149,7 @@ static inline void perform_task_no_block_mode(fast_vm_reload_sync_t* self, FastR
vm_stop(RUN_STATE_SAVE_VM);
//fast_reload_create_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_pre_path, true);
fast_reload_create_in_memory(get_fast_reload_snapshot());
fast_reload_serialize_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_pre_path);
fast_reload_serialize_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_pre_path, true);
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
qemu_mutex_unlock_iothread();
@ -218,7 +218,7 @@ static inline void perform_task_block_mode(fast_vm_reload_sync_t* self, FastRelo
vm_stop(RUN_STATE_SAVE_VM);
//fast_reload_create_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_pre_path, true);
fast_reload_create_in_memory(get_fast_reload_snapshot());
fast_reload_serialize_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_pre_path);
fast_reload_serialize_to_file(get_fast_reload_snapshot(), GET_GLOBAL_STATE()->fast_reload_pre_path, true);
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
return; /* return here to skip the vm_start call */
case REQUEST_SAVE_SNAPSHOT_ROOT_FIX_RIP:

View File

@ -10,9 +10,15 @@
#include "qemu/main-loop.h"
#include "sysemu/kvm_int.h"
#include "sysemu/kvm.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "nyx/memory_access.h"
#include "nyx/debug.h"
#include "nyx/helpers.h"
void nyx_abort(char* msg){
set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, msg, strlen(msg));
synchronization_lock();
}
uint64_t get_rip(CPUState *cpu){
kvm_arch_get_registers(cpu);
@ -33,26 +39,49 @@ int get_capstone_mode(int word_width_in_bits){
}
}
nyx_coverage_bitmap_copy_t* new_coverage_bitmaps(void){
nyx_coverage_bitmap_copy_t* bitmaps = malloc(sizeof(nyx_coverage_bitmap_copy_t));
memset(bitmaps, 0, sizeof(nyx_coverage_bitmap_copy_t));
assert(GET_GLOBAL_STATE()->shared_bitmap_size);
bitmaps->coverage_bitmap = malloc(GET_GLOBAL_STATE()->shared_bitmap_size);
assert(GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
bitmaps->ijon_bitmap_buffer = malloc(GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
return bitmaps;
}
void coverage_bitmap_reset(void){
if(GET_GLOBAL_STATE()->shared_bitmap_ptr){
//fprintf(stderr, "%s: %lx %lx\n", __func__, coverage_bitmap, coverage_bitmap_size);
memset(GET_GLOBAL_STATE()->shared_bitmap_ptr, 0x00, GET_GLOBAL_STATE()->shared_bitmap_size + GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
memset(GET_GLOBAL_STATE()->shared_bitmap_ptr, 0x00, GET_GLOBAL_STATE()->shared_bitmap_real_size);
}
if (GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr && GET_GLOBAL_STATE()->shared_ijon_bitmap_size){
memset(GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr, 0x00, GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
}
}
void coverage_bitmap_copy_to_buffer(void* buffer){
void coverage_bitmap_copy_to_buffer(nyx_coverage_bitmap_copy_t* buffer){
if(GET_GLOBAL_STATE()->shared_bitmap_ptr){
memcpy(buffer, GET_GLOBAL_STATE()->shared_bitmap_ptr, GET_GLOBAL_STATE()->shared_bitmap_size + GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
memcpy(buffer->coverage_bitmap, GET_GLOBAL_STATE()->shared_bitmap_ptr, GET_GLOBAL_STATE()->shared_bitmap_real_size);
}
if (GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr){
memcpy(buffer->ijon_bitmap_buffer, GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr, GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
}
}
void coverage_bitmap_copy_from_buffer(void* buffer){
void coverage_bitmap_copy_from_buffer(nyx_coverage_bitmap_copy_t* buffer){
if(GET_GLOBAL_STATE()->shared_bitmap_ptr){
memcpy(GET_GLOBAL_STATE()->shared_bitmap_ptr, buffer, GET_GLOBAL_STATE()->shared_bitmap_size + GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
memcpy(GET_GLOBAL_STATE()->shared_bitmap_ptr, buffer->coverage_bitmap, GET_GLOBAL_STATE()->shared_bitmap_real_size);
}
if (GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr){
memcpy(GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr, buffer->ijon_bitmap_buffer, GET_GLOBAL_STATE()->shared_ijon_bitmap_size);
}
}
void apply_capabilities(CPUState *cpu){
bool apply_capabilities(CPUState *cpu){
//X86CPU *cpux86 = X86_CPU(cpu);
//CPUX86State *env = &cpux86->env;
@ -74,7 +103,8 @@ void apply_capabilities(CPUState *cpu){
debug_printf("--------------------------\n");
if(GET_GLOBAL_STATE()->cap_compile_time_tracing_buffer_vaddr&0xfff){
fprintf(stderr, "[QEMU-Nyx] Warning: guest's trace bitmap v_addr (0x%lx) is not page aligned!\n", GET_GLOBAL_STATE()->cap_compile_time_tracing_buffer_vaddr);
fprintf(stderr, "[QEMU-Nyx] Error: guest's trace bitmap v_addr (0x%lx) is not page aligned!\n", GET_GLOBAL_STATE()->cap_compile_time_tracing_buffer_vaddr);
return false;
}
for(uint64_t i = 0; i < GET_GLOBAL_STATE()->shared_bitmap_size; i += 0x1000){
@ -84,18 +114,20 @@ void apply_capabilities(CPUState *cpu){
}
if(GET_GLOBAL_STATE()->cap_ijon_tracing){
debug_fprintf(stderr, "%s: agent trace buffer at vaddr: %lx\n", __func__, GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr);
debug_printf(stderr, "%s: agent trace buffer at vaddr: %lx\n", __func__, GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr);
if(GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr&0xfff){
fprintf(stderr, "[QEMU-Nyx] Warning: guest's ijon buffer v_addr (0x%lx) is not page aligned!\n", GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr);
fprintf(stderr, "[QEMU-Nyx] Error: guest's ijon buffer v_addr (0x%lx) is not page aligned!\n", GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr);
return false;
}
kvm_arch_get_registers_fast(cpu);
for(uint64_t i = 0; i < GET_GLOBAL_STATE()->shared_ijon_bitmap_size; i += 0x1000){
assert(remap_slot(GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr + i, (GET_GLOBAL_STATE()->shared_bitmap_size+i)/0x1000, cpu, GET_GLOBAL_STATE()->shared_bitmap_fd, GET_GLOBAL_STATE()->shared_bitmap_size+GET_GLOBAL_STATE()->shared_ijon_bitmap_size, true, GET_GLOBAL_STATE()->cap_cr3));
assert(remap_slot(GET_GLOBAL_STATE()->cap_ijon_tracing_buffer_vaddr + i, i/0x1000, cpu, GET_GLOBAL_STATE()->shared_ijon_bitmap_fd, GET_GLOBAL_STATE()->shared_ijon_bitmap_size+GET_GLOBAL_STATE()->shared_ijon_bitmap_size, true, GET_GLOBAL_STATE()->cap_cr3));
}
set_cap_agent_ijon_trace_bitmap(GET_GLOBAL_STATE()->auxilary_buffer, true);
}
return true;
}
bool folder_exits(const char* path){

View File

@ -3,13 +3,22 @@
#include "qemu/osdep.h"
uint64_t get_rip(CPUState *cpu);
typedef struct nyx_coverage_bitmap_copy_s{
void* coverage_bitmap;
void* ijon_bitmap_buffer;
}nyx_coverage_bitmap_copy_t;
void nyx_abort(char* msg);
nyx_coverage_bitmap_copy_t* new_coverage_bitmaps(void);
void coverage_bitmap_reset(void);
void coverage_bitmap_copy_to_buffer(void* buffer);
void coverage_bitmap_copy_from_buffer(void* buffer);
void coverage_bitmap_copy_to_buffer(nyx_coverage_bitmap_copy_t* buffer);
void coverage_bitmap_copy_from_buffer(nyx_coverage_bitmap_copy_t* buffer);
int get_capstone_mode(int word_width_in_bits);
void apply_capabilities(CPUState *cpu);
bool apply_capabilities(CPUState *cpu);
bool folder_exits(const char* path);
bool file_exits(const char* path);

View File

@ -1,7 +1,8 @@
#include "qemu/osdep.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "nyx/hypercall/configuration.h"
#include "nyx/memory_access.h"
#include "nyx/helpers.h"
void handle_hypercall_kafl_get_host_config(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
uint64_t vaddr = hypercall_arg;
@ -17,6 +18,20 @@ void handle_hypercall_kafl_get_host_config(struct kvm_run *run, CPUState *cpu, u
write_virtual_memory(vaddr, (uint8_t*)&config, sizeof(host_config_t), cpu);
}
static void resize_coverage_bitmap(uint32_t new_bitmap_size){
uint32_t new_bitmap_shm_size = new_bitmap_size;
if (new_bitmap_shm_size % 64 > 0) {
new_bitmap_shm_size = ((new_bitmap_shm_size + 64) >> 6) << 6;
}
GET_GLOBAL_STATE()->shared_bitmap_real_size = new_bitmap_shm_size;
resize_shared_memory(new_bitmap_shm_size, &GET_GLOBAL_STATE()->shared_bitmap_size, &GET_GLOBAL_STATE()->shared_bitmap_ptr, GET_GLOBAL_STATE()->shared_bitmap_fd);
/* pass the actual bitmap buffer size to the front-end */
GET_GLOBAL_STATE()->auxilary_buffer->capabilites.agent_coverage_bitmap_size = new_bitmap_size;
}
void handle_hypercall_kafl_set_agent_config(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
uint64_t vaddr = hypercall_arg;
agent_config_t config;
@ -60,12 +75,14 @@ void handle_hypercall_kafl_set_agent_config(struct kvm_run *run, CPUState *cpu,
if (config.coverage_bitmap_size){
resize_coverage_bitmap(config.coverage_bitmap_size);
}
if (config.input_buffer_size){
resize_payload_buffer(config.coverage_bitmap_size);
resize_payload_buffer(config.input_buffer_size);
}
apply_capabilities(cpu);
if(apply_capabilities(cpu) == false){
nyx_abort((char*)"applying agent configuration failed...");
}
if(getenv("DUMP_PAYLOAD_MODE")){
config.dump_payloads = 1;

View File

@ -2,7 +2,7 @@
#include <sys/time.h>
#include "nyx/synchronization.h"
#include "nyx/fast_vm_reload.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "nyx/hypercall/debug.h"
//#define NYX_ENABLE_DEBUG_HYPERCALLS

View File

@ -30,8 +30,6 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#include "sysemu/kvm_int.h"
#include "sysemu/runstate.h"
#include "sysemu/cpus.h"
#include "sysemu/kvm_int.h"
#include "sysemu/kvm.h"
#include "sysemu/cpus.h"
@ -43,12 +41,11 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#include "nyx/hypercall/hypercall.h"
#include "nyx/memory_access.h"
#include "nyx/interface.h"
#include "nyx/printk.h"
#include "nyx/debug.h"
#include "nyx/synchronization.h"
#include "nyx/fast_vm_reload.h"
#include "nyx/kvm_nested.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "sysemu/runstate.h"
#include "nyx/helpers.h"
#include "nyx/nested_hypercalls.h"
@ -59,8 +56,8 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#include "nyx/hypercall/debug.h"
//#define DEBUG_HPRINTF
#define HPRINTF_SIZE 0x1000
bool notifiers_enabled = false;
bool hypercall_enabled = false;
char hprintf_buffer[HPRINTF_SIZE];
@ -115,10 +112,10 @@ bool handle_hypercall_kafl_next_payload(struct kvm_run *run, CPUState *cpu, uint
//pt_reset_bitmap();
if (GET_GLOBAL_STATE()->pt_trace_mode){
fprintf(stderr, "[QEMU-Nyx] coverage mode: Intel-PT (KVM-Nyx and libxdc)\n");
printf("[QEMU-Nyx] coverage mode: Intel-PT (KVM-Nyx and libxdc)\n");
}
else{
fprintf(stderr, "[QEMU-Nyx] coverage mode: compile-time instrumentation\n");
printf("[QEMU-Nyx] coverage mode: compile-time instrumentation\n");
}
coverage_bitmap_reset();
@ -312,13 +309,6 @@ static void handle_hypercall_kafl_range_submit(struct kvm_run *run, CPUState *cp
}
static void handle_hypercall_get_program(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
fprintf(stderr, "[QEMU-Nyx] Error: This hypercall (HYPERCALL_KAFL_GET_PAYLOAD) is deprecated -> use ./hget instead!\n");
set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, (char*)"Deprecated hypercall called...", strlen("Deprecated hypercall called..."));
synchronization_lock();
}
static void release_print_once(CPUState *cpu){
if(release_print_once_bool){
release_print_once_bool = false;
@ -351,7 +341,7 @@ void handle_hypercall_kafl_mtf(struct kvm_run *run, CPUState *cpu, uint64_t hype
//assert(false);
kvm_arch_get_registers_fast(cpu);
debug_fprintf(stderr, "%s --> %lx\n", __func__, get_rip(cpu));
fprintf(stderr, "%s --> %lx\n", __func__, get_rip(cpu));
kvm_vcpu_ioctl(cpu, KVM_VMX_PT_DISABLE_MTF);
@ -417,18 +407,7 @@ static void handle_hypercall_kafl_cr3(struct kvm_run *run, CPUState *cpu, uint64
static void handle_hypercall_kafl_submit_panic(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
if(hypercall_enabled){
QEMU_PT_PRINTF(CORE_PREFIX, "Panic address:\t%lx", hypercall_arg);
if(notifiers_enabled){
write_virtual_memory(hypercall_arg, (uint8_t*)PANIC_PAYLOAD, PAYLOAD_BUFFER_SIZE, cpu);
}
}
}
static void handle_hypercall_kafl_submit_kasan(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
if(hypercall_enabled){
QEMU_PT_PRINTF(CORE_PREFIX, "kASAN address:\t%lx", hypercall_arg);
if(notifiers_enabled){
write_virtual_memory(hypercall_arg, (uint8_t*)KASAN_PAYLOAD, PAYLOAD_BUFFER_SIZE, cpu);
}
write_virtual_memory(hypercall_arg, (uint8_t*)PANIC_PAYLOAD, PAYLOAD_BUFFER_SIZE, cpu);
}
}
@ -475,9 +454,7 @@ static void handle_hypercall_kafl_panic(struct kvm_run *run, CPUState *cpu, uint
}
synchronization_lock_crash_found();
} else{
#define AGENT_HAS_CRASHED_REPORT "Agent has crashed before initializing the fuzzing loop..."
set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, (char*)AGENT_HAS_CRASHED_REPORT, strlen(AGENT_HAS_CRASHED_REPORT));
synchronization_lock();
nyx_abort((char*)"Agent has crashed before initializing the fuzzing loop...");
}
}
}
@ -541,61 +518,15 @@ static void handle_hypercall_kafl_panic_extended(struct kvm_run *run, CPUState *
read_virtual_memory(hypercall_arg, (uint8_t*)hprintf_buffer, HPRINTF_SIZE, cpu);
char* report = NULL;
assert(asprintf(&report, "Agent has crashed before initializing the fuzzing loop: %s", hprintf_buffer) != -1);
set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, report, strlen(report));
synchronization_lock();
nyx_abort(report);
}
}
static void handle_hypercall_kafl_kasan(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
if(hypercall_enabled){
#ifdef PANIC_DEBUG
if(hypercall_arg){
QEMU_PT_PRINTF(CORE_PREFIX, "ASan notification in user mode!");
} else{
QEMU_PT_PRINTF(CORE_PREFIX, "ASan notification in kernel mode!");
}
#endif
if(fast_reload_snapshot_exists(get_fast_reload_snapshot())){
synchronization_lock_asan_found();
//synchronization_stop_vm_kasan(cpu);
} else{
QEMU_PT_PRINTF(CORE_PREFIX, "KASAN detected during initialization of stage 1 or stage 2 loader");
//hypercall_snd_char(KAFL_PROTO_KASAN);
QEMU_PT_PRINTF_DEBUG("Protocol - SEND: KAFL_PROTO_KASAN");
}
}
}
/*
static uint64_t get_rsp(CPUState *cpu){
kvm_arch_get_registers(cpu);
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = &x86_cpu->env;
kvm_cpu_synchronize_state(cpu);
return env->regs[4];
}
*/
static void handle_hypercall_kafl_lock(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
if(!GET_GLOBAL_STATE()->fast_reload_pre_image){
QEMU_PT_PRINTF(CORE_PREFIX, "Skipping pre image creation (hint: set pre=on) ...");
return;
/*
fast_reload_create_in_memory(get_fast_reload_snapshot(), true);
qemu_mutex_lock_iothread();
fast_reload_restore(get_fast_reload_snapshot());
qemu_mutex_unlock_iothread();
*/
//return;
}
QEMU_PT_PRINTF(CORE_PREFIX, "Creating pre image snapshot <%s> ...", GET_GLOBAL_STATE()->fast_reload_pre_path);
@ -604,16 +535,6 @@ qemu_mutex_lock_iothread();
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_PRE);
}
static void handle_hypercall_kafl_info(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
fprintf(stderr, "[QEMU-Nyx] Error: This hypercall (HYPERCALL_KAFL_INFO) is deprecated -> use hprintf() & ./habort instead!\n");
set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, (char*)"Deprecated hypercall called...", strlen("Deprecated hypercall called..."));
synchronization_lock();
}
void enable_notifies(void){
notifiers_enabled = true;
}
static void handle_hypercall_kafl_printf(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
read_virtual_memory(hypercall_arg, (uint8_t*)hprintf_buffer, HPRINTF_SIZE, cpu);
#ifdef DEBUG_HPRINTF
@ -624,26 +545,6 @@ static void handle_hypercall_kafl_printf(struct kvm_run *run, CPUState *cpu, uin
#endif
}
static void handle_hypercall_kafl_printk(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
if(!notifiers_enabled){
if (hypercall_enabled && GET_GLOBAL_STATE()->enable_hprintf){
if(kafl_linux_printk(cpu)){
handle_hypercall_kafl_panic(run, cpu, (uint64_t)run->hypercall.args[0]);
}
}
}
}
static void handle_hypercall_kafl_printk_addr(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
if(!notifiers_enabled){
debug_printf("%s\n", __func__);
debug_printf("%lx\n", hypercall_arg);
write_virtual_memory(hypercall_arg, (uint8_t*)PRINTK_PAYLOAD, PRINTK_PAYLOAD_SIZE, cpu);
debug_printf("Done\n");
}
}
static void handle_hypercall_kafl_user_range_advise(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
kAFL_ranges* buf = malloc(sizeof(kAFL_ranges));
@ -831,9 +732,11 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall
ret = 0;
break;
case KVM_EXIT_KAFL_GET_PROGRAM:
//timeout_reload_pending = false;
//fprintf(stderr, "KVM_EXIT_KAFL_GET_PROGRAM\n");
handle_hypercall_get_program(run, cpu, arg);
nyx_abort((char*)"Deprecated hypercall called (HYPERCALL_KAFL_GET_PROGRAM)...");
ret = 0;
break;
case KVM_EXIT_KAFL_GET_ARGV:
nyx_abort((char*)"Deprecated hypercall called (HYPERCALL_KAFL_GET_ARGV)...");
ret = 0;
break;
case KVM_EXIT_KAFL_RELEASE:
@ -855,9 +758,7 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall
ret = 0;
break;
case KVM_EXIT_KAFL_SUBMIT_KASAN:
//timeout_reload_pending = false;
//fprintf(stderr, "KVM_EXIT_KAFL_SUBMIT_KASAN\n");
handle_hypercall_kafl_submit_kasan(run, cpu, arg);
nyx_abort((char*)"Deprecated hypercall called (HYPERCALL_SUBMIT_KASAN)...");
ret = 0;
break;
case KVM_EXIT_KAFL_PANIC:
@ -867,9 +768,7 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall
ret = 0;
break;
case KVM_EXIT_KAFL_KASAN:
//timeout_reload_pending = false;
//fprintf(stderr, "KVM_EXIT_KAFL_KASAN\n");
handle_hypercall_kafl_kasan(run, cpu, arg);
nyx_abort((char*)"Deprecated hypercall called (HYPERCALL_KAFL_KASAN)...");
ret = 0;
break;
case KVM_EXIT_KAFL_LOCK:
@ -879,9 +778,7 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall
ret = 0;
break;
case KVM_EXIT_KAFL_INFO:
//timeout_reload_pending = false;
//fprintf(stderr, "KVM_EXIT_KAFL_INFO\n");
handle_hypercall_kafl_info(run, cpu, arg);
nyx_abort((char*)"Deprecated hypercall called (HYPERCALL_KAFL_INFO)...");
ret = 0;
break;
case KVM_EXIT_KAFL_NEXT_PAYLOAD:
@ -897,13 +794,11 @@ int handle_kafl_hypercall(struct kvm_run *run, CPUState *cpu, uint64_t hypercall
ret = 0;
break;
case KVM_EXIT_KAFL_PRINTK_ADDR:
//timeout_reload_pending = false;
handle_hypercall_kafl_printk_addr(run, cpu, arg);
nyx_abort((char*)"Deprecated hypercall called (KVM_EXIT_KAFL_PRINTK_ADDR)...");
ret = 0;
break;
case KVM_EXIT_KAFL_PRINTK:
//timeout_reload_pending = false;
handle_hypercall_kafl_printk(run, cpu, arg);
nyx_abort((char*)"Deprecated hypercall called (KVM_EXIT_KAFL_PRINTK)...");
ret = 0;
break;

View File

@ -22,7 +22,6 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#define PAYLOAD_BUFFER_SIZE 26
#define PRINTK_PAYLOAD_SIZE 4
#define KAFL_MODE_64 0
#define KAFL_MODE_32 1
@ -100,7 +99,6 @@ void handle_hypercall_kafl_page_dump_bp(struct kvm_run *run, CPUState *cpu, uint
void hprintf(char* msg);
void enable_notifies(void);
bool handle_hypercall_kafl_next_payload(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg);
void hypercall_reset_hprintf_counter(void);

View File

@ -48,7 +48,7 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#include "nyx/snapshot/devices/state_reallocation.h"
#include "nyx/memory_access.h"
#include <sys/ioctl.h>
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "nyx/sharedir.h"
#include "nyx/helpers.h"
@ -85,10 +85,9 @@ typedef struct nyx_interface_state {
char* filter_bitmap[4];
char* ip_filter[4][2];
uint64_t bitmap_size;
uint32_t bitmap_size;
uint32_t input_buffer_size;
bool debug_mode; /* support for hprintf */
bool notifier;
bool dump_pt_trace;
bool redqueen;
@ -183,6 +182,7 @@ static void nyx_guest_setup_bitmap(nyx_interface_state *s, char* filename, uint3
GET_GLOBAL_STATE()->shared_bitmap_ptr = (void*)ptr;
GET_GLOBAL_STATE()->shared_bitmap_fd = fd;
GET_GLOBAL_STATE()->shared_bitmap_size = bitmap_size;
GET_GLOBAL_STATE()->shared_bitmap_real_size = bitmap_size;
}
@ -197,12 +197,9 @@ static void nyx_guest_setup_ijon_buffer(nyx_interface_state *s, char* filename){
assert(DEFAULT_NYX_IJON_BITMAP_SIZE == st.st_size);
ptr = mmap(0, DEFAULT_NYX_IJON_BITMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
/*
GET_GLOBAL_STATE()->shared_bitmap_ptr = (void*)ptr;
GET_GLOBAL_STATE()->shared_bitmap_fd = fd;
GET_GLOBAL_STATE()->shared_bitmap_size = bitmap_size-DEFAULT_NYX_IJON_BITMAP_SIZE;
GET_GLOBAL_STATE()->shared_ijon_bitmap_ptr = (void*)ptr;
GET_GLOBAL_STATE()->shared_ijon_bitmap_fd = fd;
GET_GLOBAL_STATE()->shared_ijon_bitmap_size = DEFAULT_NYX_IJON_BITMAP_SIZE;
*/
}
static bool verify_workdir_state(nyx_interface_state *s, Error **errp){
@ -238,7 +235,7 @@ static bool verify_workdir_state(nyx_interface_state *s, Error **errp){
return false;
}
else {
nyx_create_payload_buffer(s, PAYLOAD_SIZE, tmp, errp);
nyx_create_payload_buffer(s, s->input_buffer_size, tmp, errp);
}
free(tmp);
@ -304,8 +301,8 @@ static bool verify_workdir_state(nyx_interface_state *s, Error **errp){
if(s->dump_pt_trace){
assert(asprintf(&tmp, "%s/pt_trace_dump_%d", workdir, id) != -1);
pt_open_pt_trace_file(tmp);
free(tmp);
pt_open_pt_trace_file(tmp);
free(tmp);
}
@ -391,8 +388,6 @@ static void nyx_realize(DeviceState *dev, Error **errp){
s->bitmap_size = DEFAULT_NYX_BITMAP_SIZE;
}
assert((uint32_t)s->bitmap_size > (0x1000 + DEFAULT_NYX_IJON_BITMAP_SIZE));
assert((((uint32_t)s->bitmap_size-DEFAULT_NYX_IJON_BITMAP_SIZE) & (((uint32_t)s->bitmap_size-DEFAULT_NYX_IJON_BITMAP_SIZE) - 1)) == 0 );
if(s->worker_id == 0xFFFF){
fprintf(stderr, "[QEMU-Nyx] Error: Invalid worker id...\n");
@ -421,14 +416,6 @@ static void nyx_realize(DeviceState *dev, Error **errp){
}
check_available_ipt_ranges(s);
if(s->debug_mode){
GET_GLOBAL_STATE()->enable_hprintf = true;
}
if(s->notifier){
enable_notifies();
}
pt_setup_enable_hypercalls();
init_crash_handler();
@ -458,9 +445,8 @@ static Property nyx_interface_properties[] = {
DEFINE_PROP_STRING("ip3_b", nyx_interface_state, ip_filter[3][1]),
DEFINE_PROP_UINT64("bitmap_size", nyx_interface_state, bitmap_size, DEFAULT_NYX_BITMAP_SIZE),
DEFINE_PROP_BOOL("debug_mode", nyx_interface_state, debug_mode, false),
DEFINE_PROP_BOOL("crash_notifier", nyx_interface_state, notifier, true),
DEFINE_PROP_UINT32("bitmap_size", nyx_interface_state, bitmap_size, DEFAULT_NYX_BITMAP_SIZE),
DEFINE_PROP_UINT32("input_buffer_size", nyx_interface_state, input_buffer_size, DEFAULT_NYX_BITMAP_SIZE),
DEFINE_PROP_BOOL("dump_pt_trace", nyx_interface_state, dump_pt_trace, false),

View File

@ -23,15 +23,10 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#define INTERFACE_H
/* 64k bitmap + 4k ijon buffer */
#define DEFAULT_NYX_IJON_BITMAP_SIZE 0x1000
#define DEFAULT_NYX_BITMAP_SIZE 0x10000 + DEFAULT_NYX_IJON_BITMAP_SIZE
#define DEFAULT_EDGE_FILTER_SIZE 0x1000000
#define DEFAULT_NYX_IJON_BITMAP_SIZE 0x1000 /* fixed size buffer for IJON -> 4k */
#define DEFAULT_NYX_BITMAP_SIZE 0x10000 /* default bitmap size => 64k */
#define PAYLOAD_SIZE (128 << 10) /* 128KB Payload Data */
#define HPRINTF_SIZE 0x1000 /* 4KB hprintf Data */
#define NYX_INTERFACE_PING 'x'
#define NYX_INTERFACE_PING 'x'
bool interface_send_char(char val);

View File

@ -4,7 +4,7 @@
#include "nyx/debug.h"
#include "exec/ram_addr.h"
#include "qemu/rcu_queue.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "sysemu/kvm.h"
#include "pt.h"

View File

@ -30,7 +30,7 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#include "debug.h"
#include "nyx/fast_vm_reload.h"
#include "exec/gdbstub.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "sysemu/kvm.h"
#include "nyx/helpers.h"
@ -200,7 +200,7 @@ bool remap_slot(uint64_t addr, uint32_t slot, CPUState *cpu, int fd, uint64_t sh
if(virtual){
phys_addr = get_paging_phys_addr(cpu, cr3, (addr & x86_64_PAGE_MASK));
if(phys_addr == (uint64_t)-1){
if(phys_addr == INVALID_ADDRESS){
fprintf(stderr, "[QEMU-Nyx] Error: failed to translate v_addr (0x%lx) to p_addr!\n", addr);
fprintf(stderr, "[QEMU-Nyx] Check if the buffer is present in the guest's memory...\n");
exit(1);
@ -259,22 +259,37 @@ bool remap_payload_slot_protected(uint64_t phys_addr, uint32_t slot, CPUState *c
return true;
}
void resize_coverage_bitmap(uint32_t new_size){
assert(GET_GLOBAL_STATE()->shared_bitmap_fd && GET_GLOBAL_STATE()->shared_bitmap_size);
fprintf(stderr, "shared_bitmap_size -> %x - new_size: %x\n", GET_GLOBAL_STATE()->shared_bitmap_size, new_size);
assert(GET_GLOBAL_STATE()->shared_bitmap_size <= (new_size+0x1000) && !(new_size & 0xFFF));
void resize_shared_memory(uint32_t new_size, uint32_t* shm_size, void** shm_ptr, int fd){
assert(fd && *shm_size);
/* check if the new_size is a multiple of PAGE_SIZE */
if(new_size & (PAGE_SIZE-1)){
new_size = (new_size & ~(PAGE_SIZE-1)) + PAGE_SIZE;
}
if(*shm_size >= new_size){
/* no need no resize the buffer -> early exit */
return;
}
assert(!GET_GLOBAL_STATE()->pt_trace_mode);
assert(!GET_GLOBAL_STATE()->in_fuzzing_mode);
assert(ftruncate(GET_GLOBAL_STATE()->shared_bitmap_fd, new_size+0x1000) == 0);
assert(ftruncate(fd, new_size) == 0);
printf("MUNMAP: %d\n", GET_GLOBAL_STATE()->shared_bitmap_size);
munmap((void*)GET_GLOBAL_STATE()->shared_bitmap_ptr , GET_GLOBAL_STATE()->shared_bitmap_size+0x1000);
GET_GLOBAL_STATE()->shared_bitmap_ptr = (void*)mmap(0, new_size+0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, GET_GLOBAL_STATE()->shared_bitmap_fd, 0);;
GET_GLOBAL_STATE()->shared_bitmap_size = new_size;
GET_GLOBAL_STATE()->auxilary_buffer->capabilites.agent_coverage_bitmap_size = new_size;
if(shm_ptr){
munmap(*shm_ptr , *shm_size);
*shm_ptr = (void*)mmap(0, new_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
assert(*shm_ptr != MAP_FAILED);
}
else{
fprintf(stderr, "=> shm_ptr is NULL\n");
abort();
}
*shm_size = new_size;
}
void resize_payload_buffer(uint32_t new_size){
assert(GET_GLOBAL_STATE()->shared_payload_buffer_fd && GET_GLOBAL_STATE()->shared_payload_buffer_size);
assert(GET_GLOBAL_STATE()->shared_payload_buffer_size < new_size && !(new_size & 0xFFF));
@ -302,7 +317,7 @@ bool remap_payload_buffer(uint64_t virt_guest_addr, CPUState *cpu){
QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
if(!memcmp(block->idstr, "pc.ram", 6)){
//printf("MMUNMAP: %d\n", munmap((void*)(((uint64_t)block->host) + phys_addr), x86_64_PAGE_SIZE));
if(munmap((void*)(((uint64_t)block->host) + phys_addr), x86_64_PAGE_SIZE) == -1){
if(munmap((void*)(((uint64_t)block->host) + phys_addr), x86_64_PAGE_SIZE) == -1){
fprintf(stderr, "munmap failed!\n");
//exit(1);
assert(false);
@ -351,7 +366,7 @@ bool write_virtual_memory(uint64_t address, uint8_t* data, uint32_t size, CPUSta
attrs = MEMTXATTRS_UNSPECIFIED;
phys_addr = cpu_get_phys_page_attrs_debug(cpu, (address & x86_64_PAGE_MASK), &attrs);
if (phys_addr == -1){
if (phys_addr == INVALID_ADDRESS){
QEMU_PT_PRINTF(MEM_PREFIX, "phys_addr == -1:\t%lx", address);
return false;
}
@ -680,12 +695,17 @@ void print_48_paging2(uint64_t cr3){
}
static uint64_t* load_page_table(uint64_t page_table_address, uint64_t* paging_entries_buffer, uint8_t level, bool read_from_snapshot){
static uint64_t* load_page_table(uint64_t page_table_address, uint64_t* paging_entries_buffer, uint8_t level, bool read_from_snapshot, bool *success){
if(page_table_address == INVALID_ADDRESS){
*success = false;
}
if (read_from_snapshot){
read_snapshot_memory(get_fast_reload_snapshot(), page_table_address, (uint8_t *) paging_entries_buffer, PPAGE_SIZE);
*success = read_snapshot_memory(get_fast_reload_snapshot(), page_table_address, (uint8_t *) paging_entries_buffer, PPAGE_SIZE);
}
else{
cpu_physical_memory_rw(page_table_address, (uint8_t *) paging_entries_buffer, PPAGE_SIZE, false);
*success = true; /* fix this */
}
return paging_entries_buffer;
}
@ -702,8 +722,14 @@ static uint64_t get_48_paging_phys_addr(uint64_t cr3, uint64_t addr, bool read_f
uint64_t* paging_entries_buffer_ptr = NULL;
uint64_t page_table_address = 0;
bool success = false;
page_table_address = (cr3&PAGETABLE_MASK);
paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 0, read_from_snapshot);
paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 0, read_from_snapshot, &success);
if (unlikely(success == false)){
goto fail;
}
if(paging_entries_buffer_ptr[pml_4_index]){
address_identifier_4 = ((uint64_t)pml_4_index) << PLEVEL_1_SHIFT;
@ -713,7 +739,11 @@ static uint64_t get_48_paging_phys_addr(uint64_t cr3, uint64_t addr, bool read_f
if(CHECK_BIT(paging_entries_buffer_ptr[pml_4_index], 0)){ /* otherwise swapped out */
page_table_address = (paging_entries_buffer_ptr[pml_4_index]&PAGETABLE_MASK);
paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 1, read_from_snapshot);
paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 1, read_from_snapshot, &success);
if (unlikely(success == false)){
goto fail;
}
if(paging_entries_buffer_ptr[pml_3_index]){
@ -726,7 +756,11 @@ static uint64_t get_48_paging_phys_addr(uint64_t cr3, uint64_t addr, bool read_f
else{
page_table_address = (paging_entries_buffer_ptr[pml_3_index]&PAGETABLE_MASK);
paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 2, read_from_snapshot);
paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 2, read_from_snapshot, &success);
if (unlikely(success == false)){
goto fail;
}
if(paging_entries_buffer_ptr[pml_2_index]){
if (CHECK_BIT(paging_entries_buffer_ptr[pml_2_index], 0)){ /* otherwise swapped out */
@ -737,7 +771,11 @@ static uint64_t get_48_paging_phys_addr(uint64_t cr3, uint64_t addr, bool read_f
else{
page_table_address = (paging_entries_buffer_ptr[pml_2_index]&PAGETABLE_MASK);
paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 3, read_from_snapshot);
paging_entries_buffer_ptr = load_page_table(page_table_address, paging_entries_buffer, 3, read_from_snapshot, &success);
if (unlikely(success == false)){
goto fail;
}
if(paging_entries_buffer_ptr[pml_1_index]){
if (CHECK_BIT(paging_entries_buffer_ptr[pml_1_index], 0)){
@ -753,6 +791,8 @@ static uint64_t get_48_paging_phys_addr(uint64_t cr3, uint64_t addr, bool read_f
}
}
}
fail:
return INVALID_ADDRESS;
}
@ -839,15 +879,21 @@ bool is_addr_mapped_cr3_snapshot(uint64_t address, CPUState *cpu, uint64_t cr3){
bool dump_page_cr3_snapshot(uint64_t address, uint8_t* data, CPUState *cpu, uint64_t cr3){
fast_reload_t* snapshot = get_fast_reload_snapshot();
return read_snapshot_memory(snapshot, get_paging_phys_addr_snapshot(cpu, cr3, address), data, PPAGE_SIZE);
uint64_t phys_addr = get_paging_phys_addr_snapshot(cpu, cr3, address);
if(phys_addr == INVALID_ADDRESS){
return false;
}
else{
return read_snapshot_memory(snapshot, phys_addr, data, PPAGE_SIZE);
}
}
bool dump_page_cr3_ht(uint64_t address, uint8_t* data, CPUState *cpu, uint64_t cr3){
hwaddr phys_addr = (hwaddr) get_paging_phys_addr(cpu, cr3, address);
int asidx = cpu_asidx_from_attrs(cpu, MEMTXATTRS_UNSPECIFIED);
if(phys_addr == 0xffffffffffffffffULL || address_space_rw(cpu_get_address_space(cpu, asidx), phys_addr, MEMTXATTRS_UNSPECIFIED, data, 0x1000, 0)){
if(phys_addr != 0xffffffffffffffffULL){
if(phys_addr == INVALID_ADDRESS || address_space_rw(cpu_get_address_space(cpu, asidx), phys_addr, MEMTXATTRS_UNSPECIFIED, data, 0x1000, 0)){
if(phys_addr != INVALID_ADDRESS){
fprintf(stderr, "%s: Warning, read failed:\t%lx (%lx)\n", __func__, address, phys_addr);
}
return false;

View File

@ -67,7 +67,7 @@ void print_48_paging2(uint64_t cr3);
bool dump_page_ht(uint64_t address, uint8_t* data, CPUState *cpu);
void resize_coverage_bitmap(uint32_t new_size);
void resize_shared_memory(uint32_t new_size, uint32_t* shm_size, void** shm_ptr, int fd);
void resize_payload_buffer(uint32_t new_size);
#endif

View File

@ -5,7 +5,7 @@
#include "debug.h"
#include "nested_hypercalls.h"
#include "interface.h"
#include "state.h"
#include "state/state.h"
#include "pt.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"

View File

@ -17,7 +17,7 @@
#include "memory_access.h"
#include "fast_vm_reload.h"
#include "kvm_nested.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#endif
@ -106,7 +106,7 @@ static bool append_page(page_cache_t* self, uint64_t page, uint64_t cr3){
if(!dump_page_cr3_ht(page, self->page_data+(PAGE_SIZE*self->num_pages), self->cpu, GET_GLOBAL_STATE()->parent_cr3)){
if(!dump_page_cr3_snapshot(page, self->page_data+(PAGE_SIZE*self->num_pages), self->cpu, GET_GLOBAL_STATE()->parent_cr3)){
fprintf(stderr, "FAILED DUMP PROCESS of PAGE %lx\n", page);
//fprintf(stderr, "FAILED DUMP PROCESS of PAGE %lx\n", page);
//memset(self->page_data+(PAGE_SIZE*self->num_pages), 0xff, PAGE_SIZE);
munmap(self->page_data, (self->num_pages+1)*PAGE_SIZE);
@ -255,7 +255,7 @@ static bool update_page_cache(page_cache_t* self, uint64_t page, khiter_t* k){
kh_value(self->lookup, *k) = (self->num_pages-1)*PAGE_SIZE;
}
else{
fprintf(stderr, "Fail!!!!\n");
//fprintf(stderr, "Fail!!!!\n");
page_cache_unlock(self);
return false;
/*

View File

@ -2,7 +2,7 @@
#include "nyx/memory_access.h"
#include "nyx/disassembler.h"
#include "debug.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
uint8_t cmp_patch_data[] = { 0x38, 0xC0, [2 ... MAX_INSTRUCTION_SIZE]=0x90 }; // CMP AL,AL; NOP, NOP ...
const uint8_t *cmp_patch = &cmp_patch_data[0];

View File

@ -1,104 +0,0 @@
#include "qemu/osdep.h"
#include <linux/kvm.h>
#include "qemu-common.h"
#include "nyx/memory_access.h"
#include "nyx/hypercall/hypercall.h"
#include "nyx/printk.h"
enum reg_types{RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15, RIP};
uint8_t types[] = {RSI, RDX, RCX, R8, R9} ;
/* calling convention: RDI, RSI, RDX, RCX, R8, R9 */
/* https://www.kernel.org/doc/Documentation/printk-formats.txt :-( */
bool kafl_linux_printk(CPUState *cpu){
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = &x86_cpu->env;
char printk_buf[0x1000];
uint8_t rsp_buf[0x1000];
uint8_t rdi_buf[0x1000];
uint8_t rsi_buf[0x1000];
uint8_t rdx_buf[0x1000];
uint8_t rcx_buf[0x1000];
uint8_t r8_buf[0x1000];
uint8_t r9_buf[0x1000];
read_virtual_memory((uint64_t)env->regs[RSP], (uint8_t*)rsp_buf, 0x1000, cpu);
read_virtual_memory((uint64_t)env->regs[RDI], (uint8_t*)rdi_buf, 0x1000, cpu);
uint8_t* buf[] = {rsi_buf, rdx_buf, rcx_buf, r8_buf, r9_buf};
for(uint16_t i = 0, type = 0; i < 0x1000 && rdi_buf[i] != '\x00'; i++){
if(i > 1 && rdi_buf[i-2] == '%' && rdi_buf[i-1] != '%'){
if(rdi_buf[i-1] == 's' || rdi_buf[i-1] == 'p' || rdi_buf[i-1] == '.'){
if(rdi_buf[i] == 'B'){
rdi_buf[i-1] = 'l';
rdi_buf[i] = 'x';
buf[type] = (uint8_t*)env->regs[types[type]];
}
else if(rdi_buf[i-1] == 'p' && rdi_buf[i] == 'V'){
rdi_buf[i-1] = 's';
rdi_buf[i] = ' ';
read_virtual_memory((uint64_t)env->regs[types[type]], (uint8_t*)buf[type], 0x1000, cpu);
uint64_t tmp = *((uint64_t*)buf[type]);
read_virtual_memory(tmp, (uint8_t*)buf[type], 0x1000, cpu);
}
else if(rdi_buf[i-1] == 'p'){
rdi_buf[i-1] = 'l';
memmove(rdi_buf+i+1, rdi_buf+i, 0x1000-i-1);
rdi_buf[i] = 'x';
buf[type] = (uint8_t*)env->regs[types[type]];
}
else {
read_virtual_memory((uint64_t)env->regs[types[type]], (uint8_t*)buf[type], 0x1000, cpu);
}
}
else{
buf[type] = (uint8_t*)env->regs[types[type]];
}
type++;
if(type > 4){
rdi_buf[i] = '\n';
rdi_buf[i+1] = '\x00';
break;
}
}
}
snprintf(printk_buf, 0x1000, (char*)rdi_buf, buf[0], buf[1], buf[2], buf[3], buf[4]);
if(printk_buf[0] == 0x1){
//printf("%s", rdi_buf+2);
//hprintf(printk_buf+2);
//printf("%s", printk_buf+2);
if(!strncmp(printk_buf+2, "---[ end Kernel panic", 21)){
return true;
}
}
else {
//printf("%s", rdi_buf);
//hprintf(printk_buf);
//printf("%s", printk_buf);
if(!strncmp(printk_buf, "---[ end Kernel panic", 21)){
return true;
}
}
return false;
}

View File

@ -1,28 +0,0 @@
/*
Copyright (C) 2017 Sergej Schumilo
This file is part of QEMU-PT (kAFL).
QEMU-PT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QEMU-PT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PRINTK_H
#define PRINTK_H
bool kafl_linux_printk(CPUState *cpu);
#endif

View File

@ -38,7 +38,7 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#include "nyx/redqueen_patch.h"
#include "nyx/patcher.h"
#include "nyx/page_cache.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include <libxdc.h>
#include "nyx/helpers.h"
@ -145,7 +145,7 @@ void pt_dump(CPUState *cpu, int bytes){
cpu->intel_pt_run_trashed = true;
break;
case decoder_page_fault:
fprintf(stderr, "Page not found => 0x%lx\n", libxdc_get_page_fault_addr(GET_GLOBAL_STATE()->decoder));
//fprintf(stderr, "Page not found => 0x%lx\n", libxdc_get_page_fault_addr(GET_GLOBAL_STATE()->decoder));
GET_GLOBAL_STATE()->decoder_page_fault = true;
GET_GLOBAL_STATE()->decoder_page_fault_addr = libxdc_get_page_fault_addr(GET_GLOBAL_STATE()->decoder);
break;
@ -157,7 +157,7 @@ void pt_dump(CPUState *cpu, int bytes){
break;
}
}
}
}
}

View File

@ -28,7 +28,7 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#include "patcher.h"
#include "debug.h"
#include "redqueen_trace.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include <capstone/capstone.h>
#include <capstone/x86.h>

View File

@ -3,7 +3,7 @@
#include <sys/mman.h>
#include "nyx/snapshot/block/block_cow.h"
#include "sysemu/block-backend.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
//#define COW_CACHE_DEBUG

View File

@ -11,7 +11,7 @@
#include "nyx/snapshot/block/nyx_block_snapshot.h"
#include "nyx/debug.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
typedef struct fast_reload_cow_entry_s{
uint32_t id;

View File

@ -29,7 +29,9 @@ void nyx_snapshot_debug_enable(fast_reload_t* self){
}
/* restore operation */
void nyx_snapshot_debug_restore(shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist, bool verbose){
uint32_t nyx_snapshot_debug_restore(shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist, bool verbose){
uint32_t num_dirty_pages = 0;
void* current_region = NULL;
int counter = 0;
for(uint8_t i = 0; i < shadow_memory_state->ram_regions_num; i++){
@ -59,6 +61,7 @@ void nyx_snapshot_debug_restore(shadow_memory_t* shadow_memory_state, snapshot_p
}
memcpy(host_addr, snapshot_addr, TARGET_PAGE_SIZE);
num_dirty_pages++;
}
}
}
@ -67,6 +70,7 @@ void nyx_snapshot_debug_restore(shadow_memory_t* shadow_memory_state, snapshot_p
if(verbose){
printf("TOTAL: %d\n", counter);
}
return num_dirty_pages;
}
void nyx_snapshot_debug_save_root_pages(shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist, bool verbose){

View File

@ -5,6 +5,6 @@
void nyx_snapshot_debug_pre_init(void);
void nyx_snapshot_debug_init(fast_reload_t* self);
void nyx_snapshot_debug_enable(fast_reload_t* self);
void nyx_snapshot_debug_restore(shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist, bool verbose);
uint32_t nyx_snapshot_debug_restore(shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist, bool verbose);
void nyx_snapshot_debug_set(fast_reload_t* self);
void nyx_snapshot_debug_save_root_pages(shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist, bool verbose);

View File

@ -242,7 +242,8 @@ nyx_dirty_ring_t* nyx_dirty_ring_init(shadow_memory_t* shadow_memory){
return self;
}
static void restore_memory(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
static uint32_t restore_memory(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
uint32_t num_dirty_pages = 0;
void* host_addr = NULL;
void* snapshot_addr = NULL;
uint64_t physical_addr = 0;
@ -272,13 +273,15 @@ static void restore_memory(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memor
snapshot_addr = shadow_memory_state->ram_regions[kvm_region_slot->region_id].snapshot_region_ptr + entry_offset_addr;
}
memcpy(host_addr, snapshot_addr, TARGET_PAGE_SIZE);
memcpy(host_addr, snapshot_addr, TARGET_PAGE_SIZE);
clear_bit(gfn, (void*)kvm_region_slot->bitmap);
num_dirty_pages++;
}
kvm_region_slot->stack_ptr = 0;
}
}
return num_dirty_pages;
}
static void save_root_pages(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
@ -318,8 +321,7 @@ static void save_root_pages(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memo
//entry = &ring->dirty_gfns[ring->reset_index & (ring->size - 1)];
void nyx_snapshot_nyx_dirty_ring_restore(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
uint32_t nyx_snapshot_nyx_dirty_ring_restore(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
/*
static int perf_counter = 0;
@ -330,8 +332,8 @@ void nyx_snapshot_nyx_dirty_ring_restore(nyx_dirty_ring_t* self, shadow_memory_t
perf_counter++;
*/
dirty_ring_flush_and_collect(self, shadow_memory_state, blocklist, kvm_get_vm_fd(kvm_state));
restore_memory(self, shadow_memory_state, blocklist);
dirty_ring_flush_and_collect(self, shadow_memory_state, blocklist, kvm_get_vm_fd(kvm_state));
return restore_memory(self, shadow_memory_state, blocklist);
}
void nyx_snapshot_nyx_dirty_ring_save_root_pages(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){

View File

@ -36,7 +36,7 @@ void nyx_dirty_ring_pre_init(int kvm_fd, int vm_fd);
nyx_dirty_ring_t* nyx_dirty_ring_init(shadow_memory_t* shadow_memory);
void nyx_snapshot_nyx_dirty_ring_restore(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
uint32_t nyx_snapshot_nyx_dirty_ring_restore(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
void nyx_snapshot_nyx_dirty_ring_save_root_pages(nyx_dirty_ring_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
void nyx_snapshot_nyx_dirty_ring_flush(void);

View File

@ -98,8 +98,9 @@ nyx_fdl_t* nyx_fdl_init(shadow_memory_t* shadow_memory){
#define MEMSET_BITMAP
#ifdef MEMSET_BITMAP
static void nyx_snapshot_nyx_fdl_restore_new(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
static uint32_t nyx_snapshot_nyx_fdl_restore_new(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
uint32_t num_dirty_pages = 0;
void* current_region = NULL;
struct fdl_result result;
@ -142,24 +143,26 @@ static void nyx_snapshot_nyx_fdl_restore_new(nyx_fdl_t* self, shadow_memory_t* s
clear_bit(entry_offset_addr>>12, (void*)self->entry[i].bitmap);
memcpy(host_addr, snapshot_addr, TARGET_PAGE_SIZE);
num_dirty_pages++;
}
}
#ifdef RESET_VRAM
//nyx_snapshot_nyx_fdl_restore_vram(self, shadow_memory_state);
#endif
return num_dirty_pages;
}
#endif
/* restore operation */
void nyx_snapshot_nyx_fdl_restore(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
uint32_t nyx_snapshot_nyx_fdl_restore(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
/* not sure which one is faster -> benchmark ASAP */
#ifdef MEMSET_BITMAP
nyx_snapshot_nyx_fdl_restore_new(self, shadow_memory_state, blocklist);
return nyx_snapshot_nyx_fdl_restore_new(self, shadow_memory_state, blocklist);
#else
nyx_snapshot_nyx_fdl_restore_old(self, shadow_memory_state, blocklist);
return nyx_snapshot_nyx_fdl_restore_old(self, shadow_memory_state, blocklist);
#endif
}

View File

@ -54,6 +54,6 @@ typedef struct nyx_fdl_s{
}nyx_fdl_t;
nyx_fdl_t* nyx_fdl_init(shadow_memory_t* self);
void nyx_snapshot_nyx_fdl_restore(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
uint32_t nyx_snapshot_nyx_fdl_restore(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
void nyx_snapshot_nyx_fdl_save_root_pages(nyx_fdl_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);

View File

@ -51,7 +51,8 @@ static void nyx_snapshot_user_fdl_reset(nyx_fdl_user_t* self){
}
/* reset operation */
void nyx_snapshot_user_fdl_restore(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
uint32_t nyx_snapshot_user_fdl_restore(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist){
uint32_t num_dirty_pages = 0;
if(self){
void* current_region = NULL;
@ -85,6 +86,7 @@ void nyx_snapshot_user_fdl_restore(nyx_fdl_user_t* self, shadow_memory_t* shadow
#endif
clear_bit(entry_offset_addr>>12, (void*)self->entry[i].bitmap);
memcpy(host_addr, snapshot_addr, TARGET_PAGE_SIZE);
num_dirty_pages++;
}
}
@ -92,6 +94,7 @@ void nyx_snapshot_user_fdl_restore(nyx_fdl_user_t* self, shadow_memory_t* shadow
}
nyx_snapshot_user_fdl_reset(self);
return num_dirty_pages;
}
/* set operation (mark pf as dirty) */

View File

@ -21,5 +21,5 @@ nyx_fdl_user_t* nyx_fdl_user_init(shadow_memory_t* shadow_memory_state);
void nyx_fdl_user_enable(nyx_fdl_user_t* self);
void nyx_fdl_user_set(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state, nyx_fdl_t* nyx_fdl_state, uint64_t addr, uint64_t length);
void nyx_snapshot_user_fdl_restore(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
uint32_t nyx_snapshot_user_fdl_restore(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);
void nyx_snapshot_nyx_fdl_user_save_root_pages(nyx_fdl_user_t* self, shadow_memory_t* shadow_memory_state, snapshot_page_blocklist_t* blocklist);

View File

@ -395,7 +395,7 @@ void shadow_memory_serialize(shadow_memory_t* self, const char* snapshot_folder)
}
bool shadow_memory_read_physical_memory(shadow_memory_t* self, uint64_t address, void* ptr, size_t size){
assert(size == 0x1000 && (address & 0xFFFULL) == 0); /* remove this limitation later */
if(address < self->memory_size){

View File

@ -1,409 +0,0 @@
/*
Copyright (C) 2019 Sergej Schumilo
This file is part of QEMU-PT (HyperTrash / kAFL).
QEMU-PT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QEMU-PT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
*/
#include "nyx/state.h"
#include "nyx/debug.h"
#include "nyx/memory_access.h"
#include "sysemu/kvm.h"
#include "nyx/auxiliary_buffer.h"
#include "nyx/sharedir.h"
#include "nyx/fast_vm_reload_sync.h"
#include "nyx/helpers.h"
//#define STATE_VERBOSE
/* global singleton */
struct state_qemu_pt global_state;
#define LIBXDC_RELEASE_VERSION_REQUIRED 2
void state_init_global(void){
#ifdef STATE_VERBOSE
fprintf(stderr, "--> %s <--\n", __func__);
#endif
/* safety first */
assert(libxdc_get_release_version() == LIBXDC_RELEASE_VERSION_REQUIRED);
global_state.nyx_fdl = false;
global_state.workdir_path = NULL;
global_state.fast_reload_enabled = false;
global_state.fast_reload_mode = false;
global_state.fast_reload_path = NULL;
global_state.fast_reload_pre_path = NULL;
global_state.fast_reload_pre_image = false;
global_state.fast_reload_snapshot = fast_reload_new();
global_state.reload_state = init_fast_vm_reload_sync();
global_state.decoder = NULL;
global_state.page_cache = NULL;
global_state.redqueen_enable_pending = false;
global_state.redqueen_disable_pending = false;
global_state.redqueen_instrumentation_mode = 0;
global_state.redqueen_update_blacklist = false;
global_state.patches_enable_pending = false;
global_state.patches_disable_pending = false;
global_state.redqueen_state = NULL;
for(uint8_t i = 0; i < INTEL_PT_MAX_RANGES; i++){
global_state.pt_ip_filter_configured[i] = false;
global_state.pt_ip_filter_enabled[i] = false;
global_state.pt_ip_filter_a[i] = 0x0;
global_state.pt_ip_filter_b[i] = 0x0;
}
global_state.pt_c3_filter = 0;
global_state.enable_hprintf = false;
global_state.parent_cr3 = 0;
global_state.disassembler_word_width = 64;
global_state.nested = false;
global_state.payload_buffer = 0;
global_state.nested_payload_pages = NULL;
global_state.nested_payload_pages_num = 0;
global_state.protect_payload_buffer = 0;
global_state.discard_tmp_snapshot = 0;
global_state.mem_mode = mm_unkown;
init_timeout_detector(&(global_state.timeout_detector));
global_state.in_fuzzing_mode = false;
global_state.in_reload_mode = true;
global_state.shutdown_requested = false;
global_state.cow_cache_full = false;
global_state.auxilary_buffer = NULL;
memset(&global_state.shadow_config, 0x0, sizeof(auxilary_buffer_config_t));
global_state.decoder_page_fault = false;
global_state.decoder_page_fault_addr = 0x0;
global_state.dump_page = false;
global_state.dump_page_addr = 0x0;
global_state.in_redqueen_reload_mode = false;
global_state.pt_trace_mode = true;
global_state.pt_trace_mode_force = false;
global_state.sharedir = sharedir_new();
global_state.shared_bitmap_fd = 0;
global_state.shared_bitmap_size = 0;
global_state.shared_ijon_bitmap_size = 0;
global_state.shared_payload_buffer_fd = 0;
global_state.shared_payload_buffer_size = 0;
global_state.shared_bitmap_ptr = NULL;
global_state.pt_trace_size = 0;
global_state.bb_coverage = 0;
global_state.cap_timeout_detection = 0;
global_state.cap_only_reload_mode = 0;
global_state.cap_compile_time_tracing = 0;
global_state.cap_ijon_tracing = 0;
global_state.cap_cr3 = 0;
global_state.cap_compile_time_tracing_buffer_vaddr = 0;
global_state.cap_ijon_tracing_buffer_vaddr = 0;
QTAILQ_INIT(&global_state.redqueen_breakpoints);
}
fast_reload_t* get_fast_reload_snapshot(void){
return global_state.fast_reload_snapshot;
}
void set_fast_reload_mode(bool mode){
global_state.fast_reload_mode = mode;
}
void set_fast_reload_path(const char* path){
assert(global_state.fast_reload_path == NULL);
global_state.fast_reload_path = malloc(strlen(path)+1);
strcpy(global_state.fast_reload_path, path);
}
void set_fast_reload_pre_path(const char* path){
assert(global_state.fast_reload_pre_path == NULL);
global_state.fast_reload_pre_path = malloc(strlen(path)+1);
strcpy(global_state.fast_reload_pre_path, path);
}
void set_fast_reload_pre_image(void){
assert(global_state.fast_reload_pre_path != NULL);
global_state.fast_reload_pre_image = true;
}
void enable_fast_reloads(void){
assert(global_state.fast_reload_path != NULL);
global_state.fast_reload_enabled = true;
}
void init_page_cache(char* path){
assert(global_state.page_cache == NULL);
global_state.page_cache = page_cache_new((CPUState *)qemu_get_cpu(0), path);
#ifdef STATE_VERBOSE
debug_printf("\n\nINIT PAGE_CACHE => %s\n", path);
#endif
}
page_cache_t* get_page_cache(void){
assert(global_state.page_cache);
return global_state.page_cache;
}
void init_redqueen_state(void){
global_state.redqueen_state = new_rq_state((CPUState *)qemu_get_cpu(0), get_page_cache());
}
redqueen_t* get_redqueen_state(void){
assert(global_state.redqueen_state != NULL);
return global_state.redqueen_state;
}
void dump_global_state(const char* filename_prefix){
debug_printf("%s\n", __func__);
char* tmp;
assert(asprintf(&tmp, "%s/global.state", filename_prefix) != -1);
debug_printf("%s\n", tmp);
FILE *fp = fopen(tmp, "wb");
if(fp == NULL) {
debug_fprintf(stderr, "[%s] Could not open file %s.\n", __func__, tmp);
assert(false);
//exit(EXIT_FAILURE);
}
debug_printf("DUMPING global_state.pt_ip_filter_configured: -\n");
fwrite(&global_state.pt_ip_filter_configured, sizeof(bool)*4, 1, fp);
debug_printf("DUMPING global_state.pt_ip_filter_a: -\n");
fwrite(&global_state.pt_ip_filter_a, sizeof(uint64_t)*4, 1, fp);
debug_printf("DUMPING global_state.pt_ip_filter_b: -\n");
fwrite(&global_state.pt_ip_filter_b, sizeof(uint64_t)*4, 1, fp);
debug_printf("DUMPING global_state.enable_hprintf: %x\n", global_state.enable_hprintf);
fwrite(&global_state.enable_hprintf, sizeof(bool), 1, fp);
debug_printf("DUMPING global_state.parent_cr3: %lx\n", global_state.parent_cr3);
fwrite(&global_state.parent_cr3, sizeof(uint64_t), 1, fp);
debug_printf("DUMPING global_state.disassembler_word_width: %x\n", global_state.disassembler_word_width);
fwrite(&global_state.disassembler_word_width, sizeof(uint8_t), 1, fp);
debug_printf("DUMPING global_state.fast_reload_pre_image: %x\n", global_state.fast_reload_pre_image);
fwrite(&global_state.fast_reload_pre_image, sizeof(bool), 1, fp);
debug_printf("DUMPING global_state.mem_mode: %x\n", global_state.mem_mode);
fwrite(&global_state.mem_mode, sizeof(uint8_t), 1, fp);
debug_printf("DUMPING global_state.pt_trace_mode: %x\n", global_state.pt_trace_mode);
fwrite(&global_state.pt_trace_mode, sizeof(bool), 1, fp);
debug_printf("DUMPING global_state.nested: %x\n", global_state.nested);
fwrite(&global_state.nested, sizeof(bool), 1, fp);
if(!global_state.nested){
debug_printf("DUMPING global_state.payload_buffer: %lx\n", global_state.payload_buffer);
fwrite(&global_state.payload_buffer, sizeof(uint64_t), 1, fp);
fwrite(&global_state.cap_timeout_detection, sizeof(global_state.cap_timeout_detection), 1, fp);
fwrite(&global_state.cap_only_reload_mode, sizeof(global_state.cap_only_reload_mode), 1, fp);
fwrite(&global_state.cap_compile_time_tracing, sizeof(global_state.cap_compile_time_tracing), 1, fp);
fwrite(&global_state.cap_ijon_tracing, sizeof(global_state.cap_ijon_tracing), 1, fp);
fwrite(&global_state.cap_cr3, sizeof(global_state.cap_cr3), 1, fp);
fwrite(&global_state.cap_compile_time_tracing_buffer_vaddr, sizeof(global_state.cap_compile_time_tracing_buffer_vaddr), 1, fp);
fwrite(&global_state.cap_ijon_tracing_buffer_vaddr, sizeof(global_state.cap_ijon_tracing_buffer_vaddr), 1, fp);
fwrite(&global_state.protect_payload_buffer, sizeof(bool), 1, fp);
}
else{
assert(global_state.nested_payload_pages != NULL && global_state.nested_payload_pages_num != 0);
debug_printf("DUMPING global_state.nested_payload_pages_num: %x\n", global_state.nested_payload_pages_num);
fwrite(&global_state.nested_payload_pages_num, sizeof(uint32_t), 1, fp);
if(global_state.nested_payload_pages_num != 0){
debug_printf("DUMPING global_state.protect_payload_buffer: %x\n", global_state.protect_payload_buffer);
fwrite(&global_state.protect_payload_buffer, sizeof(bool), 1, fp);
}
for(uint32_t i = 0; i < global_state.nested_payload_pages_num; i++){
debug_printf("DUMPING global_state.nested_payload_pages[%d]: %lx\n", i, global_state.nested_payload_pages[i]);
fwrite(&global_state.nested_payload_pages[i], sizeof(uint64_t), 1, fp);
}
}
fclose(fp);
free(tmp);
}
void load_global_state(const char* filename_prefix){
debug_printf("%s\n", __func__);
char* tmp;
assert(asprintf(&tmp, "%s/global.state", filename_prefix) != -1);
debug_printf("%s\n", tmp);
FILE *fp = fopen(tmp, "rb");
if(fp == NULL) {
debug_fprintf(stderr, "[%s] Could not open file %s.\n", __func__, tmp);
assert(false);
//exit(EXIT_FAILURE);
}
assert(fread(&global_state.pt_ip_filter_configured, sizeof(bool)*4, 1, fp) == 1);
debug_printf("LOADING global_state.pt_ip_filter_configured: -\n");
assert(fread(&global_state.pt_ip_filter_a, sizeof(uint64_t)*4, 1, fp) == 1);
debug_printf("LOADING global_state.pt_ip_filter_a: -\n");
assert(fread(&global_state.pt_ip_filter_b, sizeof(uint64_t)*4, 1, fp) == 1);
debug_printf("LOADING global_state.pt_ip_filter_b: -\n");
assert(fread(&global_state.enable_hprintf, sizeof(bool), 1, fp) == 1);
debug_printf("LOADING global_state.enable_hprintf: %x\n", global_state.enable_hprintf);
assert(fread(&global_state.parent_cr3, sizeof(uint64_t), 1, fp) == 1);
debug_printf("LOADING global_state.parent_cr3: %lx\n", global_state.parent_cr3);
assert(fread(&global_state.disassembler_word_width, sizeof(uint8_t), 1, fp) == 1);
debug_printf("LOADING global_state.disassembler_word_width: %x\n", global_state.disassembler_word_width);
assert(fread(&global_state.fast_reload_pre_image, sizeof(bool), 1, fp) == 1);
debug_printf("LOADING global_state.fast_reload_pre_image: %x\n", global_state.fast_reload_pre_image);
assert(fread(&global_state.mem_mode, sizeof(uint8_t), 1, fp) == 1);
debug_printf("LOADING global_state.mem_mode: %x\n", global_state.mem_mode);
assert(fread(&global_state.pt_trace_mode, sizeof(bool), 1, fp) == 1);
debug_printf("LOADING global_state.pt_trace_mode: %x\n", global_state.pt_trace_mode);
assert(fread(&global_state.nested, sizeof(bool), 1, fp) == 1);
debug_printf("LOADING global_state.nested: %x\n", global_state.nested);
if(!global_state.nested){
assert(fread(&global_state.payload_buffer, sizeof(uint64_t), 1, fp) == 1);
debug_printf("LOADING global_state.payload_buffer: %lx\n", global_state.payload_buffer);
assert(fread(&global_state.cap_timeout_detection, sizeof(global_state.cap_timeout_detection), 1, fp) == 1);
assert(fread(&global_state.cap_only_reload_mode, sizeof(global_state.cap_only_reload_mode), 1, fp) == 1);
assert(fread(&global_state.cap_compile_time_tracing, sizeof(global_state.cap_compile_time_tracing), 1, fp) == 1);
assert(fread(&global_state.cap_ijon_tracing, sizeof(global_state.cap_ijon_tracing), 1, fp) == 1);
assert(fread(&global_state.cap_cr3, sizeof(global_state.cap_cr3), 1, fp) == 1);
assert(fread(&global_state.cap_compile_time_tracing_buffer_vaddr, sizeof(global_state.cap_compile_time_tracing_buffer_vaddr), 1, fp) == 1);
assert(fread(&global_state.cap_ijon_tracing_buffer_vaddr, sizeof(global_state.cap_ijon_tracing_buffer_vaddr), 1, fp) == 1);
if(!global_state.fast_reload_pre_image){
assert(fread(&global_state.protect_payload_buffer, sizeof(bool), 1, fp) == 1);
if(global_state.payload_buffer != 0){
debug_printf("REMAP PAYLOAD BUFFER!\n");
remap_payload_buffer(global_state.payload_buffer, ((CPUState *)qemu_get_cpu(0)) );
}
else{
fprintf(stderr, "WARNING: address of payload buffer in snapshot file is zero!\n");
}
}
apply_capabilities(qemu_get_cpu(0));
}
else{
assert(fread(&global_state.nested_payload_pages_num, sizeof(uint32_t), 1, fp) == 1);
debug_printf("LOADING global_state.nested_payload_pages_num: %x\n", global_state.nested_payload_pages_num);
global_state.in_fuzzing_mode = true; /* haaaeeeeh ??? */
if(!global_state.fast_reload_pre_image){
assert(fread(&global_state.protect_payload_buffer, sizeof(bool), 1, fp) == 1);
debug_printf("LOADING global_state.protect_payload_buffer: %x\n", global_state.protect_payload_buffer);
global_state.nested_payload_pages = (uint64_t*)malloc(sizeof(uint64_t)*global_state.nested_payload_pages_num);
for(uint32_t i = 0; i < global_state.nested_payload_pages_num; i++){
assert(fread(&global_state.nested_payload_pages[i], sizeof(uint64_t), 1, fp) == 1);
debug_printf("LOADED global_state.nested_payload_pages[%d]: %lx\n", i, global_state.nested_payload_pages[i]);
if(global_state.protect_payload_buffer){
assert(remap_payload_slot_protected(GET_GLOBAL_STATE()->nested_payload_pages[i], i, ((CPUState *)qemu_get_cpu(0))) == true);
}
else{
remap_payload_slot(global_state.nested_payload_pages[i], i, ((CPUState *)qemu_get_cpu(0)));
}
}
}
}
fclose(fp);
free(tmp);
}
static void* alloc_auxiliary_buffer(const char* file){
void* ptr;
struct stat st;
int fd = open(file, O_CREAT|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO);
assert(ftruncate(fd, AUX_BUFFER_SIZE) == 0);
stat(file, &st);
QEMU_PT_PRINTF(INTERFACE_PREFIX, "new aux buffer file: (max size: %x) %lx", AUX_BUFFER_SIZE, st.st_size);
assert(AUX_BUFFER_SIZE == st.st_size);
ptr = mmap(0, AUX_BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
fprintf(stderr, "aux buffer allocation failed!\n");
return (void*)-1;
}
return ptr;
}
void init_aux_buffer(const char* filename){
global_state.auxilary_buffer = (auxilary_buffer_t*)alloc_auxiliary_buffer(filename);
init_auxiliary_buffer(global_state.auxilary_buffer);
}
void set_payload_buffer(uint64_t payload_buffer){
assert(global_state.payload_buffer == 0 && global_state.nested == false);
global_state.payload_buffer = payload_buffer;
global_state.nested = false;
}
void set_payload_pages(uint64_t* payload_pages, uint32_t pages){
assert(global_state.nested_payload_pages == NULL && global_state.nested_payload_pages_num == 0);
global_state.nested_payload_pages = (uint64_t*)malloc(sizeof(uint64_t)*pages);
global_state.nested_payload_pages_num = pages;
memcpy(global_state.nested_payload_pages, payload_pages, sizeof(uint64_t)*pages);
global_state.nested = true;
}
void set_workdir_path(char* workdir){
assert(workdir && !global_state.workdir_path);
assert(asprintf(&global_state.workdir_path, "%s", workdir) != -1);
}

186
nyx/state/snapshot_state.c Normal file
View File

@ -0,0 +1,186 @@
#include "qemu/osdep.h"
#include "sysemu/cpus.h"
#include "nyx/state/snapshot_state.h"
#include "nyx/debug.h"
#include "nyx/state/state.h"
#include "nyx/memory_access.h"
#include <stdio.h>
void serialize_state(const char* filename_prefix, bool is_pre_snapshot){
debug_printf("%s\n", __func__);
char* tmp;
assert(asprintf(&tmp, "%s/global.state", filename_prefix) != -1);
debug_printf("%s\n", tmp);
FILE *fp = fopen(tmp, "wb");
if(fp == NULL) {
debug_fprintf(stderr, "[%s] Could not open file %s.\n", __func__, tmp);
assert(false);
//exit(EXIT_FAILURE);
}
qemu_nyx_state_t* nyx_global_state = GET_GLOBAL_STATE();
debug_printf("DUMPING global_state.pt_ip_filter_configured: -\n");
fwrite(&nyx_global_state->pt_ip_filter_configured, sizeof(bool)*4, 1, fp);
debug_printf("DUMPING global_state.pt_ip_filter_a: -\n");
fwrite(&nyx_global_state->pt_ip_filter_a, sizeof(uint64_t)*4, 1, fp);
debug_printf("DUMPING global_state.pt_ip_filter_b: -\n");
fwrite(&nyx_global_state->pt_ip_filter_b, sizeof(uint64_t)*4, 1, fp);
debug_printf("DUMPING global_state.parent_cr3: %lx\n", global_state.parent_cr3);
fwrite(&nyx_global_state->parent_cr3, sizeof(uint64_t), 1, fp);
debug_printf("DUMPING global_state.disassembler_word_width: %x\n", global_state.disassembler_word_width);
fwrite(&nyx_global_state->disassembler_word_width, sizeof(uint8_t), 1, fp);
debug_printf("DUMPING global_state.fast_reload_pre_image: %x\n", global_state.fast_reload_pre_image);
fwrite(&nyx_global_state->fast_reload_pre_image, sizeof(bool), 1, fp);
debug_printf("DUMPING global_state.mem_mode: %x\n", global_state.mem_mode);
fwrite(&nyx_global_state->mem_mode, sizeof(uint8_t), 1, fp);
debug_printf("DUMPING global_state.pt_trace_mode: %x\n", global_state.pt_trace_mode);
fwrite(&nyx_global_state->pt_trace_mode, sizeof(bool), 1, fp);
debug_printf("DUMPING global_state.nested: %x\n", global_state.nested);
fwrite(&nyx_global_state->nested, sizeof(bool), 1, fp);
if(!global_state.nested){
debug_printf("DUMPING global_state.payload_buffer: %lx\n", global_state.payload_buffer);
fwrite(&nyx_global_state->payload_buffer, sizeof(uint64_t), 1, fp);
fwrite(&nyx_global_state->cap_timeout_detection, sizeof(global_state.cap_timeout_detection), 1, fp);
fwrite(&nyx_global_state->cap_only_reload_mode, sizeof(global_state.cap_only_reload_mode), 1, fp);
fwrite(&nyx_global_state->cap_compile_time_tracing, sizeof(global_state.cap_compile_time_tracing), 1, fp);
fwrite(&nyx_global_state->cap_ijon_tracing, sizeof(global_state.cap_ijon_tracing), 1, fp);
fwrite(&nyx_global_state->cap_cr3, sizeof(global_state.cap_cr3), 1, fp);
fwrite(&nyx_global_state->cap_compile_time_tracing_buffer_vaddr, sizeof(global_state.cap_compile_time_tracing_buffer_vaddr), 1, fp);
fwrite(&nyx_global_state->cap_ijon_tracing_buffer_vaddr, sizeof(global_state.cap_ijon_tracing_buffer_vaddr), 1, fp);
fwrite(&nyx_global_state->protect_payload_buffer, sizeof(bool), 1, fp);
}
else{
assert(global_state.nested_payload_pages != NULL && global_state.nested_payload_pages_num != 0);
debug_printf("DUMPING global_state.nested_payload_pages_num: %x\n", global_state.nested_payload_pages_num);
fwrite(&nyx_global_state->nested_payload_pages_num, sizeof(uint32_t), 1, fp);
if(global_state.nested_payload_pages_num != 0){
debug_printf("DUMPING global_state.protect_payload_buffer: %x\n", global_state.protect_payload_buffer);
fwrite(&nyx_global_state->protect_payload_buffer, sizeof(bool), 1, fp);
}
for(uint32_t i = 0; i < global_state.nested_payload_pages_num; i++){
debug_printf("DUMPING global_state.nested_payload_pages[%d]: %lx\n", i, global_state.nested_payload_pages[i]);
fwrite(&nyx_global_state->nested_payload_pages[i], sizeof(uint64_t), 1, fp);
}
}
fclose(fp);
free(tmp);
}
void deserialize_state(const char* filename_prefix){
debug_printf("%s\n", __func__);
char* tmp;
assert(asprintf(&tmp, "%s/global.state", filename_prefix) != -1);
debug_printf("%s\n", tmp);
FILE *fp = fopen(tmp, "rb");
if(fp == NULL) {
debug_fprintf(stderr, "[%s] Could not open file %s.\n", __func__, tmp);
assert(false);
//exit(EXIT_FAILURE);
}
qemu_nyx_state_t* nyx_global_state = GET_GLOBAL_STATE();
assert(fread(&nyx_global_state->pt_ip_filter_configured, sizeof(bool)*4, 1, fp) == 1);
debug_printf("LOADING global_state.pt_ip_filter_configured: -\n");
assert(fread(&nyx_global_state->pt_ip_filter_a, sizeof(uint64_t)*4, 1, fp) == 1);
debug_printf("LOADING global_state.pt_ip_filter_a: -\n");
assert(fread(&nyx_global_state->pt_ip_filter_b, sizeof(uint64_t)*4, 1, fp) == 1);
debug_printf("LOADING global_state.pt_ip_filter_b: -\n");
assert(fread(&nyx_global_state->parent_cr3, sizeof(uint64_t), 1, fp) == 1);
debug_printf("LOADING global_state.parent_cr3: %lx\n", global_state.parent_cr3);
assert(fread(&nyx_global_state->disassembler_word_width, sizeof(uint8_t), 1, fp) == 1);
debug_printf("LOADING global_state.disassembler_word_width: %x\n", global_state.disassembler_word_width);
assert(fread(&nyx_global_state->fast_reload_pre_image, sizeof(bool), 1, fp) == 1);
debug_printf("LOADING global_state.fast_reload_pre_image: %x\n", global_state.fast_reload_pre_image);
assert(fread(&nyx_global_state->mem_mode, sizeof(uint8_t), 1, fp) == 1);
debug_printf("LOADING global_state.mem_mode: %x\n", global_state.mem_mode);
assert(fread(&nyx_global_state->pt_trace_mode, sizeof(bool), 1, fp) == 1);
debug_printf("LOADING global_state.pt_trace_mode: %x\n", global_state.pt_trace_mode);
assert(fread(&nyx_global_state->nested, sizeof(bool), 1, fp) == 1);
debug_printf("LOADING global_state.nested: %x\n", global_state.nested);
if(!global_state.nested){
assert(fread(&nyx_global_state->payload_buffer, sizeof(uint64_t), 1, fp) == 1);
debug_printf("LOADING global_state.payload_buffer: %lx\n", global_state.payload_buffer);
assert(fread(&nyx_global_state->cap_timeout_detection, sizeof(global_state.cap_timeout_detection), 1, fp) == 1);
assert(fread(&nyx_global_state->cap_only_reload_mode, sizeof(global_state.cap_only_reload_mode), 1, fp) == 1);
assert(fread(&nyx_global_state->cap_compile_time_tracing, sizeof(global_state.cap_compile_time_tracing), 1, fp) == 1);
assert(fread(&nyx_global_state->cap_ijon_tracing, sizeof(global_state.cap_ijon_tracing), 1, fp) == 1);
assert(fread(&nyx_global_state->cap_cr3, sizeof(global_state.cap_cr3), 1, fp) == 1);
assert(fread(&nyx_global_state->cap_compile_time_tracing_buffer_vaddr, sizeof(global_state.cap_compile_time_tracing_buffer_vaddr), 1, fp) == 1);
assert(fread(&nyx_global_state->cap_ijon_tracing_buffer_vaddr, sizeof(global_state.cap_ijon_tracing_buffer_vaddr), 1, fp) == 1);
if(!global_state.fast_reload_pre_image){
assert(fread(&nyx_global_state->protect_payload_buffer, sizeof(bool), 1, fp) == 1);
if(global_state.payload_buffer != 0){
debug_printf("REMAP PAYLOAD BUFFER!\n");
remap_payload_buffer(global_state.payload_buffer, ((CPUState *)qemu_get_cpu(0)) );
}
else{
fprintf(stderr, "WARNING: address of payload buffer in snapshot file is zero!\n");
}
}
assert(apply_capabilities(qemu_get_cpu(0)));
}
else{
assert(fread(&nyx_global_state->nested_payload_pages_num, sizeof(uint32_t), 1, fp) == 1);
debug_printf("LOADING global_state.nested_payload_pages_num: %x\n", global_state.nested_payload_pages_num);
global_state.in_fuzzing_mode = true; /* haaaeeeeh ??? */
if(!global_state.fast_reload_pre_image){
assert(fread(&nyx_global_state->protect_payload_buffer, sizeof(bool), 1, fp) == 1);
debug_printf("LOADING global_state.protect_payload_buffer: %x\n", global_state.protect_payload_buffer);
global_state.nested_payload_pages = (uint64_t*)malloc(sizeof(uint64_t)*global_state.nested_payload_pages_num);
for(uint32_t i = 0; i < global_state.nested_payload_pages_num; i++){
assert(fread(&nyx_global_state->nested_payload_pages[i], sizeof(uint64_t), 1, fp) == 1);
debug_printf("LOADED global_state.nested_payload_pages[%d]: %lx\n", i, global_state.nested_payload_pages[i]);
if(global_state.protect_payload_buffer){
assert(remap_payload_slot_protected(GET_GLOBAL_STATE()->nested_payload_pages[i], i, ((CPUState *)qemu_get_cpu(0))) == true);
}
else{
remap_payload_slot(global_state.nested_payload_pages[i], i, ((CPUState *)qemu_get_cpu(0)));
}
}
}
}
fclose(fp);
free(tmp);
}

View File

@ -0,0 +1,6 @@
#pragma once
#include <stdbool.h>
void serialize_state(const char* filename_prefix, bool is_pre_snapshot);
void deserialize_state(const char* filename_prefix);

233
nyx/state/state.c Normal file
View File

@ -0,0 +1,233 @@
/*
Copyright (C) 2019 Sergej Schumilo
This file is part of QEMU-PT (HyperTrash / kAFL).
QEMU-PT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QEMU-PT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
*/
#include "nyx/state/state.h"
#include "nyx/debug.h"
#include "nyx/memory_access.h"
#include "sysemu/kvm.h"
#include "nyx/auxiliary_buffer.h"
#include "nyx/sharedir.h"
#include "nyx/fast_vm_reload_sync.h"
#include "nyx/helpers.h"
//#define STATE_VERBOSE
/* global singleton */
qemu_nyx_state_t global_state;
#define LIBXDC_RELEASE_VERSION_REQUIRED 2
void state_init_global(void){
#ifdef STATE_VERBOSE
fprintf(stderr, "--> %s <--\n", __func__);
#endif
/* safety first */
assert(libxdc_get_release_version() == LIBXDC_RELEASE_VERSION_REQUIRED);
global_state.nyx_fdl = false;
global_state.workdir_path = NULL;
global_state.fast_reload_enabled = false;
global_state.fast_reload_mode = false;
global_state.fast_reload_path = NULL;
global_state.fast_reload_pre_path = NULL;
global_state.fast_reload_pre_image = false;
global_state.fast_reload_snapshot = fast_reload_new();
global_state.reload_state = init_fast_vm_reload_sync();
global_state.decoder = NULL;
global_state.page_cache = NULL;
global_state.redqueen_enable_pending = false;
global_state.redqueen_disable_pending = false;
global_state.redqueen_instrumentation_mode = 0;
global_state.redqueen_update_blacklist = false;
global_state.patches_enable_pending = false;
global_state.patches_disable_pending = false;
global_state.redqueen_state = NULL;
for(uint8_t i = 0; i < INTEL_PT_MAX_RANGES; i++){
global_state.pt_ip_filter_configured[i] = false;
global_state.pt_ip_filter_enabled[i] = false;
global_state.pt_ip_filter_a[i] = 0x0;
global_state.pt_ip_filter_b[i] = 0x0;
}
global_state.pt_c3_filter = 0;
global_state.parent_cr3 = 0;
global_state.disassembler_word_width = 64;
global_state.nested = false;
global_state.payload_buffer = 0;
global_state.nested_payload_pages = NULL;
global_state.nested_payload_pages_num = 0;
global_state.protect_payload_buffer = 0;
global_state.discard_tmp_snapshot = 0;
global_state.mem_mode = mm_unkown;
init_timeout_detector(&(global_state.timeout_detector));
global_state.in_fuzzing_mode = false;
global_state.in_reload_mode = true;
global_state.shutdown_requested = false;
global_state.cow_cache_full = false;
global_state.auxilary_buffer = NULL;
memset(&global_state.shadow_config, 0x0, sizeof(auxilary_buffer_config_t));
global_state.decoder_page_fault = false;
global_state.decoder_page_fault_addr = 0x0;
global_state.dump_page = false;
global_state.dump_page_addr = 0x0;
global_state.in_redqueen_reload_mode = false;
global_state.pt_trace_mode = true;
global_state.pt_trace_mode_force = false;
global_state.num_dirty_pages = 0;
global_state.sharedir = sharedir_new();
global_state.shared_bitmap_fd = 0;
global_state.shared_bitmap_size = 0;
global_state.shared_bitmap_real_size = 0;
global_state.shared_bitmap_ptr = NULL;
global_state.shared_payload_buffer_fd = 0;
global_state.shared_payload_buffer_size = 0;
global_state.shared_ijon_bitmap_fd = 0;
global_state.shared_ijon_bitmap_size = 0;
global_state.shared_ijon_bitmap_ptr = NULL;
global_state.pt_trace_size = 0;
global_state.bb_coverage = 0;
global_state.cap_timeout_detection = 0;
global_state.cap_only_reload_mode = 0;
global_state.cap_compile_time_tracing = 0;
global_state.cap_ijon_tracing = 0;
global_state.cap_cr3 = 0;
global_state.cap_compile_time_tracing_buffer_vaddr = 0;
global_state.cap_ijon_tracing_buffer_vaddr = 0;
QTAILQ_INIT(&global_state.redqueen_breakpoints);
}
fast_reload_t* get_fast_reload_snapshot(void){
return global_state.fast_reload_snapshot;
}
void set_fast_reload_mode(bool mode){
global_state.fast_reload_mode = mode;
}
void set_fast_reload_path(const char* path){
assert(global_state.fast_reload_path == NULL);
global_state.fast_reload_path = malloc(strlen(path)+1);
strcpy(global_state.fast_reload_path, path);
}
void set_fast_reload_pre_path(const char* path){
assert(global_state.fast_reload_pre_path == NULL);
global_state.fast_reload_pre_path = malloc(strlen(path)+1);
strcpy(global_state.fast_reload_pre_path, path);
}
void set_fast_reload_pre_image(void){
assert(global_state.fast_reload_pre_path != NULL);
global_state.fast_reload_pre_image = true;
}
void enable_fast_reloads(void){
assert(global_state.fast_reload_path != NULL);
global_state.fast_reload_enabled = true;
}
void init_page_cache(char* path){
assert(global_state.page_cache == NULL);
global_state.page_cache = page_cache_new((CPUState *)qemu_get_cpu(0), path);
#ifdef STATE_VERBOSE
debug_printf("\n\nINIT PAGE_CACHE => %s\n", path);
#endif
}
page_cache_t* get_page_cache(void){
assert(global_state.page_cache);
return global_state.page_cache;
}
void init_redqueen_state(void){
global_state.redqueen_state = new_rq_state((CPUState *)qemu_get_cpu(0), get_page_cache());
}
redqueen_t* get_redqueen_state(void){
assert(global_state.redqueen_state != NULL);
return global_state.redqueen_state;
}
static void* alloc_auxiliary_buffer(const char* file){
void* ptr;
struct stat st;
int fd = open(file, O_CREAT|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO);
assert(ftruncate(fd, AUX_BUFFER_SIZE) == 0);
stat(file, &st);
QEMU_PT_PRINTF(INTERFACE_PREFIX, "new aux buffer file: (max size: %x) %lx", AUX_BUFFER_SIZE, st.st_size);
assert(AUX_BUFFER_SIZE == st.st_size);
ptr = mmap(0, AUX_BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
fprintf(stderr, "aux buffer allocation failed!\n");
return (void*)-1;
}
return ptr;
}
void init_aux_buffer(const char* filename){
global_state.auxilary_buffer = (auxilary_buffer_t*)alloc_auxiliary_buffer(filename);
init_auxiliary_buffer(global_state.auxilary_buffer);
}
void set_payload_buffer(uint64_t payload_buffer){
assert(global_state.payload_buffer == 0 && global_state.nested == false);
global_state.payload_buffer = payload_buffer;
global_state.nested = false;
}
void set_payload_pages(uint64_t* payload_pages, uint32_t pages){
assert(global_state.nested_payload_pages == NULL && global_state.nested_payload_pages_num == 0);
global_state.nested_payload_pages = (uint64_t*)malloc(sizeof(uint64_t)*pages);
global_state.nested_payload_pages_num = pages;
memcpy(global_state.nested_payload_pages, payload_pages, sizeof(uint64_t)*pages);
global_state.nested = true;
}
void set_workdir_path(char* workdir){
assert(workdir && !global_state.workdir_path);
assert(asprintf(&global_state.workdir_path, "%s", workdir) != -1);
}

View File

@ -43,7 +43,7 @@ enum mem_mode {
mm_64_l5_paging, /* 32 Bit / L5 Paging */
};
struct state_qemu_pt{
typedef struct qemu_nyx_state_s{
/* set if FDL backend is used (required to perform some additional runtime tests) */
bool nyx_fdl;
@ -91,11 +91,16 @@ struct state_qemu_pt{
/* mmap Options (not migratable) */
int shared_bitmap_fd;
uint32_t shared_bitmap_size;
uint32_t shared_ijon_bitmap_size;
uint32_t shared_bitmap_size; /* size of the shared memory file */
uint32_t shared_bitmap_real_size; /* actual size of the bitmap */
void* shared_bitmap_ptr;
int shared_payload_buffer_fd;
uint32_t shared_payload_buffer_size;
void* shared_bitmap_ptr;
int shared_ijon_bitmap_fd;
uint32_t shared_ijon_bitmap_size;
void* shared_ijon_bitmap_ptr;
/* Intel PT Options (migratable) */
bool pt_ip_filter_configured[4];
@ -103,7 +108,6 @@ struct state_qemu_pt{
uint64_t pt_ip_filter_b[4];
/* OPTIONS (MIGRATABLE VIA FAST SNAPSHOTS) */
bool enable_hprintf;
uint64_t parent_cr3;
uint8_t disassembler_word_width;
bool nested;
@ -132,6 +136,8 @@ struct state_qemu_pt{
bool in_redqueen_reload_mode;
uint32_t num_dirty_pages;
/* capabilites */
uint8_t cap_timeout_detection;
uint8_t cap_only_reload_mode;
@ -146,9 +152,9 @@ struct state_qemu_pt{
sharedir_t* sharedir;
QTAILQ_HEAD(, kvm_sw_breakpoint) redqueen_breakpoints;
};
} qemu_nyx_state_t;
extern struct state_qemu_pt global_state;
extern qemu_nyx_state_t global_state;
#define GET_GLOBAL_STATE() (&global_state)
@ -169,9 +175,6 @@ void init_redqueen_state(void);
redqueen_t* get_redqueen_state(void);
void dump_global_state(const char* filename_prefix);
void load_global_state(const char* filename_prefix);
void init_aux_buffer(const char* filename);
void set_fast_reload_pre_path(const char* path);

View File

@ -8,7 +8,7 @@
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "nyx/debug.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include <sys/syscall.h>
#include <linux/kvm.h>
#include "qemu/main-loop.h"
@ -214,6 +214,7 @@ static inline bool synchronization_check_page_not_found(void){
kvm_remove_all_breakpoints(qemu_get_cpu(0));
kvm_vcpu_ioctl(qemu_get_cpu(0), KVM_VMX_PT_DISABLE_PAGE_DUMP_CR3);
kvm_vcpu_ioctl(qemu_get_cpu(0), KVM_VMX_PT_DISABLE_MTF);
reset_page_not_found_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer);
failure = true;
}
@ -241,9 +242,6 @@ void synchronization_lock_hprintf(void){
pthread_cond_wait(&synchronization_lock_condition, &synchronization_lock_mutex);
pthread_mutex_unlock(&synchronization_lock_mutex);
flush_hprintf_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer);
}
void synchronization_lock(void){
@ -255,7 +253,8 @@ void synchronization_lock(void){
}
set_exec_done_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer,
GET_GLOBAL_STATE()->timeout_detector.timeout_sec - GET_GLOBAL_STATE()->timeout_detector.arm_timeout.it_value.tv_sec,
GET_GLOBAL_STATE()->timeout_detector.timeout_usec - (uint32_t)GET_GLOBAL_STATE()->timeout_detector.arm_timeout.it_value.tv_usec);
GET_GLOBAL_STATE()->timeout_detector.timeout_usec - (uint32_t)GET_GLOBAL_STATE()->timeout_detector.arm_timeout.it_value.tv_usec,
GET_GLOBAL_STATE()->num_dirty_pages);
/*
if(last_timeout){
reset_timeout_detector_timeout(&(GET_GLOBAL_STATE()->timeout_detector));
@ -291,7 +290,6 @@ void synchronization_lock(void){
pthread_cond_wait(&synchronization_lock_condition, &synchronization_lock_mutex);
pthread_mutex_unlock(&synchronization_lock_mutex);
flush_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer);
check_auxiliary_config_buffer(GET_GLOBAL_STATE()->auxilary_buffer, &GET_GLOBAL_STATE()->shadow_config);
set_success_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, 1);
@ -337,25 +335,6 @@ void synchronization_lock_crash_found(void){
in_fuzzing_loop = false;
}
void synchronization_lock_asan_found(void){
if(!in_fuzzing_loop){
fprintf(stderr, "<%d-%ld>\t%s [NOT IN FUZZING LOOP]\n", getpid(), run_counter, __func__);
set_success_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, 0);
}
pt_disable(qemu_get_cpu(0), false);
handle_tmp_snapshot_state();
set_asan_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer);
perform_reload();
//synchronization_lock();
in_fuzzing_loop = false;
}
void synchronization_lock_timeout_found(void){
//fprintf(stderr, "<%d>\t%s\n", getpid(), __func__);

View File

@ -37,7 +37,6 @@ void synchronization_lock_hprintf(void);
void synchronization_lock(void);
void synchronization_lock_crash_found(void);
void synchronization_lock_asan_found(void);
void synchronization_lock_timeout_found(void);
void synchronization_lock_shutdown_detected(void);
void synchronization_cow_full_detected(void);

View File

@ -60,7 +60,7 @@
#endif
#ifdef QEMU_NYX
#include "nyx/state.h"
#include "nyx/state/state.h"
#endif
#include "disas/capstone.h"

2
vl.c
View File

@ -137,7 +137,7 @@ int main(int argc, char **argv)
#include "nyx/hypercall/hypercall.h"
#include "nyx/synchronization.h"
#include "nyx/fast_vm_reload.h"
#include "nyx/state.h"
#include "nyx/state/state.h"
#include "nyx/fast_vm_reload_sync.h"
#endif