예제 #1
0
def swap(il, addr, distance):
    stack_offset = distance * ADDR_SIZE

    load = il.load(
        ADDR_SIZE,
        il.add(ADDR_SIZE, il.reg(ADDR_SIZE, 'sp'),
               il.const(ADDR_SIZE, stack_offset)))

    il.append(il.set_reg(ADDR_SIZE, LLIL_TEMP(0), load))

    il.append(
        il.set_reg(ADDR_SIZE, LLIL_TEMP(1),
                   il.load(ADDR_SIZE, il.reg(ADDR_SIZE, 'sp'))))

    il.append(
        il.store(
            ADDR_SIZE,
            il.add(ADDR_SIZE, il.reg(ADDR_SIZE, 'sp'),
                   il.const(ADDR_SIZE, stack_offset)),
            il.reg(ADDR_SIZE, LLIL_TEMP(1))))
    il.append(
        il.store(ADDR_SIZE, il.reg(ADDR_SIZE, 'sp'),
                 il.reg(ADDR_SIZE, LLIL_TEMP(0))))

    return []
예제 #2
0
 def do_il(self, data, addr, il):
     src = SourceOperandsIL[self.flag](il, self.src_value)
     return [
         il.set_reg(2, LLIL_TEMP(0), src),
         il.set_reg(2, Registers[self.src_value],
                    il.reg(2, Registers[self.dst_value])),
         il.set_reg(2, Registers[self.dst_value], il.reg(2, LLIL_TEMP(0)))
     ]
예제 #3
0
def mstore(il, addr, imm):
    il.append(il.set_reg(ADDR_SIZE, LLIL_TEMP(0), il.pop(ADDR_SIZE)))
    il.append(il.set_reg(ADDR_SIZE, LLIL_TEMP(1), il.pop(ADDR_SIZE)))
    # il.append(
    #     il.store(
    #         ADDR_SIZE,
    #         il.unimplemented(),
    #         il.reg(ADDR_SIZE, LLIL_TEMP(1))
    #     )
    # )
    return []
예제 #4
0
def dup(il, addr, distance):
    il.append(
        il.set_reg(
            ADDR_SIZE, LLIL_TEMP(0),
            il.load(
                ADDR_SIZE,
                il.add(ADDR_SIZE, il.reg(ADDR_SIZE, 'sp'),
                       il.const(ADDR_SIZE, (distance - 1) * ADDR_SIZE)))))

    il.append(il.push(ADDR_SIZE, il.reg(ADDR_SIZE, LLIL_TEMP(0))))

    return []
예제 #5
0
파일: evm.py 프로젝트: sambacha/ethersplay
def exp_inst(il, addr, imm):
    base = il.pop(ADDR_SIZE)
    exponent = il.pop(ADDR_SIZE)
    il.append(il.set_reg(ADDR_SIZE, LLIL_TEMP(0), base))
    il.append(il.set_reg(ADDR_SIZE, LLIL_TEMP(1), exponent))
    if ('value' in dir(base) and 'value' in dir(exponent)
            and base.value.is_constant and exponent.value.is_constant):
        result = base.value.value**exponent.value.value
        il.append(il.push(ADDR_SIZE, il.const(ADDR_SIZE, result)))
    else:
        il.append(il.push(ADDR_SIZE, il.unimplemented()))
    il.append(il.nop())
    return []
예제 #6
0
    def jalr(self, il, op, imm, inst_size=4):

        if len(op) < 2:
            ret_adr = 'ra'
            base = op[0]
        else:
            ret_adr = op[0]
            base = op[1]

        # ret_addr => register where the return address is written to
        # base => call target (+ imm value)

        # copy base register to temp (needed in case base == ret_adr)
        il.append(
            il.set_reg(self.addr_size, LLIL_TEMP(0),
                       il.reg(self.addr_size, base)))
        base = il.reg(self.addr_size, LLIL_TEMP(0))

        # the zero register acts as a sink-hole for data, any write to it is
        # ignored, so we can just omit lifting this to LLIL altogether.
        if ret_adr != 'zero':
            # compute return address and store to ret_addr register
            il.append(
                il.set_reg(
                    self.addr_size, ret_adr,
                    il.const(self.addr_size, il.current_address + inst_size)))

        # compute the jump target
        dest = base
        if imm:
            il.append(
                il.set_reg(
                    self.addr_size, LLIL_TEMP(0),
                    il.add(self.addr_size,
                           base,
                           il.const(self.addr_size, imm))))
            dest = il.reg(self.addr_size, LLIL_TEMP(0))

        if ret_adr == 'zero':
            if base == 'ra' and not imm:
                # jalr zero, ra, 0 => jump to return address, but link address
                # is discarded into zero register => basically a JR ra => "ret"
                il.append(il.ret(dest))
            else:
                # if ret_adr == zero, but base != ra then we basically have a 
                # normal jump instead of a function call
                il.append(il.jump(dest))
        else:
            il.append(il.call(dest))
예제 #7
0
    def get_instruction_low_level_il(self, data, addr, il):
        instruction = disassemble_one(data, addr)

        ill = insn_il.get(instruction.name, None)
        if ill is None:

            for i in range(instruction.pops):
                il.append(
                    il.set_reg(ADDR_SIZE, LLIL_TEMP(i), il.pop(ADDR_SIZE))
                )

            for i in range(instruction.pushes):
                il.append(il.push(ADDR_SIZE, il.unimplemented()))

            il.append(il.nop())

            return instruction.size

        ils = ill(il, addr, instruction.operand)
        if isinstance(ils, list):
            for i in ils:
                il.append(il)
        else:
            il.append(ils)

        return instruction.size
예제 #8
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 []
예제 #9
0
def jump(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(0), il.pop(ADDR_SIZE)))

    # 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.jump(il.reg(ADDR_SIZE, LLIL_TEMP(addr))))

    return []
예제 #10
0
def call(il, src_op, src, src_value):
    if src_op == INDIRECT_AUTOINCREMENT_MODE:
        # autoincrement mode is special in that prior to making the call,
        # the register needs to be incremented. This requires a temp register,
        # so that the original value of the register can be preserved while
        # the register is incremented prior to actually making the call.
        temp_expr = il.set_reg(2, LLIL_TEMP(0), il.reg(2, src))

        call_expr = il.call(il.load(2, il.reg(2, LLIL_TEMP(0))))

        inc_expr = il.set_reg(2, src, il.add(2, il.reg(2, src), il.const(2,
                                                                         2)))

        il.append(temp_expr)
        il.append(inc_expr)

    elif src_op == IMMEDIATE_MODE:
        call_expr = il.call(il.const_pointer(2, src_value))

    else:
        call_expr = il.call(SourceOperandsIL[src_op](il, 2, src, src_value))

    il.append(call_expr)
예제 #11
0
    def get_instruction_low_level_il(self, data, addr, il):
        big_reg = LLIL_TEMP(il.temp_reg_count)

        big_reg_expr = il.set_reg(8, big_reg, il.add(8, il.reg(4, GPR[self.t]), il.shift_left(8, il.reg(4, GPR[self.s]), il.const(4, 32))))
        il.append(il.set_reg(4, GPR[self.r], il.logical_shift_right(4, big_reg_expr, il.reg(4, "sar"))))
        return self.length