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)
|
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) {
|
if (cpu->exception_index < 0) {
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
if (replay_has_exception()
|
if (replay_has_exception()
|
||||||
|
@ -32,6 +32,19 @@
|
|||||||
#include "tcg/tcg.h"
|
#include "tcg/tcg.h"
|
||||||
#include "exec/tb-lookup.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 */
|
/* 32-bit helpers */
|
||||||
|
|
||||||
int32_t HELPER(div_i32)(int32_t arg1, int32_t arg2)
|
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_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)
|
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 "exec/plugin-gen.h"
|
||||||
#include "sysemu/replay.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.
|
/* Pairs with tcg_clear_temp_count.
|
||||||
To be called by #TranslatorOps.{translate_insn,tb_stop} if
|
To be called by #TranslatorOps.{translate_insn,tb_stop} if
|
||||||
(1) the target is sufficiently clean to support reporting,
|
(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
|
/* Disassemble one instruction. The translate_insn hook should
|
||||||
update db->pc_next and db->is_jmp to indicate what should be
|
update db->pc_next and db->is_jmp to indicate what should be
|
||||||
done next -- either exiting this loop or locate the start of
|
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/translate-all.h"
|
||||||
#include "exec/log.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;
|
uintptr_t qemu_host_page_size;
|
||||||
intptr_t qemu_host_page_mask;
|
intptr_t qemu_host_page_mask;
|
||||||
|
|
||||||
|
@ -88,6 +88,16 @@ void cpu_loop(CPUARMState *env)
|
|||||||
process_queued_cpu_work(cs);
|
process_queued_cpu_work(cs);
|
||||||
|
|
||||||
switch (trapnr) {
|
switch (trapnr) {
|
||||||
|
|
||||||
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
|
#define EXCP_LIBAFL_BP 0xf4775747
|
||||||
|
|
||||||
|
case EXCP_LIBAFL_BP:
|
||||||
|
return;
|
||||||
|
|
||||||
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
case EXCP_SWI:
|
case EXCP_SWI:
|
||||||
ret = do_syscall(env,
|
ret = do_syscall(env,
|
||||||
env->xregs[8],
|
env->xregs[8],
|
||||||
|
@ -240,6 +240,16 @@ void cpu_loop(CPUARMState *env)
|
|||||||
process_queued_cpu_work(cs);
|
process_queued_cpu_work(cs);
|
||||||
|
|
||||||
switch(trapnr) {
|
switch(trapnr) {
|
||||||
|
|
||||||
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
|
#define EXCP_LIBAFL_BP 0xf4775747
|
||||||
|
|
||||||
|
case EXCP_LIBAFL_BP:
|
||||||
|
return;
|
||||||
|
|
||||||
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
case EXCP_UDEF:
|
case EXCP_UDEF:
|
||||||
case EXCP_NOCP:
|
case EXCP_NOCP:
|
||||||
case EXCP_INVSTATE:
|
case EXCP_INVSTATE:
|
||||||
|
@ -209,6 +209,16 @@ void cpu_loop(CPUX86State *env)
|
|||||||
process_queued_cpu_work(cs);
|
process_queued_cpu_work(cs);
|
||||||
|
|
||||||
switch(trapnr) {
|
switch(trapnr) {
|
||||||
|
|
||||||
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
|
#define EXCP_LIBAFL_BP 0xf4775747
|
||||||
|
|
||||||
|
case EXCP_LIBAFL_BP:
|
||||||
|
return;
|
||||||
|
|
||||||
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
case 0x80:
|
case 0x80:
|
||||||
/* linux syscall from int $0x80 */
|
/* linux syscall from int $0x80 */
|
||||||
ret = do_syscall(env,
|
ret = do_syscall(env,
|
||||||
|
@ -621,6 +621,27 @@ static int parse_args(int argc, char **argv)
|
|||||||
return optind;
|
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)
|
int main(int argc, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
struct target_pt_regs regs1, *regs = ®s1;
|
struct target_pt_regs regs1, *regs = ®s1;
|
||||||
@ -886,7 +907,16 @@ int main(int argc, char **argv, char **envp)
|
|||||||
}
|
}
|
||||||
gdb_handlesig(cpu, 0);
|
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 */
|
/* never exits */
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user