Beispiel #1
0
def make_stdio_sw(fmt_type, types, pointerize):
    '''enum -> [str] -> bool -> dict'''
    # the printf/scanf parsers can parse nearly all format string types, but we
    # do not handle all of them here
    fmt_to_type = izip([fmt_type[x] for x in types],
                       c_type_to_slot)

    return {ty: (ep_ct.ptr(val)
                 if pointerize is True
                 else val)
            for (ty, (_, val)) in fmt_to_type}
Beispiel #2
0
def make_stdio_sw(fmt_type, types, pointerize):
    '''enum -> [str] -> bool -> dict'''
    # the printf/scanf parsers can parse nearly all format string types, but we
    # do not handle all of them here
    fmt_to_type = izip([fmt_type[x] for x in types],
                       c_type_to_slot)

    return {ty : (ep_ct.ptr(val)
                  if pointerize is True
                  else val)
            for (ty, (_, val)) in fmt_to_type}
Beispiel #3
0
printf_types = [
    'TYPE_SCHAR', 'TYPE_UCHAR', 'TYPE_SHORT', 'TYPE_USHORT',
    'TYPE_INT', 'TYPE_UINT', 'TYPE_LONGINT', 'TYPE_ULONGINT',
    'TYPE_LONGLONGINT', 'TYPE_ULONGLONGINT', 'TYPE_DOUBLE',
    'TYPE_DOUBLE', 'TYPE_CHAR'
]

scanf_types = [
    'TYPE_SCHAR', 'TYPE_UCHAR', 'TYPE_SHORT', 'TYPE_USHORT',
    'TYPE_INT', 'TYPE_UINT', 'TYPE_LONGINT', 'TYPE_ULONGINT',
    'TYPE_LONGLONGINT', 'TYPE_ULONGLONGINT', 'TYPE_FLOAT',
    'TYPE_DOUBLE', 'TYPE_CHAR'
]

printf_sw = make_stdio_sw(p_Arg_type, printf_types, pointerize=False)
printf_sw[p_Arg_type.TYPE_POINTER] = ep_ct.ptr(ep_ct.simple_typename(['void']))
printf_sw[p_Arg_type.TYPE_STRING] = ep_ct.ptr(ep_ct.simple_typename(['char']))

scanf_sw = make_stdio_sw(s_Arg_type, scanf_types, pointerize=True)
scanf_sw[s_Arg_type.TYPE_POINTER] = ep_ct.ptr(ep_ct.ptr(ep_ct.simple_typename(['void'])))
scanf_sw[s_Arg_type.TYPE_STRING] = ep_ct.ptr(ep_ct.simple_typename(['char']))
scanf_sw[s_Arg_type.TYPE_CHARSEQ] = scanf_sw[s_Arg_type.TYPE_STRING]


def n32ify_regs(regs):
    '''[str] -> [str]'''
    n32_map = {'$t0': '$a4', '$t1': '$a5', '$t2': '$a6', '$t3': '$a7'}
    r = enumerate(regs)

    return list(n32_map[reg] if reg in n32_map else regs[i] for (i, reg) in r)
Beispiel #4
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))
Beispiel #5
0
printf_types = [
    'TYPE_SCHAR', 'TYPE_UCHAR', 'TYPE_SHORT', 'TYPE_USHORT',
    'TYPE_INT', 'TYPE_UINT', 'TYPE_LONGINT', 'TYPE_ULONGINT',
    'TYPE_LONGLONGINT', 'TYPE_ULONGLONGINT', 'TYPE_DOUBLE',
    'TYPE_DOUBLE', 'TYPE_CHAR'
]

scanf_types = [
    'TYPE_SCHAR', 'TYPE_UCHAR', 'TYPE_SHORT', 'TYPE_USHORT',
    'TYPE_INT', 'TYPE_UINT', 'TYPE_LONGINT', 'TYPE_ULONGINT',
    'TYPE_LONGLONGINT', 'TYPE_ULONGLONGINT', 'TYPE_FLOAT',
    'TYPE_DOUBLE', 'TYPE_CHAR'
]

printf_sw = make_stdio_sw(p_Arg_type, printf_types, pointerize=False)
printf_sw[p_Arg_type.TYPE_POINTER] = ep_ct.ptr(
    ep_ct.simple_typename(['void']))
printf_sw[p_Arg_type.TYPE_STRING] = ep_ct.ptr(
    ep_ct.simple_typename(['char']))

scanf_sw = make_stdio_sw(s_Arg_type, scanf_types, pointerize=True)
scanf_sw[s_Arg_type.TYPE_POINTER] = ep_ct.ptr(ep_ct.ptr(
    ep_ct.simple_typename(['void'])))
scanf_sw[s_Arg_type.TYPE_STRING] = ep_ct.ptr(
    ep_ct.simple_typename(['char']))
scanf_sw[s_Arg_type.TYPE_CHARSEQ] = scanf_sw[s_Arg_type.TYPE_STRING]

def n32ify_regs(regs):
    '''[str] -> [str]'''
    n32_map = {'$t0' : '$a4', '$t1' : '$a5', '$t2' : '$a6', '$t3' : '$a7'}
    r = enumerate(regs)