aboutsummaryrefslogtreecommitdiff
path: root/frida_mode/src/instrument
diff options
context:
space:
mode:
authorYour Name <you@example.com>2021-11-09 18:29:25 +0000
committerYour Name <you@example.com>2021-11-09 18:29:25 +0000
commit8578b6b01c5f41d8a75ae83cb2c058fe89bf90df (patch)
tree14a5144c94ffb2020e008aba9bf6e9414fd11d96 /frida_mode/src/instrument
parent75821d2943ee207a6d862440ac1c466b96a52861 (diff)
downloadafl++-8578b6b01c5f41d8a75ae83cb2c058fe89bf90df.tar.gz
Inline instrumentation optimization for x64
Diffstat (limited to 'frida_mode/src/instrument')
-rw-r--r--frida_mode/src/instrument/instrument_x64.c131
1 files changed, 82 insertions, 49 deletions
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index 27704f9b..07605a04 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -52,29 +52,46 @@ typedef struct {
// shared_mem[cur_location ^ prev_location]++;
// prev_location = cur_location >> 1;
- // => 0x7ffff6cfb086: lea rsp,[rsp-0x80]
- // 0x7ffff6cfb08b: pushf
- // 0x7ffff6cfb08c: push rsi
- // 0x7ffff6cfb08d: mov rsi,0x228
- // 0x7ffff6cfb094: xchg QWORD PTR [rip+0x3136a5],rsi #
- // 0x7ffff700e740 0x7ffff6cfb09b: xor rsi,0x451 0x7ffff6cfb0a2: add
- // BYTE PTR [rsi+0x10000],0x1 0x7ffff6cfb0a9: adc BYTE PTR
- // [rsi+0x10000],0x0 0x7ffff6cfb0b0: pop rsi 0x7ffff6cfb0b1: popf
- // 0x7ffff6cfb0b2: lea rsp,[rsp+0x80]
+ // 0x7ffff6cbca41: lea rsp,[rsp-0x80]
+ //
+ // 0x7ffff6cbca46: push rax
+ // 0x7ffff6cbca47: lahf
+ // 0x7ffff6cbca48: push rax
+ //
+ // 0x7ffff6cbca49: mov eax,DWORD PTR [rip+0x33bcf1]
+ // 0x7ffff6cbca4f: xor eax,0x3f77
+ // 0x7ffff6cbca54: add eax,0x10000
+ // 0x7ffff6cbca59: add BYTE PTR [rax],0x1
+ // 0x7ffff6cbca5c: adc BYTE PTR [rax],0x0
+ //
+ // 0x7ffff6cbca5f: mov eax,0xbf77
+ // 0x7ffff6cbca64: mov DWORD PTR [rip+0x33bcd6],eax
+ //
+ // 0x7ffff6cbca6a: pop rax
+ // 0x7ffff6cbca6b: sahf
+ // 0x7ffff6cbca6c: pop rax
+ //
+ // 0x7ffff6cbca6d: lea rsp,[rsp+0x80]
uint8_t lea_rsp_rsp_sub_rz[5];
- uint8_t push_fq;
- uint8_t push_rsi;
- uint8_t mov_rsi_curr_loc_shr_1[7];
- uint8_t xchg_rsi_prev_loc_curr_loc[7];
- uint8_t xor_rsi_curr_loc[7];
+ uint8_t push_rax;
+ uint8_t lahf;
+ uint8_t push_rax2;
- uint8_t add_rsi_1[7];
- uint8_t adc_rsi_0[7];
+ uint8_t mov_eax_prev_loc[6];
+ uint8_t xor_eax_curr_loc[5];
+ uint8_t add_eax_afl_area[5];
+ uint8_t add_rax_1[3];
+ uint8_t adc_rax_0[3];
+
+ uint8_t mov_eax_curr_loc_shr_1[5];
+ uint8_t mov_eax_prev_loc_curr_loc[6];
+
+ uint8_t pop_rax2;
+ uint8_t sahf;
+ uint8_t pop_rax;
- uint8_t pop_rsi;
- uint8_t pop_fq;
uint8_t lsa_rsp_rsp_add_rz[8];
} afl_log_code_asm_t;
@@ -92,18 +109,24 @@ static const afl_log_code_asm_t template =
{
.lea_rsp_rsp_sub_rz = {0x48, 0x8D, 0x64, 0x24, 0x80},
- .push_fq = 0x9c,
- .push_rsi = 0x56,
+ .push_rax = 0x50,
+ .lahf = 0x9f,
+ .push_rax2 = 0x50,
+
+ .mov_eax_prev_loc = {0x8b, 0x05},
+ .xor_eax_curr_loc = {0x35},
+
+ .add_eax_afl_area = {0x05},
+ .add_rax_1 = {0x80, 0x00, 0x01},
+ .adc_rax_0 = {0x80, 0x10, 0x00},
- .mov_rsi_curr_loc_shr_1 = {0x48, 0xC7, 0xC6},
- .xchg_rsi_prev_loc_curr_loc = {0x48, 0x87, 0x35},
- .xor_rsi_curr_loc = {0x48, 0x81, 0xF6},
+ .mov_eax_curr_loc_shr_1 = {0xb8},
+ .mov_eax_prev_loc_curr_loc = {0x89, 0x05},
- .add_rsi_1 = {0x80, 0x86, 0x00, 0x00, 0x00, 0x00, 0x01},
- .adc_rsi_0 = {0x80, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00},
+ .pop_rax2 = 0x58,
+ .sahf = 0x9e,
+ .pop_rax = 0x58,
- .pop_rsi = 0x5E,
- .pop_fq = 0x9D,
.lsa_rsp_rsp_add_rz = {0x48, 0x8D, 0xA4, 0x24, 0x80, 0x00, 0x00, 0x00},
}
@@ -123,7 +146,7 @@ static gboolean instrument_coverage_find_low(const GumRangeDetails *details,
}
- if (details->range->base_address > ((2ULL << 20) - __afl_map_size)) {
+ if (details->range->base_address > ((2ULL << 30) - __afl_map_size)) {
return FALSE;
@@ -248,8 +271,6 @@ static void instrument_coverage_switch(GumStalkerObserver *self,
}
- // OKF("SKIP: %p %s %s", start_address, from_insn->mnemonic,
- // from_insn->op_str);
*target = *target + sizeof(afl_log_code);
}
@@ -327,6 +348,7 @@ void instrument_coverage_optimize(const cs_insn * instr,
afl_log_code code = {0};
GumX86Writer *cw = output->writer.x86;
guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
+ guint64 area_offset_ror;
GumAddress code_addr = 0;
instrument_coverage_suppress_init();
@@ -342,19 +364,21 @@ void instrument_coverage_optimize(const cs_insn * instr,
code.code = template;
gssize curr_loc_shr_1_offset =
- offsetof(afl_log_code, code.mov_rsi_curr_loc_shr_1) +
- sizeof(code.code.mov_rsi_curr_loc_shr_1) - sizeof(guint32);
+ offsetof(afl_log_code, code.mov_eax_curr_loc_shr_1) +
+ sizeof(code.code.mov_eax_curr_loc_shr_1) - sizeof(guint32);
- *((guint32 *)&code.bytes[curr_loc_shr_1_offset]) =
- (guint32)(area_offset >> 1);
+ area_offset_ror = ((area_offset & (MAP_SIZE - 1) >> 1)) |
+ ((area_offset & 0x1) << (MAP_SIZE_POW2 - 1));
+
+ *((guint32 *)&code.bytes[curr_loc_shr_1_offset]) = (guint32)(area_offset_ror);
gssize prev_loc_value =
GPOINTER_TO_SIZE(&instrument_previous_pc) -
- (code_addr + offsetof(afl_log_code, code.xchg_rsi_prev_loc_curr_loc) +
- sizeof(code.code.xchg_rsi_prev_loc_curr_loc));
+ (code_addr + offsetof(afl_log_code, code.mov_eax_prev_loc_curr_loc) +
+ sizeof(code.code.mov_eax_prev_loc_curr_loc));
gssize prev_loc_value_offset =
- offsetof(afl_log_code, code.xchg_rsi_prev_loc_curr_loc) +
- sizeof(code.code.xchg_rsi_prev_loc_curr_loc) - sizeof(gint);
+ offsetof(afl_log_code, code.mov_eax_prev_loc_curr_loc) +
+ sizeof(code.code.mov_eax_prev_loc_curr_loc) - sizeof(gint);
if (!instrument_coverage_in_range(prev_loc_value)) {
FATAL("Patch out of range (current_pc_value1): 0x%016lX", prev_loc_value);
@@ -363,22 +387,31 @@ void instrument_coverage_optimize(const cs_insn * instr,
*((gint *)&code.bytes[prev_loc_value_offset]) = (gint)prev_loc_value;
- gssize xor_curr_loc_offset = offsetof(afl_log_code, code.xor_rsi_curr_loc) +
- sizeof(code.code.xor_rsi_curr_loc) -
- sizeof(guint32);
+ gssize prev_loc_value2 =
+ GPOINTER_TO_SIZE(&instrument_previous_pc) -
+ (code_addr + offsetof(afl_log_code, code.mov_eax_prev_loc) +
+ sizeof(code.code.mov_eax_prev_loc));
+ gssize prev_loc_value_offset2 =
+ offsetof(afl_log_code, code.mov_eax_prev_loc) +
+ sizeof(code.code.mov_eax_prev_loc) - sizeof(gint);
+ if (!instrument_coverage_in_range(prev_loc_value)) {
- *((guint32 *)&code.bytes[xor_curr_loc_offset]) = (guint32)(area_offset);
+ FATAL("Patch out of range (current_pc_value1): 0x%016lX", prev_loc_value2);
+
+ }
- gssize add_rsi_1_offset = offsetof(afl_log_code, code.add_rsi_1) +
- sizeof(code.code.add_rsi_1) - sizeof(guint32) - 1;
+ *((gint *)&code.bytes[prev_loc_value_offset2]) = (gint)prev_loc_value2;
- *((guint32 *)&code.bytes[add_rsi_1_offset]) =
- (guint32)GPOINTER_TO_SIZE(__afl_area_ptr);
+ gssize xor_curr_loc_offset = offsetof(afl_log_code, code.xor_eax_curr_loc) +
+ sizeof(code.code.xor_eax_curr_loc) -
+ sizeof(guint32);
+
+ *((guint32 *)&code.bytes[xor_curr_loc_offset]) = (guint32)(area_offset);
- gssize adc_rsi_0_ffset = offsetof(afl_log_code, code.adc_rsi_0) +
- sizeof(code.code.adc_rsi_0) - sizeof(guint32) - 1;
+ gssize lea_rax_offset = offsetof(afl_log_code, code.add_eax_afl_area) +
+ sizeof(code.code.add_eax_afl_area) - sizeof(guint32);
- *((guint32 *)&code.bytes[adc_rsi_0_ffset]) =
+ *((guint32 *)&code.bytes[lea_rax_offset]) =
(guint32)GPOINTER_TO_SIZE(__afl_area_ptr);
gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));