예제 #1
0
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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
    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)
예제 #6
0
    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)
예제 #7
0
    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
예제 #8
0
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))
예제 #9
0
    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
예제 #10
0
 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)
예제 #11
0
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
예제 #12
0
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
예제 #13
0
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 []
예제 #14
0
    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
예제 #15
0
    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
예제 #16
0
    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))
예제 #17
0
    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