def find_interrupts(trace): to_remove = [] ints = trace.find_interrupts() for a,b in ints: i = a while trace[i].op != 'IFLO_INSN_BYTES': i -= 1 fault_idx = i fault_eip = trace[i].args[0] fault_insn = pydasm.get_instruction(trace[i].args[1].decode('hex'), pydasm.MODE_32) i = b while trace[i].op != 'IFLO_TB_HEAD_EIP': i += 1 ret_eip = trace[i].args[0] end = i # Default: delete up to the HEAD_EIP (i.e. start a new block) if trace[a].args[0] < 32 and fault_eip == ret_eip: start = fault_idx else: start = a # MZ says I only need to worry about this if it's a page fault. # Blame him if this breaks ;) if trace[a].args[0] == 0xe and (fault_eip == ret_eip or not is_branch(fault_insn)): # We want to merge the new TB in with this one while trace[i].op != "IFLO_INSN_BYTES": i += 1 end = i to_remove.append((start,end)) return to_remove
def fix_sti(trace, tbdict): tbs_to_fix = [] for t in tbdict: for tb in tbdict[t]: if any(i.op == 'IFLO_RESET_INHIBIT_IRQ' for i in tb.rbody): tbs_to_fix.append(tb) edits = [] for tb in tbs_to_fix: i, _ = first(lambda x: x[1].op == 'IFLO_RESET_INHIBIT_IRQ', tb.body) j = i while trace[j].op != 'IFLO_INSN_BYTES': j -= 1 last_idx = j last_eip = trace[j].args[0] last_insn = pydasm.get_instruction(trace[j].args[1].decode('hex'), pydasm.MODE_32) assert trace[i].op == 'IFLO_RESET_INHIBIT_IRQ' assert trace[i+1].op == 'IFLO_MOVL_T0_0' assert trace[i+2].op == 'IFLO_EXIT_TB' if is_branch(last_insn): ep = i+2 elif trace[i+3].op == 'IFLO_TB_HEAD_EIP': ep = i+3 elif trace[i+3].op == 'IFLO_TB_ID' and trace[i+4].op == 'IFLO_TB_HEAD_EIP': ep = i+4 else: ep = i+2 #print "Will heal TB %s by removing trace entry %d" % (`tb`, ep) edits.append((i,ep)) edits.sort() while edits: a,b = edits.pop() del trace[a:b+1] return remake_trace(trace)