Example #1
0
def fmt_op(arg, mnem, op=None):
    '''op_ty -> str -> opt:int -> c_ast()'''
    insn = insns.insns[mnem]

    def addrof_or_deref(arg):
        # since addiu cannot touch memory, it must be calculating an address
        if mnem == 'addiu' or (insn.ty == insns.types.usefn and insn.subst == 'memcpy'):
            return c_ast.UnaryOp('&', arg)
        else:
            return arg

    if arg.ty == ida.op_ty.reg:
        try:
            slot = insn.slots[op]
        except IndexError:
            slot = None
        reg = fmt_reg(mnem, arg.val, slot)
        if insn.ty == insns.types.usefn and insn.subst == 'memcpy':
            return c_ast.UnaryOp('&', reg)
        else:
            return reg

    if mnem == 'la':
        # XXX the "name" type is neither suitable for a decompiler nor a
        # braindead static translator such as this one.  i.e., in order to
        # translate to C, we have no choice but to deal with C's type system,
        # because things like "la ptr" should be translated as "reg = ptr", but
        # "la not_ptr" should be translated as "reg = &not_ptr"
        if arg.ty in [ida.op_ty.array, ida.op_ty.ptr]:
            return c_ast.ID(arg.val)
        elif arg.ty == ida.op_ty.name:
            return c_ast.UnaryOp('&', c_ast.ID(arg.val))
        else:  # an address
            return c_ast.Constant('int', str(arg.val))
    elif arg.ty == ida.op_ty.array:
        (idx, rem) = ida.item_off(arg.target)
        arr = c_ast.ArrayRef(c_ast.ID(arg.val), c_ast.Constant('int', str(idx)))

        return addrof_or_deref(arr)
        # retained in case we ever come across some strange pointer math.  this
        # will generate a nonsense lvalue anyway, so we'd need to handle it some
        # other way
        # left = addrof_or_deref(arr)
        #return c_ast.BinaryOp('+', left, c_ast.Constant('int', str(rem)))
    elif arg.ty == ida.op_ty.ptr:
        # dereferencing of pointers is handled by the "displ" case, so just
        # return an address here too
        (_, rem) = ida.item_off(arg.target)

        return c_ast.ID(arg.val)
        # same as above
        # return c_ast.BinaryOp('+',
        #                      c_ast.ID(arg.val),
        #                      c_ast.Constant('int', str(rem)))
    elif arg.ty == ida.op_ty.name:
        nameval = c_ast.ID(arg.val)
        return addrof_or_deref(nameval)
    elif arg.ty == ida.op_ty.displ:
        r = fmt_reg(mnem, arg.val.reg, ep_ct.slot_types.u32)
        off = c_ast.BinaryOp('+', r, c_ast.Constant('int', str(arg.val.displ)))
        tyns = ['char' if insns.types.usefn and insn.subst == 'memcpy'
                else insn.subst]
        cast = ep_ct.simple_cast(ep_ct.ptr(ep_ct.simple_typename(tyns)), off)

        if insn.ty == insns.types.usefn and insn.subst == 'memcpy':
            return cast
        else:
            return c_ast.UnaryOp('*', cast)
    else:
        return c_ast.Constant('int', str(arg.val))
Example #2
0
def do_lui(**kw):
    # {rt} = {op} << 16
    return ep_ct.do_assign(rt=kw['rt'], op=ep_ct.simple_cast(
        ep_ct.slot_to_typename[kw['result']],
        c_ast.BinaryOp('<<', kw['op'], c_ast.Constant('int', '16'))))
Example #3
0
 def fmt_reg_for_call(reg, slot, node):
     '''reg -> slot_ty -> c_ast -> c_ast'''
     reg_ast = fmt_reg(mnem, reg, slot)
     return ep_ct.simple_cast(node, reg_ast)
Example #4
0
 def cast(which):
     return ep_ct.simple_cast(ep_ct.simple_typename([kw['subst']]), which)