aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2022-02-18 11:04:45 +0100
committerGitHub <noreply@github.com>2022-02-18 11:04:45 +0100
commita5943dc782d1a6047aaa8f455ab37e4a31369311 (patch)
tree9ffc1ca018245aa6533a9194da7c21a03c4e4a7c
parent8fc249d210ad49e3dd88d1409877ca64d9884690 (diff)
parentfc7bf33fb144162ede0c2d56b91ad31143113f16 (diff)
downloadafl++-a5943dc782d1a6047aaa8f455ab37e4a31369311.tar.gz
Merge pull request #1332 from WorksButNotTested/module
Module
-rw-r--r--frida_mode/README.md2
-rw-r--r--frida_mode/frida.map1
-rw-r--r--frida_mode/include/instrument.h3
-rw-r--r--frida_mode/include/module.h11
-rw-r--r--frida_mode/src/instrument/instrument.c10
-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.c533
-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
-rw-r--r--frida_mode/src/main.c3
-rw-r--r--frida_mode/src/module.c106
-rw-r--r--frida_mode/src/ranges.c2
-rw-r--r--frida_mode/test/cmov/GNUmakefile87
-rw-r--r--frida_mode/test/cmov/Makefile19
-rw-r--r--frida_mode/test/cmov/cmov.c122
-rw-r--r--frida_mode/test/python/GNUmakefile37
-rw-r--r--frida_mode/test/python/Makefile17
-rw-r--r--frida_mode/ts/lib/afl.ts12
-rw-r--r--include/envs.h1
21 files changed, 691 insertions, 314 deletions
diff --git a/frida_mode/README.md b/frida_mode/README.md
index e5b46baf..50e3b8d7 100644
--- a/frida_mode/README.md
+++ b/frida_mode/README.md
@@ -170,6 +170,8 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent
***
```
+* `AFL_FRIDA_INST_INSN` - Generate instrumentation for conditional
+ instructions (e.g. `CMOV` instructions on x64).
* `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
a file.
diff --git a/frida_mode/frida.map b/frida_mode/frida.map
index d059bdb6..41220d4b 100644
--- a/frida_mode/frida.map
+++ b/frida_mode/frida.map
@@ -15,6 +15,7 @@
js_api_set_instrument_debug_file;
js_api_set_instrument_jit;
js_api_set_instrument_libraries;
+ js_api_set_instrument_instructions;
js_api_set_instrument_no_optimize;
js_api_set_instrument_seed;
js_api_set_instrument_trace;
diff --git a/frida_mode/include/instrument.h b/frida_mode/include/instrument.h
index abb89c9f..20312a4b 100644
--- a/frida_mode/include/instrument.h
+++ b/frida_mode/include/instrument.h
@@ -12,6 +12,7 @@ extern gboolean instrument_optimize;
extern gboolean instrument_unique;
extern guint64 instrument_hash_zero;
extern char * instrument_coverage_unstable_filename;
+extern gboolean instrument_coverage_insn;
extern gboolean instrument_use_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(const cs_insn * instr,
GumStalkerOutput *output);
+void instrument_coverage_optimize_insn(const cs_insn * instr,
+ GumStalkerOutput *output);
void instrument_debug_config(void);
void instrument_debug_init(void);
diff --git a/frida_mode/include/module.h b/frida_mode/include/module.h
new file mode 100644
index 00000000..b66f7feb
--- /dev/null
+++ b/frida_mode/include/module.h
@@ -0,0 +1,11 @@
+#ifndef _MODULE_H
+#define _MODULE_H
+
+#include "frida-gumjs.h"
+
+void module_config(void);
+
+void module_init(void);
+
+#endif
+
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index 418b35e8..43560478 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_INSN") != NULL);
instrument_debug_config();
instrument_coverage_config();
@@ -294,6 +302,8 @@ void instrument_init(void) {
instrument_coverage_unstable_filename == NULL
? " "
: instrument_coverage_unstable_filename);
+ FOKF(cBLU "Instrumentation" cRST " - " cGRN "instructions:" cYEL " [%c]",
+ instrument_coverage_insn ? 'X' : ' ');
if (instrument_tracing && instrument_optimize) {
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 fb84d6d2..4b1a2d68 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -23,13 +23,39 @@
#if defined(__x86_64__)
- #ifndef MAP_FIXED_NOREPLACE
- #ifdef MAP_EXCL
- #define MAP_FIXED_NOREPLACE MAP_EXCL | MAP_FIXED
- #else
- #define MAP_FIXED_NOREPLACE MAP_FIXED
- #endif
- #endif
+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;
@@ -45,8 +71,7 @@ static gboolean instrument_coverage_in_range(gssize offset) {
}
- #ifdef __APPLE__
- #pragma pack(push, 1)
+ #pragma pack(push, 1)
typedef struct {
@@ -54,95 +79,28 @@ typedef struct {
// shared_mem[cur_location ^ prev_location]++;
// prev_location = cur_location >> 1;
- // mov QWORD PTR [rsp-0x80],rax
- // lahf
- // mov QWORD PTR [rsp-0x88],rax
- // mov QWORD PTR [rsp-0x90],rbx
- // mov eax,DWORD PTR [rip+0x333d5a] # 0x7ffff6ff2740
- // mov DWORD PTR [rip+0x333d3c],0x9fbb # 0x7ffff6ff2740
- // lea rax,[rip + 0x103f77]
- // mov bl,BYTE PTR [rax]
- // add bl,0x1
- // adc bl,0x0
- // mov BYTE PTR [rax],bl
- // mov rbx,QWORD PTR [rsp-0x90]
- // mov rax,QWORD PTR [rsp-0x88]
- // sahf
- // mov rax,QWORD PTR [rsp-0x80]
-
- uint8_t mov_rax_rsp_88[8];
- uint8_t lahf;
- uint8_t mov_rax_rsp_90[8];
- uint8_t mov_rbx_rsp_98[8];
-
- uint8_t mov_eax_prev_loc[6];
- uint8_t mov_prev_loc_curr_loc_shr1[10];
-
- uint8_t leax_eax_curr_loc[7];
+ // mov QWORD PTR [rsp-0x88],rax
+ // lahf
+ // mov QWORD PTR [rsp-0x90],rax
+ // mov QWORD PTR [rsp-0x98],rbx
- uint8_t mov_rbx_ptr_rax[2];
- uint8_t add_bl_1[3];
- uint8_t adc_bl_0[3];
- uint8_t mov_ptr_rax_rbx[2];
+ // mov eax,DWORD PTR [rip+0x1312334]
+ // xor eax,0x3f77
- uint8_t mov_rsp_98_rbx[8];
- uint8_t mov_rsp_90_rax[8];
- uint8_t sahf;
- uint8_t mov_rsp_88_rax[8];
+ // lea rbx,[rip+0x132338]
+ // add rax,rbx
-} afl_log_code_asm_t;
+ // mov bl,BYTE PTR [rax]
+ // add bl,0x1
+ // adc bl,0x0
+ // mov BYTE PTR [rax],bl
- #pragma pack(pop)
+ // mov rbx,QWORD PTR [rsp-0x98]
+ // mov rax,QWORD PTR [rsp-0x90]
+ // sahf
+ // mov rax,QWORD PTR [rsp-0x88]
-static const afl_log_code_asm_t template =
- {
-
- .mov_rax_rsp_88 = {0x48, 0x89, 0x84, 0x24, 0x78, 0xFF, 0xFF, 0xFF},
- .lahf = 0x9f,
- .mov_rax_rsp_90 = {0x48, 0x89, 0x84, 0x24, 0x70, 0xFF, 0xFF, 0xFF},
- .mov_rbx_rsp_98 = {0x48, 0x89, 0x9C, 0x24, 0x68, 0xFF, 0xFF, 0xFF},
-
- .mov_eax_prev_loc = {0x8b, 0x05},
- .mov_prev_loc_curr_loc_shr1 = {0xc7, 0x05},
-
- .leax_eax_curr_loc = {0x48, 0x8d, 0x05},
- .mov_rbx_ptr_rax = {0x8a, 0x18},
- .add_bl_1 = {0x80, 0xc3, 0x01},
- .adc_bl_0 = {0x80, 0xd3, 0x00},
- .mov_ptr_rax_rbx = {0x88, 0x18},
-
- .mov_rsp_98_rbx = {0x48, 0x8B, 0x9C, 0x24, 0x68, 0xFF, 0xFF, 0xFF},
- .mov_rsp_90_rax = {0x48, 0x8B, 0x84, 0x24, 0x70, 0xFF, 0xFF, 0xFF},
- .sahf = 0x9e,
- .mov_rsp_88_rax = {0x48, 0x8B, 0x84, 0x24, 0x78, 0xFF, 0xFF, 0xFF},
-
-}
-
-;
-
- #else
- #pragma pack(push, 1)
-typedef struct {
-
- // cur_location = (block_address >> 4) ^ (block_address << 8);
- // shared_mem[cur_location ^ prev_location]++;
- // prev_location = cur_location >> 1;
-
- // mov QWORD PTR [rsp-0x80],rax
- // lahf
- // mov QWORD PTR [rsp-0x88],rax
- // mov QWORD PTR [rsp-0x90],rbx
- // mov eax,DWORD PTR [rip+0x333d5a] # 0x7ffff6ff2740
- // mov DWORD PTR [rip+0x333d3c],0x9fbb # 0x7ffff6ff2740
- // xor eax,0x103f77
- // mov bl,BYTE PTR [rax]
- // add bl,0x1
- // adc bl,0x0
- // mov BYTE PTR [rax],bl
- // mov rbx,QWORD PTR [rsp-0x90]
- // mov rax,QWORD PTR [rsp-0x88]
- // sahf
- // mov rax,QWORD PTR [rsp-0x80]
+ // mov DWORD PTR [rip+0x13122f8],0x9fbb
uint8_t mov_rax_rsp_88[8];
uint8_t lahf;
@@ -150,10 +108,11 @@ typedef struct {
uint8_t mov_rbx_rsp_98[8];
uint8_t mov_eax_prev_loc[6];
- uint8_t mov_prev_loc_curr_loc_shr1[10];
-
uint8_t xor_eax_curr_loc[5];
+ uint8_t lea_rbx_area_ptr[7];
+ uint8_t add_rax_rbx[3];
+
uint8_t mov_rbx_ptr_rax[2];
uint8_t add_bl_1[3];
uint8_t adc_bl_0[3];
@@ -164,9 +123,11 @@ typedef struct {
uint8_t sahf;
uint8_t mov_rsp_88_rax[8];
+ uint8_t mov_prev_loc_curr_loc_shr1[10];
+
} afl_log_code_asm_t;
- #pragma pack(pop)
+ #pragma pack(pop)
static const afl_log_code_asm_t template =
{
@@ -177,9 +138,10 @@ static const afl_log_code_asm_t template =
.mov_rbx_rsp_98 = {0x48, 0x89, 0x9C, 0x24, 0x68, 0xFF, 0xFF, 0xFF},
.mov_eax_prev_loc = {0x8b, 0x05},
- .mov_prev_loc_curr_loc_shr1 = {0xc7, 0x05},
-
.xor_eax_curr_loc = {0x35},
+ .lea_rbx_area_ptr = {0x48, 0x8d, 0x1d},
+ .add_rax_rbx = {0x48, 0x01, 0xd8},
+
.mov_rbx_ptr_rax = {0x8a, 0x18},
.add_bl_1 = {0x80, 0xc3, 0x01},
.adc_bl_0 = {0x80, 0xd3, 0x00},
@@ -190,10 +152,11 @@ static const afl_log_code_asm_t template =
.sahf = 0x9e,
.mov_rsp_88_rax = {0x48, 0x8B, 0x84, 0x24, 0x78, 0xFF, 0xFF, 0xFF},
+ .mov_prev_loc_curr_loc_shr1 = {0xc7, 0x05},
+
}
;
- #endif
typedef union {
@@ -202,171 +165,12 @@ typedef union {
} afl_log_code;
- #ifdef __APPLE__
-
-void instrument_coverage_optimize_init(void) {
-
-}
-
- #else
-
-static gboolean instrument_coverage_find_low(const GumRangeDetails *details,
- gpointer user_data) {
-
- static GumAddress last_limit = (64ULL << 10);
- gpointer * address = (gpointer *)user_data;
-
- last_limit = GUM_ALIGN_SIZE(last_limit, __afl_map_size);
-
- if ((details->range->base_address - last_limit) > __afl_map_size) {
-
- *address = GSIZE_TO_POINTER(last_limit);
- return FALSE;
-
- }
-
- if (details->range->base_address > ((2ULL << 30) - __afl_map_size)) {
-
- return FALSE;
-
- }
-
- /*
- * Align our buffer on a 64k boundary so that the low 16-bits of the address
- * are zero, then we can just XOR the base address in, when we XOR with the
- * current block ID.
- */
- last_limit = GUM_ALIGN_SIZE(
- details->range->base_address + details->range->size, __afl_map_size);
- return TRUE;
-
-}
-
-static void instrument_coverage_optimize_map_mmap_anon(gpointer address) {
-
- __afl_area_ptr =
- mmap(address, __afl_map_size, PROT_READ | PROT_WRITE,
- MAP_FIXED_NOREPLACE | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
- if (__afl_area_ptr != address) {
-
- FATAL("Failed to map mmap __afl_area_ptr: %d", errno);
-
- }
-
-}
-
-static void instrument_coverage_optimize_map_mmap(char * shm_file_path,
- gpointer address) {
-
- int shm_fd = -1;
-
- if (munmap(__afl_area_ptr, __afl_map_size) != 0) {
-
- FATAL("Failed to unmap previous __afl_area_ptr");
-
- }
-
- __afl_area_ptr = NULL;
-
- #if !defined(__ANDROID__)
- shm_fd = shm_open(shm_file_path, O_RDWR, DEFAULT_PERMISSION);
- if (shm_fd == -1) { FATAL("shm_open() failed\n"); }
- #else
- shm_fd = open("/dev/ashmem", O_RDWR);
- if (shm_fd == -1) { FATAL("open() failed\n"); }
- if (ioctl(shm_fd, ASHMEM_SET_NAME, shm_file_path) == -1) {
-
- FATAL("ioctl(ASHMEM_SET_NAME) failed");
-
- }
-
- if (ioctl(shm_fd, ASHMEM_SET_SIZE, __afl_map_size) == -1) {
-
- FATAL("ioctl(ASHMEM_SET_SIZE) failed");
-
- }
-
- #endif
-
- __afl_area_ptr = mmap(address, __afl_map_size, PROT_READ | PROT_WRITE,
- MAP_FIXED_NOREPLACE | MAP_SHARED, shm_fd, 0);
- if (__afl_area_ptr != address) {
-
- FATAL("Failed to map mmap __afl_area_ptr: %d", errno);
-
- }
-
- if (close(shm_fd) != 0) { FATAL("Failed to close shm_fd"); }
-
-}
-
-static void instrument_coverage_optimize_map_shm(guint64 shm_env_val,
- gpointer address) {
-
- if (shmdt(__afl_area_ptr) != 0) {
-
- FATAL("Failed to detach previous __afl_area_ptr");
-
- }
-
- __afl_area_ptr = shmat(shm_env_val, address, 0);
- if (__afl_area_ptr != address) {
-
- FATAL("Failed to map shm __afl_area_ptr: %d", errno);
-
- }
-
-}
-
void instrument_coverage_optimize_init(void) {
- gpointer low_address = NULL;
-
- gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, instrument_coverage_find_low,
- &low_address);
-
- FVERBOSE("Low address: %p", low_address);
-
- if (low_address == 0 ||
- GPOINTER_TO_SIZE(low_address) > ((2UL << 30) - __afl_map_size)) {
-
- FATAL("Invalid low_address: %p", low_address);
-
- }
-
- ranges_print_debug_maps();
-
- char *shm_env = getenv(SHM_ENV_VAR);
- FVERBOSE("SHM_ENV_VAR: %s", shm_env);
-
- if (shm_env == NULL) {
-
- FWARNF("SHM_ENV_VAR not set, using anonymous map for debugging purposes");
-
- instrument_coverage_optimize_map_mmap_anon(low_address);
-
- } else {
-
- guint64 shm_env_val = g_ascii_strtoull(shm_env, NULL, 10);
-
- if (shm_env_val == 0) {
-
- instrument_coverage_optimize_map_mmap(shm_env, low_address);
-
- } else {
-
- instrument_coverage_optimize_map_shm(shm_env_val, low_address);
-
- }
-
- }
-
FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr);
}
- #endif
-
static void instrument_coverage_switch(GumStalkerObserver *self,
gpointer start_address,
const cs_insn * from_insn,
@@ -431,48 +235,19 @@ 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;
- gssize curr_loc_shr_1_offset =
- offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) +
- sizeof(code.code.mov_prev_loc_curr_loc_shr1) - sizeof(guint32);
-
- map_size_pow2 = util_log2(__afl_map_size);
- area_offset_ror = util_rotate(area_offset, 1, map_size_pow2);
-
- *((guint32 *)&code.bytes[curr_loc_shr_1_offset]) = (guint32)(area_offset_ror);
+ /* mov_prev_loc_curr_loc_shr1 */
gssize prev_loc_value =
GPOINTER_TO_SIZE(instrument_previous_pc_addr) -
@@ -490,6 +265,8 @@ void instrument_coverage_optimize(const cs_insn * instr,
*((gint *)&code.bytes[prev_loc_value_offset]) = (gint)prev_loc_value;
+ /* mov_eax_prev_loc */
+
gssize prev_loc_value2 =
GPOINTER_TO_SIZE(instrument_previous_pc_addr) -
(code_addr + offsetof(afl_log_code, code.mov_eax_prev_loc) +
@@ -505,40 +282,172 @@ void instrument_coverage_optimize(const cs_insn * instr,
*((gint *)&code.bytes[prev_loc_value_offset2]) = (gint)prev_loc_value2;
- #ifdef __APPLE__
+ /* xor_eax_curr_loc */
- gssize xor_curr_loc_offset = offsetof(afl_log_code, code.leax_eax_curr_loc) +
- sizeof(code.code.leax_eax_curr_loc) -
+ gssize xor_curr_loc_offset = offsetof(afl_log_code, code.xor_eax_curr_loc) +
+ sizeof(code.code.xor_eax_curr_loc) -
sizeof(guint32);
- gssize xor_curr_loc_value =
- ((GPOINTER_TO_SIZE(__afl_area_ptr) | area_offset) -
- (code_addr + offsetof(afl_log_code, code.mov_eax_prev_loc) +
- sizeof(code.code.mov_eax_prev_loc)));
+ *((guint32 *)&code.bytes[xor_curr_loc_offset]) = area_offset;
+
+ /* lea_rbx_area_ptr */
+
+ gssize lea_rbx_area_ptr_offset =
+ offsetof(afl_log_code, code.lea_rbx_area_ptr) +
+ sizeof(code.code.lea_rbx_area_ptr) - sizeof(guint32);
+
+ gssize lea_rbx_area_ptr_value =
+ (GPOINTER_TO_SIZE(__afl_area_ptr) -
+ (code_addr + offsetof(afl_log_code, code.lea_rbx_area_ptr) +
+ sizeof(code.code.lea_rbx_area_ptr)));
- if (!instrument_coverage_in_range(xor_curr_loc_value)) {
+ if (!instrument_coverage_in_range(lea_rbx_area_ptr_value)) {
- FATAL("Patch out of range (xor_curr_loc_value): 0x%016lX",
- xor_curr_loc_value);
+ FATAL("Patch out of range (lea_rbx_area_ptr_value): 0x%016lX",
+ lea_rbx_area_ptr_value);
}
- *((guint32 *)&code.bytes[xor_curr_loc_offset]) = xor_curr_loc_value;
+ *((guint32 *)&code.bytes[lea_rbx_area_ptr_offset]) = lea_rbx_area_ptr_value;
- #else
+ /* mov_prev_loc_curr_loc_shr1 */
- gssize xor_curr_loc_offset = offsetof(afl_log_code, code.xor_eax_curr_loc) +
- sizeof(code.code.xor_eax_curr_loc) -
- sizeof(guint32);
+ gssize curr_loc_shr_1_offset =
+ offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) +
+ sizeof(code.code.mov_prev_loc_curr_loc_shr1) - sizeof(guint32);
- *((guint32 *)&code.bytes[xor_curr_loc_offset]) =
- (guint32)(GPOINTER_TO_SIZE(__afl_area_ptr) | area_offset);
- #endif
+ map_size_pow2 = util_log2(__afl_map_size);
+ area_offset_ror = util_rotate(area_offset, 1, map_size_pow2);
+
+ *((guint32 *)&code.bytes[curr_loc_shr_1_offset]) = (guint32)(area_offset_ror);
gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
}
+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..82b8e63d 100644
--- a/frida_mode/src/js/api.js
+++ b/frida_mode/src/js/api.js
@@ -114,6 +114,12 @@ class Afl {
Afl.jsApiSetInstrumentTrace();
}
/**
+ * See `AFL_FRIDA_INST_INSN`
+ */
+ static setInstrumentInstructions() {
+ Afl.jsApiSetInstrumentInstructions();
+ }
+ /**
* See `AFL_FRIDA_INST_JIT`.
*/
static setInstrumentJit() {
@@ -297,6 +303,7 @@ Afl.jsApiSetDebugMaps = Afl.jsApiGetFunction("js_api_set_debug_maps", "void", []
Afl.jsApiSetEntryPoint = Afl.jsApiGetFunction("js_api_set_entrypoint", "void", ["pointer"]);
Afl.jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument_coverage_file", "void", ["pointer"]);
Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]);
+Afl.jsApiSetInstrumentInstructions = Afl.jsApiGetFunction("js_api_set_instrument_instructions", "void", []);
Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []);
Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []);
Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []);
diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c
index 94ec8842..89df7803 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_instructions(
+ void) {
+
+ instrument_coverage_insn = TRUE;
+
+}
+
__attribute__((visibility("default"))) void js_api_set_instrument_no_optimize(
void) {
diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c
index d8521300..bb6e4109 100644
--- a/frida_mode/src/main.c
+++ b/frida_mode/src/main.c
@@ -21,6 +21,7 @@
#include "intercept.h"
#include "js.h"
#include "lib.h"
+#include "module.h"
#include "output.h"
#include "persistent.h"
#include "prefetch.h"
@@ -197,6 +198,7 @@ __attribute__((visibility("default"))) void afl_frida_start(void) {
instrument_config();
js_config();
lib_config();
+ module_config();
output_config();
persistent_config();
prefetch_config();
@@ -214,6 +216,7 @@ __attribute__((visibility("default"))) void afl_frida_start(void) {
entry_init();
instrument_init();
lib_init();
+ module_init();
persistent_init();
prefetch_init();
seccomp_init();
diff --git a/frida_mode/src/module.c b/frida_mode/src/module.c
new file mode 100644
index 00000000..65b394cd
--- /dev/null
+++ b/frida_mode/src/module.c
@@ -0,0 +1,106 @@
+#include "intercept.h"
+#include "module.h"
+#include "util.h"
+
+#if defined(__linux__)
+ #include <dlfcn.h>
+ #include <link.h>
+#endif
+
+static guint page_size = 0;
+static gboolean handle_dlclose = FALSE;
+
+void module_config(void) {
+
+#if defined(__linux__)
+ handle_dlclose = (getenv("AFL_FRIDA_NO_MODULE") == NULL);
+#else
+ FWARNF("AFL_FRIDA_MODULE not supported");
+#endif
+
+}
+
+typedef struct {
+
+ GumMemoryRange range;
+ GumPageProtection protection;
+ GumFileMapping file;
+
+} gum_range_t;
+
+gboolean found_range(const GumRangeDetails *details, gpointer user_data) {
+
+ gum_range_t range = {0};
+ GArray * ranges = (GArray *)user_data;
+
+ range.range = *details->range;
+ range.protection = details->protection;
+ if (details->file != NULL) { range.file = *details->file; }
+
+ g_array_append_val(ranges, range);
+ return FALSE;
+
+}
+
+#if defined(__linux__)
+static int on_dlclose(void *handle) {
+
+ GArray * ranges = NULL;
+ struct link_map *lm = NULL;
+ gum_range_t * range = NULL;
+ GumAddress base;
+ GumAddress limit;
+ gpointer mem;
+
+ if (dlinfo(handle, RTLD_DI_LINKMAP, &lm) < 0) {
+
+ FFATAL("Failed to dlinfo: %s", dlerror());
+
+ }
+
+ FVERBOSE("on_dlclose: %s", lm->l_name);
+
+ ranges = g_array_new(FALSE, TRUE, sizeof(gum_range_t));
+ gum_module_enumerate_ranges(lm->l_name, GUM_PAGE_EXECUTE, found_range,
+ ranges);
+
+ int ret = dlclose(handle);
+ if (ret != 0) {
+
+ FWARNF("dlclose returned: %d (%s)", ret, dlerror());
+ return ret;
+
+ }
+
+ for (guint i = 0; i < ranges->len; i++) {
+
+ range = &g_array_index(ranges, gum_range_t, i);
+ base = range->range.base_address;
+ limit = base + range->range.size;
+ FVERBOSE("Reserving range: 0x%016lx, 0x%016lX", base, limit);
+ mem = gum_memory_allocate(GSIZE_TO_POINTER(base), range->range.size,
+ page_size, GUM_PAGE_NO_ACCESS);
+ if (mem == NULL) { FATAL("Failed to allocate %p (%d)", mem, errno); }
+
+ }
+
+ g_array_free(ranges, TRUE);
+ return 0;
+
+}
+
+#endif
+
+void module_init(void) {
+
+ FOKF(cBLU "Module" cRST " - " cYEL " [%c]", handle_dlclose ? 'X' : ' ');
+
+#if defined(__linux__)
+ if (!handle_dlclose) { return; }
+
+ page_size = gum_query_page_size();
+ intercept_hook(dlclose, on_dlclose, NULL);
+#endif
+
+}
+
diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c
index 84803453..d47d1c14 100644
--- a/frida_mode/src/ranges.c
+++ b/frida_mode/src/ranges.c
@@ -595,8 +595,6 @@ void ranges_init(void) {
ranges_inst_jit ? 'X' : ' ');
FOKF(cBLU "Ranges" cRST " - " cGRN "instrument libraries:" cYEL " [%c]",
ranges_inst_libs ? 'X' : ' ');
- FOKF(cBLU "Ranges" cRST " - " cGRN "instrument libraries:" cYEL " [%c]",
- ranges_inst_libs ? 'X' : ' ');
print_ranges("include", include_ranges);
print_ranges("exclude", exclude_ranges);
diff --git a/frida_mode/test/cmov/GNUmakefile b/frida_mode/test/cmov/GNUmakefile
new file mode 100644
index 00000000..96f1ae5b
--- /dev/null
+++ b/frida_mode/test/cmov/GNUmakefile
@@ -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_INST_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 \
+ -t 10000+ \
+ -- \
+ $(TEST_CMOV_OBJ) $(DUMMY_DATA_FILE)
+
+frida_noinst: $(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 \
+ -- \
+ $(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
diff --git a/frida_mode/test/cmov/Makefile b/frida_mode/test/cmov/Makefile
new file mode 100644
index 00000000..9ef6fc8f
--- /dev/null
+++ b/frida_mode/test/cmov/Makefile
@@ -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
diff --git a/frida_mode/test/cmov/cmov.c b/frida_mode/test/cmov/cmov.c
new file mode 100644
index 00000000..08c7c132
--- /dev/null
+++ b/frida_mode/test/cmov/cmov.c
@@ -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;
+
+}
+
diff --git a/frida_mode/test/python/GNUmakefile b/frida_mode/test/python/GNUmakefile
new file mode 100644
index 00000000..e4f7857b
--- /dev/null
+++ b/frida_mode/test/python/GNUmakefile
@@ -0,0 +1,37 @@
+PWD:=$(shell pwd)/
+ROOT:=$(PWD)../../../
+BUILD_DIR:=$(PWD)build/
+TESTINSTR_DATA_DIR:=$(BUILD_DIR)in/
+FRIDA_OUT:=$(BUILD_DIR)frida-out
+QEMU_OUT:=$(BUILD_DIR)qemu-out
+
+.PHONY: all clean run qemu frida
+
+all:
+ make -C $(ROOT)frida_mode/
+
+clean:
+ rm -rf $(BUILD_DIR)
+
+$(BUILD_DIR):
+ mkdir -p $@
+
+$(TESTINSTR_DATA_DIR): | $(BUILD_DIR)
+ mkdir -p $@
+
+run:
+ date
+ /usr/bin/python -c 'print("hi");'
+ date
+
+qemu:
+ date
+ $(ROOT)afl-qemu-trace \
+ /usr/bin/python -c 'print("hi");'
+ date
+
+frida:
+ date
+ LD_PRELOAD=$(ROOT)afl-frida-trace.so \
+ python -c 'print("hi");'
+ date
diff --git a/frida_mode/test/python/Makefile b/frida_mode/test/python/Makefile
new file mode 100644
index 00000000..e66cfdef
--- /dev/null
+++ b/frida_mode/test/python/Makefile
@@ -0,0 +1,17 @@
+all:
+ @echo trying to use GNU make...
+ @gmake all || echo please install GNUmake
+
+clean:
+ @gmake clean
+
+run:
+ @gmake run
+
+qemu:
+ @gmake qemu
+
+frida:
+ @gmake frida
+
+
diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts
index 57d7b5b5..7999b661 100644
--- a/frida_mode/ts/lib/afl.ts
+++ b/frida_mode/ts/lib/afl.ts
@@ -136,6 +136,13 @@ class Afl {
}
/**
+ * See `AFL_FRIDA_INST_INSN`
+ */
+ public static setInstrumentInstructions(): void {
+ Afl.jsApiSetInstrumentInstructions();
+ }
+
+ /**
* See `AFL_FRIDA_INST_JIT`.
*/
public static setInstrumentJit(): void {
@@ -367,6 +374,11 @@ class Afl {
"void",
["pointer"]);
+ private static readonly jsApiSetInstrumentInstructions = Afl.jsApiGetFunction(
+ "js_api_set_instrument_instructions",
+ "void",
+ []);
+
private static readonly jsApiSetInstrumentJit = Afl.jsApiGetFunction(
"js_api_set_instrument_jit",
"void",
diff --git a/include/envs.h b/include/envs.h
index f4327d8c..1f6d33e6 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -59,6 +59,7 @@ static char *afl_environment_variables[] = {
"AFL_FRIDA_EXCLUDE_RANGES",
"AFL_FRIDA_INST_COVERAGE_FILE",
"AFL_FRIDA_INST_DEBUG_FILE",
+ "AFL_FRIDA_INST_INSN",
"AFL_FRIDA_INST_JIT",
"AFL_FRIDA_INST_NO_OPTIMIZE",
"AFL_FRIDA_INST_NO_PREFETCH",