mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-12 10:08:07 +00:00
Added instrumentation for CMOV instructions
This commit is contained in:
@ -173,6 +173,8 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent
|
|||||||
* `AFL_FRIDA_INST_JIT` - Enable the instrumentation of Just-In-Time compiled
|
* `AFL_FRIDA_INST_JIT` - Enable the instrumentation of Just-In-Time compiled
|
||||||
code. Code is considered to be JIT if the executable segment is not backed by
|
code. Code is considered to be JIT if the executable segment is not backed by
|
||||||
a file.
|
a file.
|
||||||
|
* `AFL_FRIDA_INST_NO_INSN` - Don't generate instrumentation for conditional
|
||||||
|
instructions (e.g. `CMOV` instructions on x64).
|
||||||
* `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage
|
* `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage
|
||||||
instrumentation (the default where available). Required to use
|
instrumentation (the default where available). Required to use
|
||||||
`AFL_FRIDA_INST_TRACE`.
|
`AFL_FRIDA_INST_TRACE`.
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
js_api_set_instrument_debug_file;
|
js_api_set_instrument_debug_file;
|
||||||
js_api_set_instrument_jit;
|
js_api_set_instrument_jit;
|
||||||
js_api_set_instrument_libraries;
|
js_api_set_instrument_libraries;
|
||||||
|
js_api_set_instrument_no_instructions;
|
||||||
js_api_set_instrument_no_optimize;
|
js_api_set_instrument_no_optimize;
|
||||||
js_api_set_instrument_seed;
|
js_api_set_instrument_seed;
|
||||||
js_api_set_instrument_trace;
|
js_api_set_instrument_trace;
|
||||||
|
@ -12,6 +12,7 @@ extern gboolean instrument_optimize;
|
|||||||
extern gboolean instrument_unique;
|
extern gboolean instrument_unique;
|
||||||
extern guint64 instrument_hash_zero;
|
extern guint64 instrument_hash_zero;
|
||||||
extern char * instrument_coverage_unstable_filename;
|
extern char * instrument_coverage_unstable_filename;
|
||||||
|
extern gboolean instrument_coverage_insn;
|
||||||
|
|
||||||
extern gboolean instrument_use_fixed_seed;
|
extern gboolean instrument_use_fixed_seed;
|
||||||
extern guint64 instrument_fixed_seed;
|
extern guint64 instrument_fixed_seed;
|
||||||
@ -33,6 +34,8 @@ gboolean instrument_is_coverage_optimize_supported(void);
|
|||||||
void instrument_coverage_optimize_init(void);
|
void instrument_coverage_optimize_init(void);
|
||||||
void instrument_coverage_optimize(const cs_insn * instr,
|
void instrument_coverage_optimize(const cs_insn * instr,
|
||||||
GumStalkerOutput *output);
|
GumStalkerOutput *output);
|
||||||
|
void instrument_coverage_optimize_insn(const cs_insn * instr,
|
||||||
|
GumStalkerOutput *output);
|
||||||
|
|
||||||
void instrument_debug_config(void);
|
void instrument_debug_config(void);
|
||||||
void instrument_debug_init(void);
|
void instrument_debug_init(void);
|
||||||
|
@ -29,6 +29,7 @@ guint64 instrument_hash_seed = 0;
|
|||||||
gboolean instrument_use_fixed_seed = FALSE;
|
gboolean instrument_use_fixed_seed = FALSE;
|
||||||
guint64 instrument_fixed_seed = 0;
|
guint64 instrument_fixed_seed = 0;
|
||||||
char * instrument_coverage_unstable_filename = NULL;
|
char * instrument_coverage_unstable_filename = NULL;
|
||||||
|
gboolean instrument_coverage_insn = FALSE;
|
||||||
|
|
||||||
static GumStalkerTransformer *transformer = NULL;
|
static GumStalkerTransformer *transformer = NULL;
|
||||||
|
|
||||||
@ -233,6 +234,12 @@ static void instrument_basic_block(GumStalkerIterator *iterator,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instrument_coverage_insn) {
|
||||||
|
|
||||||
|
instrument_coverage_optimize_insn(instr, output);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
instrument_debug_instruction(instr->address, instr->size, output);
|
instrument_debug_instruction(instr->address, instr->size, output);
|
||||||
|
|
||||||
if (likely(!excluded)) {
|
if (likely(!excluded)) {
|
||||||
@ -269,6 +276,7 @@ void instrument_config(void) {
|
|||||||
instrument_fixed_seed = util_read_num("AFL_FRIDA_INST_SEED", 0);
|
instrument_fixed_seed = util_read_num("AFL_FRIDA_INST_SEED", 0);
|
||||||
instrument_coverage_unstable_filename =
|
instrument_coverage_unstable_filename =
|
||||||
(getenv("AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE"));
|
(getenv("AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE"));
|
||||||
|
instrument_coverage_insn = (getenv("AFL_FRIDA_INST_NO_INSN") == NULL);
|
||||||
|
|
||||||
instrument_debug_config();
|
instrument_debug_config();
|
||||||
instrument_coverage_config();
|
instrument_coverage_config();
|
||||||
|
@ -20,6 +20,15 @@ void instrument_coverage_optimize(const cs_insn * instr,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void instrument_coverage_optimize_insn(const cs_insn * instr,
|
||||||
|
GumStalkerOutput *output) {
|
||||||
|
|
||||||
|
UNUSED_PARAMETER(instr);
|
||||||
|
UNUSED_PARAMETER(output);
|
||||||
|
FFATAL("Optimized coverage not supported on this architecture");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void instrument_coverage_optimize_init(void) {
|
void instrument_coverage_optimize_init(void) {
|
||||||
|
|
||||||
FWARNF("Optimized coverage not supported on this architecture");
|
FWARNF("Optimized coverage not supported on this architecture");
|
||||||
|
@ -341,6 +341,14 @@ void instrument_coverage_optimize(const cs_insn * instr,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void instrument_coverage_optimize_insn(const cs_insn * instr,
|
||||||
|
GumStalkerOutput *output) {
|
||||||
|
|
||||||
|
UNUSED_PARAMETER(instr);
|
||||||
|
UNUSED_PARAMETER(output);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void instrument_coverage_optimize_init(void) {
|
void instrument_coverage_optimize_init(void) {
|
||||||
|
|
||||||
char *shm_env = getenv(SHM_ENV_VAR);
|
char *shm_env = getenv(SHM_ENV_VAR);
|
||||||
|
@ -23,6 +23,40 @@
|
|||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
|
|
||||||
|
enum jcc_opcodes {
|
||||||
|
|
||||||
|
OPC_JO = 0x70,
|
||||||
|
OPC_JNO = 0x71,
|
||||||
|
OPC_JB = 0x72,
|
||||||
|
OPC_JAE = 0x73,
|
||||||
|
OPC_JE = 0x74,
|
||||||
|
OPC_JNE = 0x75,
|
||||||
|
OPC_JBE = 0x76,
|
||||||
|
OPC_JA = 0x77,
|
||||||
|
OPC_JS = 0x78,
|
||||||
|
OPC_JNS = 0x79,
|
||||||
|
OPC_JP = 0x7a,
|
||||||
|
OPC_JNP = 0x7b,
|
||||||
|
OPC_JL = 0x7c,
|
||||||
|
OPC_JGE = 0x7d,
|
||||||
|
OPC_JLE = 0x7e,
|
||||||
|
OPC_JG = 0x7f,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
|
||||||
|
struct {
|
||||||
|
|
||||||
|
uint8_t opcode;
|
||||||
|
uint8_t distance;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t bytes[0];
|
||||||
|
|
||||||
|
} jcc_insn;
|
||||||
|
|
||||||
static GHashTable *coverage_blocks = NULL;
|
static GHashTable *coverage_blocks = NULL;
|
||||||
|
|
||||||
gboolean instrument_is_coverage_optimize_supported(void) {
|
gboolean instrument_is_coverage_optimize_supported(void) {
|
||||||
@ -201,37 +235,15 @@ static void instrument_coverage_suppress_init(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void instrument_coverage_optimize(const cs_insn * instr,
|
static void instrument_coverage_write(GumAddress address,
|
||||||
GumStalkerOutput *output) {
|
GumStalkerOutput *output) {
|
||||||
|
|
||||||
afl_log_code code = {0};
|
afl_log_code code = {0};
|
||||||
GumX86Writer *cw = output->writer.x86;
|
GumX86Writer *cw = output->writer.x86;
|
||||||
guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
|
guint64 area_offset = instrument_get_offset_hash(address);
|
||||||
gsize map_size_pow2;
|
gsize map_size_pow2;
|
||||||
gsize area_offset_ror;
|
gsize area_offset_ror;
|
||||||
GumAddress code_addr = 0;
|
GumAddress code_addr = cw->pc;
|
||||||
if (instrument_previous_pc_addr == NULL) {
|
|
||||||
|
|
||||||
GumAddressSpec spec = {.near_address = cw->code,
|
|
||||||
.max_distance = 1ULL << 30};
|
|
||||||
|
|
||||||
instrument_previous_pc_addr = gum_memory_allocate_near(
|
|
||||||
&spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE);
|
|
||||||
*instrument_previous_pc_addr = instrument_hash_zero;
|
|
||||||
FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
|
|
||||||
FVERBOSE("code_addr: %p", cw->code);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
instrument_coverage_suppress_init();
|
|
||||||
|
|
||||||
// gum_x86_writer_put_breakpoint(cw);
|
|
||||||
code_addr = cw->pc;
|
|
||||||
if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
|
|
||||||
|
|
||||||
FATAL("Failed - g_hash_table_add");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
code.code = template;
|
code.code = template;
|
||||||
|
|
||||||
@ -313,6 +325,129 @@ void instrument_coverage_optimize(const cs_insn * instr,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void instrument_coverage_optimize(const cs_insn * instr,
|
||||||
|
GumStalkerOutput *output) {
|
||||||
|
|
||||||
|
GumX86Writer *cw = output->writer.x86;
|
||||||
|
guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
|
||||||
|
if (instrument_previous_pc_addr == NULL) {
|
||||||
|
|
||||||
|
GumAddressSpec spec = {.near_address = cw->code,
|
||||||
|
.max_distance = 1ULL << 30};
|
||||||
|
|
||||||
|
instrument_previous_pc_addr = gum_memory_allocate_near(
|
||||||
|
&spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE);
|
||||||
|
*instrument_previous_pc_addr = instrument_hash_zero;
|
||||||
|
FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
|
||||||
|
FVERBOSE("code_addr: %p", cw->code);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
instrument_coverage_suppress_init();
|
||||||
|
|
||||||
|
if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
|
||||||
|
|
||||||
|
FATAL("Failed - g_hash_table_add");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
instrument_coverage_write(GUM_ADDRESS(instr->address), output);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void instrument_coverage_optimize_insn(const cs_insn * instr,
|
||||||
|
GumStalkerOutput *output) {
|
||||||
|
|
||||||
|
GumX86Writer *cw = output->writer.x86;
|
||||||
|
jcc_insn taken, not_taken;
|
||||||
|
|
||||||
|
switch (instr->id) {
|
||||||
|
|
||||||
|
case X86_INS_CMOVA:
|
||||||
|
taken.opcode = OPC_JA;
|
||||||
|
not_taken.opcode = OPC_JBE;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVAE:
|
||||||
|
taken.opcode = OPC_JAE;
|
||||||
|
not_taken.opcode = OPC_JB;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVB:
|
||||||
|
taken.opcode = OPC_JB;
|
||||||
|
not_taken.opcode = OPC_JAE;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVBE:
|
||||||
|
taken.opcode = OPC_JBE;
|
||||||
|
not_taken.opcode = OPC_JA;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVE:
|
||||||
|
taken.opcode = OPC_JE;
|
||||||
|
not_taken.opcode = OPC_JNE;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVG:
|
||||||
|
taken.opcode = OPC_JG;
|
||||||
|
not_taken.opcode = OPC_JLE;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVGE:
|
||||||
|
taken.opcode = OPC_JGE;
|
||||||
|
not_taken.opcode = OPC_JL;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVL:
|
||||||
|
taken.opcode = OPC_JL;
|
||||||
|
not_taken.opcode = OPC_JGE;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVLE:
|
||||||
|
taken.opcode = OPC_JLE;
|
||||||
|
not_taken.opcode = OPC_JG;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVNE:
|
||||||
|
taken.opcode = OPC_JNE;
|
||||||
|
not_taken.opcode = OPC_JE;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVNO:
|
||||||
|
taken.opcode = OPC_JNO;
|
||||||
|
not_taken.opcode = OPC_JO;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVNP:
|
||||||
|
taken.opcode = OPC_JNP;
|
||||||
|
not_taken.opcode = OPC_JP;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVNS:
|
||||||
|
taken.opcode = OPC_JNS;
|
||||||
|
not_taken.opcode = OPC_JS;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVO:
|
||||||
|
taken.opcode = OPC_JO;
|
||||||
|
not_taken.opcode = OPC_JNO;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVP:
|
||||||
|
taken.opcode = OPC_JP;
|
||||||
|
not_taken.opcode = OPC_JNP;
|
||||||
|
break;
|
||||||
|
case X86_INS_CMOVS:
|
||||||
|
taken.opcode = OPC_JS;
|
||||||
|
not_taken.opcode = OPC_JNS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
taken.distance = sizeof(afl_log_code);
|
||||||
|
not_taken.distance = sizeof(afl_log_code);
|
||||||
|
|
||||||
|
// gum_x86_writer_put_breakpoint(cw);
|
||||||
|
|
||||||
|
gum_x86_writer_put_bytes(cw, taken.bytes, sizeof(jcc_insn));
|
||||||
|
instrument_coverage_write(GUM_ADDRESS(instr->address), output);
|
||||||
|
|
||||||
|
gum_x86_writer_put_bytes(cw, not_taken.bytes, sizeof(jcc_insn));
|
||||||
|
instrument_coverage_write(GUM_ADDRESS(instr->address + instr->size), output);
|
||||||
|
|
||||||
|
FVERBOSE("Instrument - 0x%016lx: %s %s", instr->address, instr->mnemonic,
|
||||||
|
instr->op_str);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void instrument_flush(GumStalkerOutput *output) {
|
void instrument_flush(GumStalkerOutput *output) {
|
||||||
|
|
||||||
gum_x86_writer_flush(output->writer.x86);
|
gum_x86_writer_flush(output->writer.x86);
|
||||||
|
@ -218,6 +218,14 @@ void instrument_coverage_optimize(const cs_insn * instr,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void instrument_coverage_optimize_insn(const cs_insn * instr,
|
||||||
|
GumStalkerOutput *output) {
|
||||||
|
|
||||||
|
UNUSED_PARAMETER(instr);
|
||||||
|
UNUSED_PARAMETER(output);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void instrument_coverage_optimize_init(void) {
|
void instrument_coverage_optimize_init(void) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,12 @@ class Afl {
|
|||||||
static setInstrumentLibraries() {
|
static setInstrumentLibraries() {
|
||||||
Afl.jsApiSetInstrumentLibraries();
|
Afl.jsApiSetInstrumentLibraries();
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* See `AFL_FRIDA_INST_NO_INSN`
|
||||||
|
*/
|
||||||
|
static setInstrumentNoInstructions() {
|
||||||
|
Afl.jsApiSetInstrumentNoInstructions();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* See `AFL_FRIDA_INST_NO_OPTIMIZE`
|
* See `AFL_FRIDA_INST_NO_OPTIMIZE`
|
||||||
*/
|
*/
|
||||||
@ -299,6 +305,7 @@ Afl.jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument
|
|||||||
Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]);
|
Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]);
|
||||||
Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []);
|
Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []);
|
||||||
Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []);
|
Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []);
|
||||||
|
Afl.jsApiSetInstrumentNoInstructions = Afl.jsApiGetFunction("js_api_set_instrument_no_instructions", "void", []);
|
||||||
Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []);
|
Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []);
|
||||||
Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]);
|
Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]);
|
||||||
Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []);
|
Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []);
|
||||||
|
@ -142,6 +142,13 @@ js_api_set_prefetch_backpatch_disable(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) void
|
||||||
|
js_api_set_instrument_no_instructions(void) {
|
||||||
|
|
||||||
|
instrument_coverage_insn = FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
__attribute__((visibility("default"))) void js_api_set_instrument_no_optimize(
|
__attribute__((visibility("default"))) void js_api_set_instrument_no_optimize(
|
||||||
void) {
|
void) {
|
||||||
|
|
||||||
|
87
frida_mode/test/cmov/GNUmakefile
Normal file
87
frida_mode/test/cmov/GNUmakefile
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
PWD:=$(shell pwd)/
|
||||||
|
ROOT:=$(PWD)../../../
|
||||||
|
BUILD_DIR:=$(PWD)build/
|
||||||
|
|
||||||
|
TEST_CMOV_SRC:=$(PWD)cmov.c
|
||||||
|
TEST_CMOV_OBJ:=$(BUILD_DIR)cmov
|
||||||
|
|
||||||
|
TEST_DATA_DIR:=$(BUILD_DIR)in/
|
||||||
|
CMP_LOG_INPUT:=$(TEST_DATA_DIR)in
|
||||||
|
QEMU_OUT:=$(BUILD_DIR)qemu-out
|
||||||
|
FRIDA_OUT:=$(BUILD_DIR)frida-out
|
||||||
|
|
||||||
|
ADDR_BIN:=$(ROOT)frida_mode/build/addr
|
||||||
|
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
|
||||||
|
|
||||||
|
AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so
|
||||||
|
|
||||||
|
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
|
||||||
|
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_CMOV_OBJ) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
|
||||||
|
|
||||||
|
DUMMY_DATA_FILE:=$(BUILD_DIR)dummy.dat
|
||||||
|
|
||||||
|
.PHONY: all 32 clean frida frida_noinst debug format
|
||||||
|
|
||||||
|
all: $(TEST_CMOV_OBJ)
|
||||||
|
make -C $(ROOT)frida_mode/
|
||||||
|
|
||||||
|
32:
|
||||||
|
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
|
||||||
|
|
||||||
|
$(BUILD_DIR):
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
$(TEST_DATA_DIR): | $(BUILD_DIR)
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
$(CMP_LOG_INPUT): | $(TEST_DATA_DIR)
|
||||||
|
echo -n "ABC" > $@
|
||||||
|
|
||||||
|
$(TEST_CMOV_OBJ): $(TEST_CMOV_SRC) | $(BUILD_DIR)
|
||||||
|
$(CC) -g $(CFLAGS) $(LDFLAGS) $< -o $@
|
||||||
|
|
||||||
|
########## DUMMY #######
|
||||||
|
|
||||||
|
$(DUMMY_DATA_FILE): | $(BUILD_DIR)
|
||||||
|
dd if=/dev/zero bs=1048576 count=1 of=$@
|
||||||
|
|
||||||
|
frida: $(TEST_CMOV_OBJ) $(CMP_LOG_INPUT) $(DUMMY_DATA_FILE)
|
||||||
|
AFL_FRIDA_PERSISTENT_CNT=1000000 \
|
||||||
|
AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \
|
||||||
|
AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \
|
||||||
|
AFL_ENTRYPOINT=$(AFL_FRIDA_PERSISTENT_ADDR) \
|
||||||
|
$(ROOT)afl-fuzz \
|
||||||
|
-O \
|
||||||
|
-i $(TEST_DATA_DIR) \
|
||||||
|
-o $(FRIDA_OUT) \
|
||||||
|
-Z \
|
||||||
|
-t 10000+ \
|
||||||
|
-- \
|
||||||
|
$(TEST_CMOV_OBJ) $(DUMMY_DATA_FILE)
|
||||||
|
|
||||||
|
frida_noinst: $(TEST_CMOV_OBJ) $(CMP_LOG_INPUT) $(DUMMY_DATA_FILE)
|
||||||
|
AFL_FRIDA_INST_NO_INSN=1 \
|
||||||
|
AFL_FRIDA_PERSISTENT_CNT=1000000 \
|
||||||
|
AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \
|
||||||
|
AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \
|
||||||
|
AFL_ENTRYPOINT=$(AFL_FRIDA_PERSISTENT_ADDR) \
|
||||||
|
$(ROOT)afl-fuzz \
|
||||||
|
-O \
|
||||||
|
-i $(TEST_DATA_DIR) \
|
||||||
|
-o $(FRIDA_OUT) \
|
||||||
|
-Z \
|
||||||
|
-- \
|
||||||
|
$(TEST_CMOV_OBJ) $(DUMMY_DATA_FILE)
|
||||||
|
|
||||||
|
debug: $(TEST_CMOV_OBJ) $(CMP_LOG_INPUT)
|
||||||
|
gdb \
|
||||||
|
--ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \
|
||||||
|
--ex 'set disassembly-flavor intel' \
|
||||||
|
--ex 'r $(CMP_LOG_INPUT)' \
|
||||||
|
--args $(TEST_CMOV_OBJ) $(CMP_LOG_INPUT)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILD_DIR)
|
||||||
|
|
||||||
|
format:
|
||||||
|
cd $(ROOT) && echo $(TEST_CMOV_SRC) | xargs -L1 ./.custom-format.py -i
|
19
frida_mode/test/cmov/Makefile
Normal file
19
frida_mode/test/cmov/Makefile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
all:
|
||||||
|
@echo trying to use GNU make...
|
||||||
|
@gmake all || echo please install GNUmake
|
||||||
|
|
||||||
|
32:
|
||||||
|
@echo trying to use GNU make...
|
||||||
|
@gmake 32 || echo please install GNUmake
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@gmake clean
|
||||||
|
|
||||||
|
frida:
|
||||||
|
@gmake frida
|
||||||
|
|
||||||
|
format:
|
||||||
|
@gmake format
|
||||||
|
|
||||||
|
debug:
|
||||||
|
@gmake debug
|
122
frida_mode/test/cmov/cmov.c
Normal file
122
frida_mode/test/cmov/cmov.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static bool cmov_test(char *x, char *y, size_t len) {
|
||||||
|
|
||||||
|
register char * __rdi __asm__("rdi") = x;
|
||||||
|
register char * __rsi __asm__("rsi") = y;
|
||||||
|
register size_t __rcx __asm__("rcx") = len;
|
||||||
|
|
||||||
|
register long __rax __asm__("rax");
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"mov $0x1, %%rax\n"
|
||||||
|
"mov $0x0, %%r8\n"
|
||||||
|
"1:\n"
|
||||||
|
"mov (%%rsi), %%bl\n"
|
||||||
|
"mov (%%rdi), %%dl\n"
|
||||||
|
"cmp %%bl, %%dl\n"
|
||||||
|
"cmovne %%r8, %%rax\n"
|
||||||
|
"inc %%rsi\n"
|
||||||
|
"inc %%rdi\n"
|
||||||
|
"dec %%rcx\n"
|
||||||
|
"jnz 1b\n"
|
||||||
|
: "=r"(__rax)
|
||||||
|
: "r"(__rdi), "r"(__rsi)
|
||||||
|
: "r8", "bl", "dl", "memory");
|
||||||
|
|
||||||
|
return __rax;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLVMFuzzerTestOneInput(char *buf, int len) {
|
||||||
|
|
||||||
|
char match[] = "CBAABC";
|
||||||
|
|
||||||
|
if (len > sizeof(match)) { return; }
|
||||||
|
|
||||||
|
if (cmov_test(buf, match, sizeof(buf)) != 0) {
|
||||||
|
|
||||||
|
printf("Puzzle solved, congrats!\n");
|
||||||
|
abort();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
char * file;
|
||||||
|
int fd = -1;
|
||||||
|
off_t len;
|
||||||
|
char * buf = NULL;
|
||||||
|
size_t n_read;
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
if (argc != 2) { return 1; }
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
file = argv[1];
|
||||||
|
|
||||||
|
dprintf(STDERR_FILENO, "Running: %s\n", file);
|
||||||
|
|
||||||
|
fd = open(file, O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
|
||||||
|
perror("open");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
len = lseek(fd, 0, SEEK_END);
|
||||||
|
if (len < 0) {
|
||||||
|
|
||||||
|
perror("lseek (SEEK_END)");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lseek(fd, 0, SEEK_SET) != 0) {
|
||||||
|
|
||||||
|
perror("lseek (SEEK_SET)");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = (char *)malloc(len);
|
||||||
|
if (buf == NULL) {
|
||||||
|
|
||||||
|
perror("malloc");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
n_read = read(fd, buf, len);
|
||||||
|
if (n_read != len) {
|
||||||
|
|
||||||
|
perror("read");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf(STDERR_FILENO, "Running: %s: (%zd bytes)\n", file, n_read);
|
||||||
|
|
||||||
|
LLVMFuzzerTestOneInput(buf, len);
|
||||||
|
dprintf(STDERR_FILENO, "Done: %s: (%zd bytes)\n", file, n_read);
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
if (buf != NULL) { free(buf); }
|
||||||
|
|
||||||
|
if (fd != -1) { close(fd); }
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -149,6 +149,13 @@ class Afl {
|
|||||||
Afl.jsApiSetInstrumentLibraries();
|
Afl.jsApiSetInstrumentLibraries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See `AFL_FRIDA_INST_NO_INSN`
|
||||||
|
*/
|
||||||
|
public static setInstrumentNoInstructions(): void {
|
||||||
|
Afl.jsApiSetInstrumentNoInstructions();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See `AFL_FRIDA_INST_NO_OPTIMIZE`
|
* See `AFL_FRIDA_INST_NO_OPTIMIZE`
|
||||||
*/
|
*/
|
||||||
@ -377,6 +384,11 @@ class Afl {
|
|||||||
"void",
|
"void",
|
||||||
[]);
|
[]);
|
||||||
|
|
||||||
|
private static readonly jsApiSetInstrumentNoInstructions = Afl.jsApiGetFunction(
|
||||||
|
"js_api_set_instrument_no_instructions",
|
||||||
|
"void",
|
||||||
|
[]);
|
||||||
|
|
||||||
private static readonly jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction(
|
private static readonly jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction(
|
||||||
"js_api_set_instrument_no_optimize",
|
"js_api_set_instrument_no_optimize",
|
||||||
"void",
|
"void",
|
||||||
|
@ -60,6 +60,7 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_FRIDA_INST_COVERAGE_FILE",
|
"AFL_FRIDA_INST_COVERAGE_FILE",
|
||||||
"AFL_FRIDA_INST_DEBUG_FILE",
|
"AFL_FRIDA_INST_DEBUG_FILE",
|
||||||
"AFL_FRIDA_INST_JIT",
|
"AFL_FRIDA_INST_JIT",
|
||||||
|
"AFL_FRIDA_INST_NO_INSN",
|
||||||
"AFL_FRIDA_INST_NO_OPTIMIZE",
|
"AFL_FRIDA_INST_NO_OPTIMIZE",
|
||||||
"AFL_FRIDA_INST_NO_PREFETCH",
|
"AFL_FRIDA_INST_NO_PREFETCH",
|
||||||
"AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH",
|
"AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH",
|
||||||
|
Reference in New Issue
Block a user