static RList * r_core_asm_back_disassemble_all(RCore *core, ut64 addr, ut64 len, ut64 max_hit_count, ut32 extra_padding){ RList *hits = r_core_asm_hit_list_new (); RCoreAsmHit dummy_value; RCoreAsmHit *hit = NULL; RAsmOp op; ut8 *buf = (ut8 *)malloc (len + extra_padding); int current_instr_len = 0; ut64 current_instr_addr = addr, current_buf_pos = len - 1, hit_count = 0; memset (&dummy_value, 0, sizeof (RCoreAsmHit)); if (hits == NULL || buf == NULL ){ if (hits) { r_list_purge (hits); free (hits); } free (buf); return NULL; } if (r_io_read_at (core->io, addr-(len+extra_padding), buf, len+extra_padding) != len+extra_padding) { r_list_purge (hits); free (hits); free (buf); return NULL; } if (len == 0){ return hits; } current_buf_pos = len - 1; do { if (r_cons_singleton ()->breaked) break; // reset assembler r_asm_set_pc (core->assembler, current_instr_addr); current_instr_len = len - current_buf_pos + extra_padding; IFDBG eprintf("current_buf_pos: 0x%"PFMT64x", current_instr_len: %d\n", current_buf_pos, current_instr_len); current_instr_len = r_asm_disassemble (core->assembler, &op, buf+current_buf_pos, current_instr_len); hit = r_core_asm_hit_new (); hit->addr = current_instr_addr; hit->len = current_instr_len; hit->code = NULL; r_list_add_sorted (hits, hit, ((RListComparator)rcoreasm_address_comparator)); current_buf_pos--; current_instr_addr--; hit_count++; } while ( ((int) current_buf_pos >= 0) && (int)(len - current_buf_pos) >= 0 && hit_count <= max_hit_count); free(buf); return hits; }
static void add_hit_to_sorted_hits(RList* hits, ut64 addr, int len, ut8 is_valid) { RCoreAsmHit *hit = r_core_asm_hit_new(); if (hit) { IFDBG eprintf("*** Inserting instruction (valid?: %d): instr_addr: 0x%"PFMT64x" instr_len: %d\n", is_valid, addr, len ); hit->addr = addr; hit->len = len; hit->valid = is_valid; hit->code = NULL; r_list_add_sorted (hits, hit, ((RListComparator)rcoreasm_address_comparator)); } }
static int handle_forward_disassemble(RCore* core, RList *hits, ut8* buf, ut64 len, ut64 current_buf_pos, ut64 current_instr_addr, ut64 end_addr){ // forward disassemble from the current instruction up to the end address ut64 temp_instr_len = 0, temp_instr_addr = current_instr_addr, tmp_current_buf_pos = current_buf_pos, start = 0, end = 0, start_range = current_instr_addr, end_range = end_addr; RAsmOp op; RCoreAsmHit *hit = NULL, *found_addr = NULL; ut8 is_valid = R_FALSE; if (end_addr < current_instr_addr) return end_addr; r_asm_set_pc (core->assembler, current_instr_addr); while ( tmp_current_buf_pos < len && temp_instr_addr < end_addr) { temp_instr_len = len - tmp_current_buf_pos; IFDBG eprintf("Current position: %"PFMT64d" instr_addr: 0x%"PFMT64x"\n", tmp_current_buf_pos, temp_instr_addr); temp_instr_len = r_asm_disassemble (core->assembler, &op, buf+tmp_current_buf_pos, temp_instr_len); if (temp_instr_len == 0){ is_valid = R_FALSE; temp_instr_len = 1; } else is_valid = R_TRUE; // check to see if addr exits found_addr = find_addr(hits, temp_instr_addr); start = temp_instr_addr; end = temp_instr_addr + temp_instr_len; if (!found_addr) { add_hit_to_sorted_hits(hits, temp_instr_addr, temp_instr_len, is_valid); } else if (is_valid && !found_addr->valid && is_addr_in_range(start, end, start_range, end_range )) { ut32 prune_results = 0; prune_results = prune_hits_in_addr_range(hits, temp_instr_addr, temp_instr_len, is_valid); add_hit_to_sorted_hits(hits, temp_instr_addr, temp_instr_len, is_valid); if (prune_results ) { r_list_add_sorted (hits, hit, ((RListComparator)rcoreasm_address_comparator)); IFDBG eprintf("Pruned %u hits from list in fwd sweep.\n", prune_results); } else { free (hit); hit = NULL; } } temp_instr_addr += temp_instr_len; tmp_current_buf_pos += temp_instr_len; } return temp_instr_addr; }