disable unused hypercalls

This commit is contained in:
Sergej Schumilo 2022-01-11 04:16:34 +01:00
parent 6105067351
commit dd9f586327
8 changed files with 131 additions and 289 deletions

View File

@ -46,7 +46,7 @@
#ifdef QEMU_NYX
#include "nyx/pt.h"
#include "nyx/hypercall.h"
#include "nyx/hypercall/hypercall.h"
#include "nyx/synchronization.h"
#include "nyx/debug.h"
#include "nyx/state.h"

112
nyx/hypercall/debug.c Normal file
View File

@ -0,0 +1,112 @@
#include "qemu/osdep.h"
#include <sys/time.h>
#include "nyx/synchronization.h"
#include "nyx/fast_vm_reload.h"
#include "nyx/state.h"
#include "nyx/hypercall/debug.h"
//#define NYX_ENABLE_DEBUG_HYPERCALLS
#ifdef NYX_ENABLE_DEBUG_HYPERCALLS
static double get_time(void){
struct timeval t;
struct timezone tzp;
gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6;
}
static void print_time_diff(int iterations){
static bool init = true;
static double start_time = 0.0;
static double end_time = 0.0;
if(init){
init = false;
printf("start time is zero!\n");
start_time = get_time();
}
else{
end_time = get_time();
double elapsed_time = end_time - start_time;
printf("Done in %f seconds\n", elapsed_time);
printf("Performance: %f\n", iterations/elapsed_time);
start_time = get_time();
}
}
static void meassure_performance(void){
static int perf_counter = 0;
if ((perf_counter%1000) == 0){
//printf("perf_counter -> %d \n", perf_counter);
print_time_diff(1000);
}
perf_counter++;
}
void handle_hypercall_kafl_debug_tmp_snapshot(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
//X86CPU *x86_cpu = X86_CPU(cpu);
//CPUX86State *env = &x86_cpu->env;
static bool first = true;
//printf("CALLED %s: %lx\n", __func__, hypercall_arg);
switch(hypercall_arg&0xFFF){
case 0: /* create root snapshot */
if(!fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_ROOT_EXISTS)){
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_ROOT);
}
break;
case 1: /* create tmp snapshot */
//printf("%s: create tmp...(RIP: %lx)\n", __func__, get_rip(cpu));
if(!fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_TMP_EXISTS)){
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_TMP);
}
break;
case 2: /* load root snapshot (+ discard tmp snapshot) */
//printf("%s: load root...(RIP: %lx)\n", __func__, get_rip(cpu));
if(fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_TMP_EXISTS)){
reload_request_discard_tmp(GET_GLOBAL_STATE()->reload_state);
}
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_LOAD_SNAPSHOT_ROOT);
meassure_performance();
break;
case 3: /* load tmp snapshot */
if(fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_TMP_EXISTS)){
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_LOAD_SNAPSHOT_TMP);
meassure_performance();
}
break;
case 5: // firefox debug hypercall
if(first){
first = false;
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_ROOT);
//request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_TMP);
break;
}
else{
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_LOAD_SNAPSHOT_ROOT);
break;
}
/*
case 6:
printf("%s: -> request to add 0x%lx to block-list\n", __func__, hypercall_arg&(~0xFFF));
CPUX86State *env = &(X86_CPU(cpu))->env;
kvm_arch_get_registers_fast(cpu);
hwaddr phys_addr = (hwaddr) get_paging_phys_addr(cpu, env->cr[3], hypercall_arg&(~0xFFF));
fast_reload_blacklist_page(get_fast_reload_snapshot(), phys_addr);
break;
*/
default:
abort();
}
}
#else
void handle_hypercall_kafl_debug_tmp_snapshot(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
fprintf(stderr, "[QEMU-Nyx] Error: This hypercall (HYPERCALL_KAFL_DEBUG_TMP) is not enabled!\n");
set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, (char*)"Disabled debug hypercall called...", strlen("Disabled debug hypercall called..."));
synchronization_lock();
}
#endif

