aboutsummaryrefslogtreecommitdiff
path: root/frida_mode/src
diff options
context:
space:
mode:
authorYour Name <you@example.com>2022-02-18 07:55:45 +0000
committerYour Name <you@example.com>2022-02-18 08:01:34 +0000
commitcb1256499f7e07fd0edf0958d08b958fec63c34c (patch)
tree6e11894987f8d234d651e780b0b58cb2265f725c /frida_mode/src
parentdd8ad4dfa35c8b11ebcc6005f44855db02fefb74 (diff)
downloadafl++-cb1256499f7e07fd0edf0958d08b958fec63c34c.tar.gz
Added instrumentation for CMOV instructions
Diffstat (limited to 'frida_mode/src')
-rw-r--r--frida_mode/src/instrument/instrument.c8
-rw-r--r--frida_mode/src/instrument/instrument_arm32.c9
-rw-r--r--frida_mode/src/instrument/instrument_arm64.c8
-rw-r--r--frida_mode/src/instrument/instrument_x64.c191
-rw-r--r--frida_mode/src/instrument/instrument_x86.c8
-rw-r--r--frida_mode/src/js/api.js7
-rw-r--r--frida_mode/src/js/js_api.c7
7 files changed, 210 insertions, 28 deletions
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index 418b35e8..4877f4fb 100644
--- a/frida_mode/src/instrument/instrument.c
+++ b/frida_mode/src/instrument/instrument.c
@@ -29,6 +29,7 @@ guint64 instrument_hash_seed = 0;
gboolean instrument_use_fixed_seed = FALSE;
guint64 instrument_fixed_seed = 0;
char * instrument_coverage_unstable_filename = NULL;
+gboolean instrument_coverage_insn = FALSE;
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);
if (likely(!excluded)) {
@@ -269,6 +276,7 @@ void instrument_config(void) {
instrument_fixed_seed = util_read_num("AFL_FRIDA_INST_SEED", 0);
instrument_coverage_unstable_filename =
(getenv("AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE"));
+ instrument_coverage_insn = (getenv("AFL_FRIDA_INST_NO_INSN") == NULL);
instrument_debug_config();
instrument_coverage_config();
diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c
index 16e8eaab..705faa64 100644
--- a/frida_mode/src/instrument/instrument_arm32.c
+++ b/frida_mode/src/instrument/instrument_arm32.c
@@ -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) {
FWARNF("Optimized coverage not supported on this architecture");
diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c
index 1a704585..4abc0625 100644
--- a/frida_mode/src/instrument/instrument_arm64.c
+++ b/frida_mode/src/instrument/instrument_arm64.c
@@ -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) {
char *shm_env = getenv(SHM_ENV_VAR);
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index c28285ff..4b1a2d68 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -23,6 +23,40 @@
#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;
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,
- GumStalkerOutput *output) {
+static void instrument_coverage_write(GumAddress address,
+ GumStalkerOutput *output) {
afl_log_code code = {0};
GumX86Writer *cw = output->writer.x86;
- guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
- gsize map_size_pow2;
- gsize area_offset_ror;
- GumAddress code_addr = 0;
- 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");
-
- }
+ guint64 area_offset = instrument_get_offset_hash(address);
+ gsize map_size_pow2;
+ gsize area_offset_ror;
+ GumAddress code_addr = cw->pc;
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) {
gum_x86_writer_flush(output->writer.x86);
diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c
index c4e93324..916cd0e2 100644
--- a/frida_mode/src/instrument/instrument_x86.c
+++ b/frida_mode/src/instrument/instrument_x86.c
@@ -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) {
}
diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js
index 52e9e45c..c2d9a2d4 100644
--- a/frida_mode/src/js/api.js
+++ b/frida_mode/src/js/api.js
@@ -126,6 +126,12 @@ class Afl {
Afl.jsApiSetInstrumentLibraries();
}
/**
+ * See `AFL_FRIDA_INST_NO_INSN`
+ */
+ static setInstrumentNoInstructions() {
+ Afl.jsApiSetInstrumentNoInstructions();
+ }
+ /**
* See `AFL_FRIDA_INST_NO_OPTIMIZE`
*/
static setInstrumentNoOptimize() {
@@ -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.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "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.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]);
Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []);
diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c
index 94ec8842..613747b8 100644
--- a/frida_mode/src/js/js_api.c
+++ b/frida_mode/src/js/js_api.c
@@ -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(
void) {