libafl: breakpoints and regs r/w
This commit is contained in:
parent
53c5433e84
commit
7fce6835b0
@ -487,6 +487,18 @@ static inline void cpu_handle_debug_exception(CPUState *cpu)
|
||||
|
||||
static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
|
||||
{
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
#define EXCP_LIBAFL_BP 0xf4775747
|
||||
|
||||
if (cpu->exception_index == EXCP_LIBAFL_BP) {
|
||||
*ret = cpu->exception_index;
|
||||
cpu->exception_index = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
||||
if (cpu->exception_index < 0) {
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (replay_has_exception()
|
||||
|
@ -32,6 +32,19 @@
|
||||
#include "tcg/tcg.h"
|
||||
#include "exec/tb-lookup.h"
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
#define EXCP_LIBAFL_BP 0xf4775747
|
||||
|
||||
void HELPER(libafl_qemu_handle_breakpoint)(CPUArchState *env)
|
||||
{
|
||||
CPUState* cpu = env_cpu(env);
|
||||
cpu->exception_index = EXCP_LIBAFL_BP;
|
||||
cpu_loop_exit(cpu);
|
||||
}
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
||||
/* 32-bit helpers */
|
||||
|
||||
int32_t HELPER(div_i32)(int32_t arg1, int32_t arg2)
|
||||
|
@ -331,3 +331,9 @@ DEF_HELPER_FLAGS_4(gvec_leu32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_leu64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_5(gvec_bitsel, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
DEF_HELPER_FLAGS_1(libafl_qemu_handle_breakpoint, TCG_CALL_NO_RWG, void, env)
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
@ -19,6 +19,17 @@
|
||||
#include "exec/plugin-gen.h"
|
||||
#include "sysemu/replay.h"
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
struct libafl_breakpoint {
|
||||
target_ulong addr;
|
||||
struct libafl_breakpoint* next;
|
||||
};
|
||||
|
||||
extern struct libafl_breakpoint* libafl_qemu_breakpoints;
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
||||
/* Pairs with tcg_clear_temp_count.
|
||||
To be called by #TranslatorOps.{translate_insn,tb_stop} if
|
||||
(1) the target is sufficiently clean to support reporting,
|
||||
@ -91,6 +102,18 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
|
||||
}
|
||||
}
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
struct libafl_breakpoint* bp = libafl_qemu_breakpoints;
|
||||
while (bp) {
|
||||
if (bp->addr == db->pc_next) {
|
||||
gen_helper_libafl_qemu_handle_breakpoint(cpu_env);
|
||||
}
|
||||
bp = bp->next;
|
||||
}
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
||||
/* Disassemble one instruction. The translate_insn hook should
|
||||
update db->pc_next and db->is_jmp to indicate what should be
|
||||
done next -- either exiting this loop or locate the start of
|
||||
|
104
cpu.c
104
cpu.c
@ -37,6 +37,110 @@
|
||||
#include "exec/translate-all.h"
|
||||
#include "exec/log.h"
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
struct libafl_breakpoint {
|
||||
target_ulong addr;
|
||||
struct libafl_breakpoint* next;
|
||||
};
|
||||
|
||||
struct libafl_breakpoint* libafl_qemu_breakpoints = NULL;
|
||||
|
||||
static GByteArray *libafl_qemu_mem_buf = NULL;
|
||||
|
||||
int libafl_qemu_write_reg(int reg, uint8_t* val);
|
||||
int libafl_qemu_read_reg(int reg, uint8_t* val);
|
||||
int libafl_qemu_num_regs(void);
|
||||
int libafl_qemu_set_breakpoint(uint64_t addr);
|
||||
int libafl_qemu_remove_breakpoint(uint64_t addr);
|
||||
|
||||
int libafl_qemu_write_reg(int reg, uint8_t* val)
|
||||
{
|
||||
CPUState *cpu = current_cpu;
|
||||
if (!cpu) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (libafl_qemu_mem_buf == NULL) {
|
||||
libafl_qemu_mem_buf = g_byte_array_sized_new(64);
|
||||
}
|
||||
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
if (reg < cc->gdb_num_core_regs) {
|
||||
return cc->gdb_write_register(cpu, val, reg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libafl_qemu_read_reg(int reg, uint8_t* val)
|
||||
{
|
||||
CPUState *cpu = current_cpu;
|
||||
if (!cpu) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
if (reg < cc->gdb_num_core_regs) {
|
||||
int len = cc->gdb_read_register(cpu, libafl_qemu_mem_buf, reg);
|
||||
if (len > 0) {
|
||||
memcpy(val, libafl_qemu_mem_buf->data, len);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libafl_qemu_num_regs(void)
|
||||
{
|
||||
CPUState *cpu = current_cpu;
|
||||
if (!cpu) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
return cc->gdb_num_core_regs;
|
||||
}
|
||||
|
||||
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc);
|
||||
|
||||
int libafl_qemu_set_breakpoint(uint64_t addr)
|
||||
{
|
||||
CPUState *cpu;
|
||||
|
||||
target_ulong pc = (target_ulong) addr;
|
||||
CPU_FOREACH(cpu) {
|
||||
breakpoint_invalidate(cpu, pc);
|
||||
}
|
||||
|
||||
struct libafl_breakpoint* bp = malloc(sizeof(struct libafl_breakpoint));
|
||||
bp->addr = pc;
|
||||
bp->next = libafl_qemu_breakpoints;
|
||||
libafl_qemu_breakpoints = bp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int libafl_qemu_remove_breakpoint(uint64_t addr)
|
||||
{
|
||||
CPUState *cpu;
|
||||
|
||||
target_ulong pc = (target_ulong) addr;
|
||||
struct libafl_breakpoint** bp = &libafl_qemu_breakpoints;
|
||||
while (*bp) {
|
||||
if ((*bp)->addr == pc) {
|
||||
CPU_FOREACH(cpu) {
|
||||
breakpoint_invalidate(cpu, pc);
|
||||
}
|
||||
|
||||
*bp = (*bp)->next;
|
||||
return 1;
|
||||
}
|
||||
bp = &(*bp)->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
||||
uintptr_t qemu_host_page_size;
|
||||
intptr_t qemu_host_page_mask;
|
||||
|
||||
|
@ -88,6 +88,16 @@ void cpu_loop(CPUARMState *env)
|
||||
process_queued_cpu_work(cs);
|
||||
|
||||
switch (trapnr) {
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
#define EXCP_LIBAFL_BP 0xf4775747
|
||||
|
||||
case EXCP_LIBAFL_BP:
|
||||
return;
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
||||
case EXCP_SWI:
|
||||
ret = do_syscall(env,
|
||||
env->xregs[8],
|
||||
|
@ -240,6 +240,16 @@ void cpu_loop(CPUARMState *env)
|
||||
process_queued_cpu_work(cs);
|
||||
|
||||
switch(trapnr) {
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
#define EXCP_LIBAFL_BP 0xf4775747
|
||||
|
||||
case EXCP_LIBAFL_BP:
|
||||
return;
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
||||
case EXCP_UDEF:
|
||||
case EXCP_NOCP:
|
||||
case EXCP_INVSTATE:
|
||||
|
@ -209,6 +209,16 @@ void cpu_loop(CPUX86State *env)
|
||||
process_queued_cpu_work(cs);
|
||||
|
||||
switch(trapnr) {
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
#define EXCP_LIBAFL_BP 0xf4775747
|
||||
|
||||
case EXCP_LIBAFL_BP:
|
||||
return;
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
||||
case 0x80:
|
||||
/* linux syscall from int $0x80 */
|
||||
ret = do_syscall(env,
|
||||
|
@ -621,6 +621,27 @@ static int parse_args(int argc, char **argv)
|
||||
return optind;
|
||||
}
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
int libafl_qemu_main(void);
|
||||
int libafl_qemu_run(void);
|
||||
|
||||
static CPUArchState *libafl_qemu_env;
|
||||
|
||||
__attribute__((weak)) int libafl_qemu_main(void)
|
||||
{
|
||||
libafl_qemu_run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libafl_qemu_run(void)
|
||||
{
|
||||
cpu_loop(libafl_qemu_env);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
struct target_pt_regs regs1, *regs = ®s1;
|
||||
@ -886,7 +907,16 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
gdb_handlesig(cpu, 0);
|
||||
}
|
||||
cpu_loop(env);
|
||||
// cpu_loop(env);
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
libafl_qemu_env = env;
|
||||
|
||||
return libafl_qemu_main();
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
||||
/* never exits */
|
||||
return 0;
|
||||
// return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user