3
nyx/hypercall/debug.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void handle_hypercall_kafl_debug_tmp_snapshot(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg);

View File

@ -56,6 +56,7 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#include "nyx/redqueen.h"
#include "nyx/hypercall/configuration.h"
#include "nyx/hypercall/debug.h"
//#define DEBUG_HPRINTF
@ -65,7 +66,6 @@ bool notifiers_enabled = false;
bool hypercall_enabled = false;
void* program_buffer = NULL;
char info_buffer[INFO_SIZE];
char hprintf_buffer[HPRINTF_SIZE];
static bool init_state = true;
@ -322,47 +322,9 @@ static void handle_hypercall_kafl_range_submit(struct kvm_run *run, CPUState *cp
}
static void handle_hypercall_get_program(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
//fprintf(stderr, "%s\n", __func__);
/*
return;
if(!get_fast_reload_snapshot()->qemu_state){
fast_reload_create_in_memory(get_fast_reload_snapshot(), true);
}
*/
/*
qemu_mutex_lock_iothread();
fast_reload_restore(get_fast_reload_snapshot());
qemu_mutex_unlock_iothread();
return;
*/
kvm_arch_get_registers(cpu);
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = &x86_cpu->env;
if(hypercall_enabled){
if(program_buffer){
if (env->cr[4] & CR4_PAE_MASK) {
if (env->hflags & HF_LMA_MASK) {
//fprintf(stderr, "IN 64Bit MODE\n");
}
else{
debug_fprintf(stderr, "IN 32Bit PAE MODE\n");
abort();
}
}
else{
debug_fprintf(stderr, "IN 32Bit MODE\n");
abort();
}
//print_48_paging2(env->cr[3]);
write_virtual_memory(hypercall_arg, program_buffer, PROGRAM_SIZE, cpu);
}
}
fprintf(stderr, "[QEMU-Nyx] Error: This hypercall (HYPERCALL_KAFL_GET_PAYLOAD) is deprecated -> use ./hget instead!\n");
set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, (char*)"Deprecated hypercall called...", strlen("Deprecated hypercall called..."));
synchronization_lock();
}
@ -546,100 +508,6 @@ static void handle_hypercall_kafl_panic(struct kvm_run *run, CPUState *cpu, uint
}
}
static double get_time(void){
struct timeval t;
struct timezone tzp;
gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6;
}
static void print_time_diff(int iterations){
static bool init = true;
static double start_time = 0.0;
static double end_time = 0.0;
if(init){
init = false;
printf("start time is zero!\n");
start_time = get_time();
}
else{
end_time = get_time();
double elapsed_time = end_time - start_time;
printf("Done in %f seconds\n", elapsed_time);
printf("Performance: %f\n", iterations/elapsed_time);
start_time = get_time();
}
}
static void meassure_performance(void){
static int perf_counter = 0;
if ((perf_counter%1000) == 0){
//printf("perf_counter -> %d \n", perf_counter);
print_time_diff(1000);
}
perf_counter++;
}
static void handle_hypercall_kafl_debug_tmp_snapshot(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
//X86CPU *x86_cpu = X86_CPU(cpu);
//CPUX86State *env = &x86_cpu->env;
static bool first = true;
//printf("CALLED %s: %lx\n", __func__, hypercall_arg);
switch(hypercall_arg&0xFFF){
case 0: /* create root snapshot */
if(!fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_ROOT_EXISTS)){
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_ROOT);
}
break;
case 1: /* create tmp snapshot */
//printf("%s: create tmp...(RIP: %lx)\n", __func__, get_rip(cpu));
if(!fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_TMP_EXISTS)){
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_TMP);
}
break;
case 2: /* load root snapshot (+ discard tmp snapshot) */
//printf("%s: load root...(RIP: %lx)\n", __func__, get_rip(cpu));
if(fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_TMP_EXISTS)){
reload_request_discard_tmp(GET_GLOBAL_STATE()->reload_state);
}
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_LOAD_SNAPSHOT_ROOT);
//meassure_performance();
break;
case 3: /* load tmp snapshot */
if(fast_snapshot_exists(GET_GLOBAL_STATE()->reload_state, REQUEST_TMP_EXISTS)){
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_LOAD_SNAPSHOT_TMP);
//meassure_performance();
}
break;
case 5: // firefox debug hypercall
if(first){
first = false;
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_ROOT);
//request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_SAVE_SNAPSHOT_TMP);
break;
}
else{
request_fast_vm_reload(GET_GLOBAL_STATE()->reload_state, REQUEST_LOAD_SNAPSHOT_ROOT);
break;
}
/*
case 6:
printf("%s: -> request to add 0x%lx to block-list\n", __func__, hypercall_arg&(~0xFFF));
CPUX86State *env = &(X86_CPU(cpu))->env;
kvm_arch_get_registers_fast(cpu);
hwaddr phys_addr = (hwaddr) get_paging_phys_addr(cpu, env->cr[3], hypercall_arg&(~0xFFF));
fast_reload_blacklist_page(get_fast_reload_snapshot(), phys_addr);
break;
*/
default:
abort();
}
}
static void handle_hypercall_kafl_create_tmp_snapshot(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
//X86CPU *x86_cpu = X86_CPU(cpu);
//CPUX86State *env = &x86_cpu->env;
@ -647,7 +515,6 @@ static void handle_hypercall_kafl_create_tmp_snapshot(struct kvm_run *run, CPUSt
/* decode PT data */
pt_disable(qemu_get_cpu(0), false);
pt_sync();
/*
kvm_arch_get_registers(cpu);
@ -764,84 +631,23 @@ qemu_mutex_lock_iothread();
}
static void handle_hypercall_kafl_info(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
if(setup_snapshot_once)
return;
debug_printf("%s\n", __func__);
/*
printf("[*] EXEC: %s\t%lx %lx\n", __func__, get_rip(cpu), get_rsp(cpu));
hexdump_virtual_memory(get_rsp(cpu), 0x100, cpu);
kvm_arch_get_registers(cpu);
kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
*/
/*
qemu_mutex_lock_iothread();
//fast_reload_restore((fast_reload_t*)cpu->fast_reload_snapshot);
fast_reload_restore(get_fast_reload_snapshot());
//kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
qemu_mutex_unlock_iothread();
return;
*/
/*
kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
printf("[*] EXIT: %s\t%lx %lx\n", __func__, get_rip(cpu), get_rsp(cpu));
hexdump_virtual_memory(get_rsp(cpu), 0x100, cpu);
*/
// return;
read_virtual_memory(hypercall_arg, (uint8_t*)info_buffer, INFO_SIZE, cpu);
FILE* info_file_fd = fopen(INFO_FILE, "w");
fprintf(info_file_fd, "%s\n", info_buffer);
fclose(info_file_fd);
if(hypercall_enabled){
//hypercall_snd_char(KAFL_PROTO_INFO);
QEMU_PT_PRINTF_DEBUG("Protocol - SEND: KAFL_PROTO_INFO");
abort();
}
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
fprintf(stderr, "[QEMU-Nyx] Error: This hypercall (HYPERCALL_KAFL_INFO) is deprecated -> use hprintf() & ./habort instead!\n");
set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, (char*)"Deprecated hypercall called...", strlen("Deprecated hypercall called..."));
synchronization_lock();
}
void enable_notifies(void){
notifiers_enabled = true;
}
/*
void hprintf(char* msg){
char file_name[256];
if(!(hprintf_counter >= HPRINTF_LIMIT) && GET_GLOBAL_STATE()->enable_hprintf){
if(hypercall_enabled){
snprintf(file_name, 256, "%s.%d", HPRINTF_FILE, hprintf_counter);
//printf("%s: %s\n", __func__, msg);
FILE* printf_file_fd = fopen(file_name, "w");
fprintf(printf_file_fd, "%s", msg);
fclose(printf_file_fd);
//hypercall_snd_char(KAFL_PROTO_PRINTF);
QEMU_PT_PRINTF_DEBUG("Protocol - SEND: KAFL_PROTO_PRINTF");
}
hprintf_counter++;
}
}
*/
static void handle_hypercall_kafl_printf(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg){
//fprintf(stderr, "%s\n", __func__);
//if( /* !(hprintf_counter >= HPRINTF_LIMIT) && */ GET_GLOBAL_STATE()->enable_hprintf){ // && !GET_GLOBAL_STATE()->in_fuzzing_mode){
read_virtual_memory(hypercall_arg, (uint8_t*)hprintf_buffer, HPRINTF_SIZE, cpu);
//hprintf(hprintf_buffer);
read_virtual_memory(hypercall_arg, (uint8_t*)hprintf_buffer, HPRINTF_SIZE, cpu);
#ifdef DEBUG_HPRINTF
fprintf(stderr, "%s %s\n", __func__, hprintf_buffer);
fprintf(stderr, "%s %s\n", __func__, hprintf_buffer);
#else
set_hprintf_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, hprintf_buffer, strnlen(hprintf_buffer, HPRINTF_SIZE)+1);
synchronization_lock();
set_hprintf_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, hprintf_buffer, strnlen(hprintf_buffer, HPRINTF_SIZE)+1);
synchronization_lock();
#endif
//}
}

