def cond_branch(il, cond, dest): t = il.get_label_for_address(Architecture['msp430'], il[dest].constant) if t is None: # t is not an address in the current function scope. t = LowLevelILLabel() indirect = True else: indirect = False f_label_found = True f = il.get_label_for_address(Architecture['msp430'], il.current_address + 2) if f is None: f = LowLevelILLabel() f_label_found = False il.append(il.if_expr(cond, t, f)) if indirect: # If the destination is not in the current function, # then a jump, rather than a goto, needs to be added to # the IL. il.mark_label(t) il.append(il.jump(dest)) if not f_label_found: il.mark_label(f)
def lift_cmp_eq(il: LowLevelILFunction, insn: SHInsn): assert len(insn.opcode["args"] ) == 2, f"Invalid instruction at: 0x{insn.addr:x}" op_1 = insn.opcode["args"][0] op_2 = insn.opcode["args"][1] extend = False if op_1.type == OpType.IMM: extend = True t = LowLevelILLabel() f = LowLevelILLabel() next_insn = LowLevelILLabel() il.append( il.if_expr( il.compare_equal( RSIZE, Lifter._lift_op(il, insn, op_1, sign_ext=extend), Lifter._lift_op(il, insn, op_2)), t, f)) il.mark_label(t) il.append(il.set_flag('t', il.const(0, 1))) il.append(il.goto(next_insn)) il.mark_label(f) il.append(il.set_flag('t', il.const(0, 0))) il.mark_label(next_insn)
def lift_bf(il: LowLevelILFunction, insn: SHInsn): assert len(insn.opcode["args"] ) == 1, f"Invalid instruction at: 0x{insn.addr:x}" op_1 = insn.opcode["args"][0] t = il.get_label_for_address(Architecture["superh"], op_1.val) if t is None: t = LowLevelILLabel() indirect = True else: indirect = False f = LowLevelILLabel() il.append( il.if_expr(il.compare_equal(0, il.flag("t"), il.const(0, 0)), t, f)) if indirect: il.mark_label(t) il.append(il.jump(il.const(RSIZE, op_1.val))) il.mark_label(f)
def lift_tst(il: LowLevelILFunction, insn: SHInsn): assert len(insn.opcode["args"] ) == 2, f"Invalid instruction at: 0x{insn.addr:x}" op_1 = insn.opcode["args"][0] op_2 = insn.opcode["args"][1] t = LowLevelILLabel() f = LowLevelILLabel() next_insn = LowLevelILLabel() il.append( il.if_expr( il.compare_equal( RSIZE, il.and_expr(RSIZE, Lifter._lift_op(il, insn, op_1), Lifter._lift_op(il, insn, op_2)), il.const(RSIZE, 0)), t, f)) il.mark_label(t) il.append(il.set_flag('t', il.const(0, 1))) il.append(il.goto(next_insn)) il.mark_label(f) il.append(il.set_flag('t', il.const(0, 0))) il.mark_label(next_insn)
def _handle_branch(il: LowLevelILFunction, nmemonic, inst_length, value): true_label = il.get_label_for_address(Architecture['M6800'], value) if true_label is None: true_label = LowLevelILLabel() indirect = True else: indirect = False false_label_found = True false_label = il.get_label_for_address( Architecture['M6800'], il.current_address + inst_length) if false_label is None: false_label = LowLevelILLabel() false_label_found = False il.append( il.if_expr(LLIL_OPERATIONS[nmemonic](il, None, None), true_label, false_label)) if indirect: il.mark_label(true_label) il.append(il.jump(il.const(2, value))) if not false_label_found: il.mark_label(false_label)
def condBranch(self, il, cond, imm): """ generic helper/lifter for all conditional branches """ dest = il.add( self.addr_size, il.const(self.addr_size, il.current_address), il.sign_extend(self.addr_size, il.const(self.addr_size, imm))) t = il.get_label_for_address(Architecture[self.arch_name], il.current_address + imm) if t is None: t = LowLevelILLabel() indirect = True else: indirect = False f_label_found = True f = il.get_label_for_address(Architecture[self.arch_name], il.current_address + 4) if f is None: f = LowLevelILLabel() f_label_found = False il.append(il.if_expr(cond, t, f)) if indirect: il.mark_label(t) il.append(il.jump(dest)) if not f_label_found: il.mark_label(f)
def get_instruction_low_level_il(self, data, addr, il): true_label = LowLevelILLabel() false_label = LowLevelILLabel() cmp_expr = il.compare_equal(4, il.reg(4, GPR[self.t]), il.const(4, 0)) if_expr = il.if_expr(cmp_expr, true_label, false_label) il.append(if_expr) il.mark_label(true_label) il.append(il.set_reg(4, GPR[self.r], il.reg(4, GPR[self.s]))) il.mark_label(false_label) return self.length
def cond_branch(il, cond, dest, fail_addr): label = None if il[dest].operation == LowLevelILOperation.LLIL_CONST: label = il.get_label_for_address(Architecture[ARCH_NAME], il[dest].constant) if label is None: label = LowLevelILLabel() indirect = True else: indirect = False f = il.get_label_for_address(Architecture[ARCH_NAME], fail_addr) if f is None: f = LowLevelILLabel() il.mark_label(f) il.append(il.if_expr(cond, label, f)) if indirect: il.mark_label(label) il.append(il.jump(dest))
def lift_ccmp(self, addr, data, il, insn): rn = insn.operands[0] rm = insn.operands[1] reg_size = get_reg_size(insn, rn) cond = insn.cc assert rm.type in (ARM64_OP_REG, ARM64_OP_IMM) t = LowLevelILLabel() f = LowLevelILLabel() e = LowLevelILLabel() il_cond = get_il_cond(il, cond) if il_cond is None: print("0x%x:\t%s\t%s %x" % (insn.address, insn.mnemonic, insn.op_str, cond)) return super(A64ArchHook, self).get_instruction_low_level_il(data, addr, il) il.append(il.if_expr(il_cond, t, f)) il.mark_label(f) nzcv = data[0] & 0xf set_il_flags(il, nzcv) il.append(il.goto(e)) il.mark_label(t) if rm.type == ARM64_OP_REG: il.append( il.sub(reg_size, self.get_reg_or_zero(il, insn, rn), self.get_reg_or_zero(il, insn, rm), flags='*')) elif rm.type == ARM64_OP_IMM: il.append( il.sub(reg_size, self.get_reg_or_zero(il, insn, rn), il.const(reg_size, rm.value.imm), flags='*')) il.append(il.goto(e)) il.mark_label(e) return 4
def cond_branch(self, il, cond, dest, false_addr): t = None if il[dest].operation == LowLevelILOperation.LLIL_CONST: t = il.get_label_for_address(self, il[dest].constant) if t is None: t = LowLevelILLabel() indirect = True else: indirect = False f = il.get_label_for_address(self, false_addr) found = f is not None if not found: f = LowLevelILLabel() il.append(il.if_expr(cond, t, f)) if indirect: il.mark_label(t) il.append(il.jump(dest)) if not found: il.mark_label(f)
def conditional_jump(il, cond, dest): t = None if il[dest].operation == LowLevelILOperation.LLIL_CONST: t = il.get_label_for_address(Architecture['spu'], il[dest].value) if t is None: t = LowLevelILLabel() indirect = True else: indirect = False f = LowLevelILLabel() il.append(il.if_expr(cond, t, f)) if indirect: il.mark_label(t) il.append(il.jump(dest)) il.mark_label(f) return None
def branch(il, pred, dst): """Copying from example w/o understanding""" t = None if il[dst].operation == LowLevelILOperation.LLIL_CONST: # Hmm. Should I be doing this for all SFRs? t = il.get_label_for_address(Architecture['8051'], il[dst].value) # And arch is cached, right? indirect = t is None if indirect: t = LowLevelILLabel() f = LowLevelILLabel() il.append(il.if_expr(pred, t, f)) if indirect: il.mark_label(t) il.append(il.jump(dst)) il.mark_label(f) return None
def jumpi(il, addr, imm): dest = il.pop(ADDR_SIZE) if len(il) > 0: push = il[len(il)-1] else: push = None if (push is not None and push.operation == LowLevelILOperation.LLIL_PUSH and push.src.operation == LowLevelILOperation.LLIL_CONST): dest = il.const(ADDR_SIZE, push.src.constant) il.append(il.set_reg(ADDR_SIZE, LLIL_TEMP(1), il.pop(ADDR_SIZE))) else: il.append(dest) t = LowLevelILLabel() f = il.get_label_for_address(Architecture['EVM'], addr+1) must_mark = False if f is None: f = LowLevelILLabel() must_mark = True # We need to use a temporary register here. The il.if_expr() helper # function makes a tree and evaluates the condition's il.pop() # first, but dest needs to be first. #il.append(il.set_reg(ADDR_SIZE, LLIL_TEMP(addr), dest)) il.append(il.set_reg(ADDR_SIZE, LLIL_TEMP(0), il.pop(ADDR_SIZE))) il.append(il.if_expr(il.reg(ADDR_SIZE, LLIL_TEMP(0)), t, f)) il.mark_label(t) il.append(il.jump(il.unimplemented())) # il.reg(ADDR_SIZE, LLIL_TEMP(1)))) if must_mark: il.mark_label(f) # false is the fall through case il.append(il.jump(il.const(ADDR_SIZE, addr + 1))) return []
def lift_csinc(self, addr, data, il, insn): if len(insn.operands) != 3: print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str)) return super(A64ArchHook, self).get_instruction_low_level_il(data, addr, il) t = LowLevelILLabel() f = LowLevelILLabel() e = LowLevelILLabel() rd = insn.operands[0] rn = insn.operands[1] rm = insn.operands[2] cond = insn.cc il_cond = get_il_cond(il, cond) if il_cond is None: print("0x%x:\t%s\t%s %x" % (insn.address, insn.mnemonic, insn.op_str, cond)) return super(A64ArchHook, self).get_instruction_low_level_il(data, addr, il) il.append(il.if_expr(il_cond, t, f)) reg_size = get_reg_size(insn, rd) il.mark_label(f) il.append( il.set_reg( reg_size, self.get_bn_reg_index(insn, rd), il.add(reg_size, self.get_reg_or_zero(il, insn, rm), il.const(reg_size, 1)))) il.append(il.goto(e)) il.mark_label(t) il.append( il.set_reg(reg_size, self.get_bn_reg_index(insn, rd), self.get_reg_or_zero(il, insn, rn))) il.append(il.goto(e)) il.mark_label(e) return 4
def get_instruction_low_level_il(self, data, addr, il): negative_label = LowLevelILLabel() positive_label = LowLevelILLabel() post_label = LowLevelILLabel() # Check if we have a positive or negative number cmp_expr = il.compare_signed_greater_equal( 4, il.sign_extend(4, il.reg(4, GPR[self.t])), il.const(4, 0)) if_expr = il.if_expr(cmp_expr, positive_label, negative_label) il.append(if_expr) # if it is negative, we want to negate it il.mark_label(negative_label) il.append(il.set_reg(4, GPR[self.r], il.neg_expr(4, il.reg(4, GPR[self.t])))) il.append(il.goto(post_label)) # otherwise, just move the value il.mark_label(positive_label) il.append(il.set_reg(4, GPR[self.r], il.reg(4, GPR[self.t]))) il.append(il.goto(post_label)) il.mark_label(post_label) return self.length
def low_level_il(self, il): a, b = self.operands_to_il(il) condition = il.compare_equal(size, a, il.const(size, 0)) addr = getattr(il[b], 'constant', None) true_branch = addr and il.get_label_for_address(il.arch, addr) indirect = not true_branch if indirect: true_branch = LowLevelILLabel() false_branch = il.get_label_for_address(il.arch, self.next_operation) il.append(il.if_expr(condition, true_branch, false_branch)) if indirect: il.mark_label(true_branch) il.append(il.jump(b))
def perform_get_instruction_low_level_il(self, data, addr, il): # If we can't decode an instruction return None if len(data) < 12: return None # Unpack our operands from the data a, b, c = struct.unpack('<3I', data[:4 * 3]) # If this instruction would crash, ignore it if b * 4 >= 0x4400 or a * 4 >= 0x4400: il.append(il.nop()) return 4 * 3 # A, B, and C as pointers addr_a = il.const_pointer(4, a * 4) addr_b = il.const_pointer(4, a * 4) addr_c = il.const_pointer(4, c * 4) # mem[A] and mem[B] pointers mem_a = il.load(4, addr_a) mem_b = il.load(4, addr_b) # For a clear instruction just store 0 if a == b: # *B = 0 store_b = il.store(4, addr_b, il.const(4, 0)) il.append(store_b) # For normal operation, construct a subtraction else: # *B = *B - *A sub_op = il.sub(4, mem_b, mem_a) store_b = il.store(4, addr_b, sub_op) il.append(store_b) # Unconditional jump if c != 0 and b == a: # goto C jmp = il.jump(addr_c) il.append(jmp) # Conditional jump elif c != 0: # See if we have marked the True jump target before t_target = il.get_label_for_address( Architecture['subleq'], il[il.const_pointer(4, c * 4)].constant) # Create the False jump label f_target = LowLevelILLabel() # If we have to create a jump IL for the True target indirect = t_target is None if indirect: t_target = LowLevelILLabel() less_op = il.compare_signed_less_equal(4, mem_b, il.const(4, 0)) if_op = il.if_expr(less_op, t_target, f_target) il.append(if_op) # We need to create a jump to the true target if it doesn't exist if indirect: il.mark_label(t_target) jmp = il.jump(addr_c) il.append(jmp) # Last is the fall though for the false target il.mark_label(f_target) return 12