/* * QEMU System Emulator * * Copyright (c) 2003-2020 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "qemu/osdep.h" #include "qemu-common.h" #include "sysemu/sysemu.h" #ifdef CONFIG_SDL #if defined(__APPLE__) || defined(main) #include static int qemu_main(int argc, char **argv, char **envp); int main(int argc, char **argv) { return qemu_main(argc, argv, NULL); } #undef main #define main qemu_main #endif #endif /* CONFIG_SDL */ #ifdef CONFIG_COCOA #undef main #define main qemu_main #endif /* CONFIG_COCOA */ /* Begin LibAFL instrumentation */ #include "sysemu/runstate.h" #include "sysemu/cpu-timers.h" #include "migration/snapshot.h" #include "hw/core/cpu.h" #include "qapi/error.h" #include "exec/memory.h" void libafl_qemu_main_loop( void ); void libafl_qemu_run( void ); void libafl_qemu_sys_init(int argc, char **argv, char **envp); void libafl_qemu_cleanup( void ); void libafl_qemu_sys_init(int argc, char **argv, char **envp) { qemu_init(argc, argv, envp); } void libafl_qemu_cleanup( void ) { qemu_cleanup(); } void libafl_qemu_set_native_breakpoint( vaddr ); void libafl_qemu_remove_native_breakpoint( vaddr ); int libafl_snapshot_save( const char* ); int libafl_snapshot_load( const char* ); void libafl_phys_read(vaddr, uint8_t*, int); void libafl_phys_write(vaddr, uint8_t*, int); int64_t libafl_get_clock( void ); #ifdef TARGET_ARM extern void libafl_start_int_timer(void); #endif void libafl_qemu_main_loop( void ) { #ifdef TARGET_ARM libafl_start_int_timer(); #endif vm_start(); qemu_main_loop(); } void libafl_qemu_run( void ) { libafl_qemu_main_loop(); } void libafl_qemu_set_native_breakpoint(vaddr pc) { CPUState *cpu; CPU_FOREACH(cpu) { cpu_breakpoint_insert(cpu, pc, BP_GDB, NULL); } } void libafl_qemu_remove_native_breakpoint(vaddr pc) { CPUState *cpu; CPU_FOREACH(cpu) { cpu_breakpoint_remove(cpu, pc, BP_GDB); } } int libafl_snapshot_save( const char* name ) { Error *err = NULL; save_snapshot(name, true, NULL, false, NULL, &err); return err == 0; } int libafl_snapshot_load( const char* name ) { Error *err = NULL; load_snapshot(name, NULL, false, NULL, &err); return err == 0; } void libafl_phys_read(vaddr addr, uint8_t* buf, int len) { cpu_physical_memory_read(addr, buf, len); } void libafl_phys_write(vaddr addr, uint8_t* buf, int len) { cpu_physical_memory_write(addr, buf, len); } int64_t libafl_get_clock( void ) { return icount_get_raw(); } #ifndef AS_SHARED_LIB #ifdef TARGET_ARM extern unsigned int libafl_int_offset; #endif int main(int argc, char **argv, char **envp) { qemu_init(argc, argv, envp); qemu_main_loop(); qemu_cleanup(); //LIBAFL Instrumentation Demo /* // unsigned char buf[32] = "_`abcdefghijklmnopqrstuvwxyz{|}~"; #ifdef TARGET_ARM libafl_int_offset = 375000; #endif // unsigned char buf[32] = "\x02\x9b\x02\x9b\x02\x9b\x02\x9b"; // 0xFA71 x 4 unsigned char buf[32] = "\x05\x29\x07\x1f\x0b\x17\x01\x17"; // 5*73 7*59 11*43 unsigned char len = 8; libafl_qemu_sys_init(argc, argv, envp); int pheader = 0x5be4; libafl_phys_write(0x20000110-0x20000100+pheader, buf,32); libafl_phys_read(0x20000110-0x20000100+pheader, buf,32); libafl_phys_write(0x20000108-0x20000100+pheader, &len,1); printf("FUZZ_INPUT[0]: %x\n", buf[0]); libafl_qemu_set_native_breakpoint(0xae); libafl_snapshot_save("Start"); int counter = 3; do { libafl_qemu_main_loop(); libafl_snapshot_load("Start"); puts("Reload has occured"); counter--; } while (runstate_check(RUN_STATE_DEBUG) && counter); libafl_qemu_cleanup(); */ /* // Clock comparison unsigned char ex1[32] = "_`abcdefghijklmnopqrstuvwxyz{|}~"; // unsigned char ex1[32] = "a!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; unsigned char ex2[32] = "a!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; libafl_qemu_sys_init(argc, argv, envp); libafl_qemu_set_native_breakpoint(0x4be0); libafl_snapshot_save("Start"); libafl_phys_write(0x20000110-0x20000100+0x00006ae4, ex1,32); libafl_qemu_main_loop(); printf("Post ex1: %ld\n",libafl_get_clock()); libafl_snapshot_load("Start"); libafl_phys_write(0x20000110-0x20000100+0x00006ae4, ex2,32); libafl_qemu_main_loop(); printf("Post ex2: %ld\n",libafl_get_clock()); */ return 0; } #endif /* End LibAFL instrumentation */