View File

@ -2,7 +2,7 @@
#include <linux/kvm.h>
#include "qemu-common.h"
#include "nyx/memory_access.h"
#include "nyx/hypercall.h"
#include "nyx/hypercall/hypercall.h"
#include "nyx/printk.h"
enum reg_types{RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15, RIP};

View File

@ -44,11 +44,6 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#define PT_BUFFER_MMAP_ADDR 0x3ffff0000000
/*
extern uint32_t kafl_bitmap_size;
uint8_t* bitmap = NULL;
*/
uint32_t state_byte = 0;
uint32_t last = 0;
@ -69,14 +64,6 @@ void pt_trucate_pt_trace_file(void){
}
}
void pt_sync(void){
/*
if(bitmap){
msync(bitmap, kafl_bitmap_size, MS_SYNC);
}
*/
}
static void pt_set(CPUState *cpu, run_on_cpu_data arg){
asm volatile("" ::: "memory");
}
@ -111,59 +98,12 @@ static inline int pt_ioctl(int fd, unsigned long request, unsigned long arg){
return ioctl(fd, request, arg);
}
/*
void pt_setup_bitmap(void* ptr){
bitmap = (uint8_t*)ptr;
}
void pt_reset_bitmap(void){
if(bitmap){
state_byte = 0;
last = 0;
memset(bitmap, 0x00, kafl_bitmap_size);
}
}
*/
static inline uint64_t mix_bits(uint64_t v) {
v ^= (v >> 31);
v *= 0x7fb5d329728ea185;
/*
v ^= (v >> 27);
v *= 0x81dadef4bc2dd44d;
v ^= (v >> 33);
*/
return v;
}
/*
void pt_bitmap(uint64_t from, uint64_t to){
//if(to == 0x400965 || (last == 0x400965 && to == 0x40087A)){
// last = to;
// state_byte = mix_bits(state_byte)^to;
// bitmap[state_byte & (kafl_bitmap_size-1)]++;
//}
//printf("from: %lx\tto: %lx\n", from, to);
uint32_t transition_value = 0;
#ifdef SAMPLE_DECODED
sample_decoded(from,to);
#endif
if(bitmap){
transition_value = mix_bits(to)^(mix_bits(from)>>1);
//
//if ((from == 0x7ffff7884e8f && to == 0x7ffff7884eff) || (from == 0x7ffff7884f10 && to == 0x7ffff7884f12) || (from == 0x7ffff7884f14 && to == 0x7ffff7884e80)){
// return;
//}
//fprintf(stderr, "%lx %lx %x\n", from, to, check_bitmap_byte(transition_value & (kafl_bitmap_size-1)));
if (check_bitmap_byte(transition_value & (kafl_bitmap_size-1)) == 0)
bitmap[transition_value & (kafl_bitmap_size-1)]++;
}
}
*/
#ifdef DUMP_AND_DEBUG_PT
void dump_pt_trace(void* buffer, int bytes){
static FILE* f = NULL;
@ -497,13 +437,3 @@ void pt_post_kvm_run(CPUState *cpu){
//}
}
}
/*
void pt_sync_kvm_run_lock(void){
pthread_mutex_lock(&pt_dump_mutex);
}
void pt_sync_kvm_run_unlock(void){
pthread_mutex_unlock(&pt_dump_mutex);
}
*/

View File

@ -24,7 +24,6 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
void pt_init_decoder(CPUState *cpu);
void pt_sync(void);
void pt_reset_bitmap(void);
void pt_setup_bitmap(void* ptr);

View File

@ -1,5 +1,5 @@
#include "nyx/synchronization.h"
#include "nyx/hypercall.h"
#include "nyx/hypercall/hypercall.h"
#include "nyx/interface.h"
#include "nyx/fast_vm_reload.h"
#include "qemu-common.h"
@ -237,7 +237,7 @@ bool in_fuzzing_loop = false;
void synchronization_lock_hprintf(void){
pthread_mutex_lock(&synchronization_lock_mutex);
interface_send_char(KAFL_PING);
interface_send_char(NYX_INTERFACE_PING);
pthread_cond_wait(&synchronization_lock_condition, &synchronization_lock_mutex);
pthread_mutex_unlock(&synchronization_lock_mutex);
@ -286,8 +286,7 @@ void synchronization_lock(void){
fsync_all_traces();
}
interface_send_char(KAFL_PING);
//QEMU_PT_PRINTF_DEBUG("Protocol - SEND: KAFL_PING");
interface_send_char(NYX_INTERFACE_PING);
pthread_cond_wait(&synchronization_lock_condition, &synchronization_lock_mutex);
pthread_mutex_unlock(&synchronization_lock_mutex);
@ -326,7 +325,6 @@ void synchronization_lock_crash_found(void){
}
pt_disable(qemu_get_cpu(0), false);
pt_sync();
handle_tmp_snapshot_state();
@ -346,7 +344,6 @@ void synchronization_lock_asan_found(void){
}
pt_disable(qemu_get_cpu(0), false);
pt_sync();
handle_tmp_snapshot_state();
@ -369,7 +366,6 @@ void synchronization_lock_timeout_found(void){
}
pt_disable(qemu_get_cpu(0), false);
pt_sync();
handle_tmp_snapshot_state();
@ -388,7 +384,6 @@ void synchronization_lock_shutdown_detected(void){
}
pt_disable(qemu_get_cpu(0), false);
pt_sync();
handle_tmp_snapshot_state();
@ -406,7 +401,6 @@ void synchronization_payload_buffer_write_detected(void){
}
pt_disable(qemu_get_cpu(0), false);
pt_sync();
handle_tmp_snapshot_state();
@ -426,7 +420,6 @@ void synchronization_cow_full_detected(void){
}
pt_disable(qemu_get_cpu(0), false);
pt_sync();
handle_tmp_snapshot_state();
@ -450,7 +443,6 @@ void synchronization_disable_pt(CPUState *cpu){
}
pt_disable(qemu_get_cpu(0), false);
pt_sync();
handle_tmp_snapshot_state();