示例#1
0
def is_jni_header_loaded():
    # not work as expected:
    # return idaapi.get_struc_id('JNIInvokeInterface_') != idaapi.BADADDR
    try:
        idc.parse_decl('JNIEnv *env', idc.PT_SILENT)
    except Exception as e:
        return False
    return True
示例#2
0
def apply_load_unload(ea, load=True):
    name = idc.GetFunctionName(ea)
    log('apply 0x%x %s', ea, name)
    decl = "{} {}(JavaVM *vm, void *reserved)".format(
        "jint" if load else "void", "JNI_OnLoad" if load else "JNI_OnUnload")
    prototype_details = idc.parse_decl(decl, idc.PT_SILENT)
    idc.apply_type(ea, prototype_details)
示例#3
0
def apply_like(path):
    with open('{}.log'.format(path), 'w') as log_fp:
        with open(path) as fp:
            like = json.load(fp)
        for item in like.values():
            if item[0] != 'subprogram':
                continue
            _, return_type, name, parameters, has_varargs = item
            address = get_name_ea(BADADDR, str(name))
            if address == BADADDR:
                log_fp.write('Subprogram not found: {}\n'.format(name))
                log_fp.flush()
                continue
            decl = resolve_type(like, return_type, log_fp) + ' ' + name + '('
            first = True
            for parameter_type, parameter_name in parameters:
                if first:
                    first = False
                else:
                    decl += ', '
                if not _is_uname(str(parameter_name)):
                    parameter_name = '_' + parameter_name
                decl += resolve_type(like, parameter_type, log_fp)
                if _is_uname(str(parameter_name)):
                    decl += ' ' + parameter_name
            if has_varargs:
                if not first:
                    decl += ', '
                decl += '...'
            decl += ')'
            log_fp.write('{}: ...\n'.format(decl))
            log_fp.flush()
            ret = apply_type(address, parse_decl(str(decl), 0))
            log_fp.write('... ret={}\n'.format(ret))
            log_fp.flush()
示例#4
0
def apply_signature(ea, sig):
    name = idc.get_func_name(ea)
    ret, args = sig
    log('apply 0x%x %s', ea, name)
    decl = '{} {}({})'.format(ret, name, args)
    # log(decl)
    prototype_details = idc.parse_decl(decl, idc.PT_SILENT)
    # idc.set_name(ea, name)
    idc.apply_type(ea, prototype_details)
示例#5
0
def force_variable(ea, type, name):
    t = ida_typeinf.tinfo_t()
    ida_typeinf.parse_decl(t, None, '{} a;'.format(type), 0)
    ida_bytes.del_items(
        ea, ida_bytes.DELIT_EXPAND | ida_bytes.DELIT_DELNAMES
        | ida_bytes.DELIT_NOCMT, t.get_size())
    ida_name.set_name(ea, name, ida_name.SN_CHECK)
    idc.apply_type(ea, idc.parse_decl('{} a;'.format(type), 0),
                   idc.TINFO_DEFINITE)
示例#6
0
def mark_string(ea, name=None):
    strlen = len(idc.get_strlit_contents(ea, -1) or '')
    ida_bytes.del_items(
        ea, ida_bytes.DELIT_EXPAND | ida_bytes.DELIT_DELNAMES
        | ida_bytes.DELIT_NOCMT, strlen + 1)
    ida_bytes.create_strlit(ea, strlen + 1, idc.get_inf_attr(idc.INF_STRTYPE))
    if name:
        ida_name.set_name(ea, name, ida_name.SN_CHECK)
    idc.apply_type(ea, idc.parse_decl('char const a[]', 0), idc.TINFO_DEFINITE)
    return get_cstring(ea)
示例#7
0
 def parse_type_declaration(self, new_type_declaration):
     result = idc.parse_decl(new_type_declaration, 0)
     if result is None:
         return False
     _, tp, fld = result
     tinfo = idaapi.tinfo_t()
     tinfo.deserialize(idaapi.cvar.idati, tp, fld, None)
     self.tinfo = tinfo
     self.is_array = False
     return True
示例#8
0
 def activate(self):
     new_type_declaration = idaapi.askstr(0x100, self.type_name,
                                          "Enter type:")
     result = idc.parse_decl(new_type_declaration, 0)
     if result is None:
         return
     _, tp, fld = result
     tinfo = idaapi.tinfo_t()
     tinfo.deserialize(idaapi.cvar.idati, tp, fld, None)
     self.tinfo = tinfo
     self.is_array = False
示例#9
0
def get_type_size(type):
    sid = idc.get_struc_id(type)
    if sid != idc.BADADDR:
        return idc.get_struc_size(sid)

    try:
        name, tp, fld = idc.parse_decl(type, 1)
        if tp:
            return idc.SizeOf(tp)
    except:
        return 0
示例#10
0
def get_typeinf(typestr):
    if not typestr:
        # Passing None to tinfo_t.get_named_type() can crash IDA
        return None
    tif = idaapi.tinfo_t()
    if tif.get_named_type(idaapi.get_idati(), typestr):
        return tif
    PT_SILENT = 1  # in IDA7.0 idc.PT_SILENT=2, which is incorrect
    py_type = idc.parse_decl(typestr, PT_SILENT)
    if not py_type:
        return None
    return deserialize_tinfo(py_type[1:])
示例#11
0
def DuplicateResolver(t1, t2, fToStorage=False):
    f = forms.DublicateResolverUI(t1.print_type(), t2.print_type(), fToStorage)
    while True:
        f.Go()
        if f.sel == 1:
            return t1
        elif f.sel == 2:
            return t2
        else:
            r = idc.parse_decl(f.selText, 0x008E)
            if r is not None:
                return LocalType(r[0], r[1], r[2])
示例#12
0
def force_array(ea, type, name, count=None):
    t = ida_typeinf.tinfo_t()
    ida_typeinf.parse_decl(t, None, '{} a;'.format(type), 0)
    ida_bytes.del_items(
        ea, ida_bytes.DELIT_EXPAND | ida_bytes.DELIT_DELNAMES
        | ida_bytes.DELIT_NOCMT,
        t.get_size() * (1 if count is None else count))
    ida_name.set_name(ea, name, ida_name.SN_CHECK)
    idc.apply_type(
        ea,
        idc.parse_decl(
            '{} a[{}];'.format(type, '' if count is None else str(count)), 0),
        idc.TINFO_DEFINITE)
示例#13
0
def import_structure(name, tinfo):
    cdecl_typedef = idaapi.print_tinfo(None, 4, 5, idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI,
                                       tinfo, name, None)
    if idc.parse_decl(cdecl_typedef, idaapi.PT_TYP) is None:
        return 0

    previous_ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, name)
    if previous_ordinal:
        idaapi.del_numbered_type(idaapi.cvar.idati, previous_ordinal)
        ordinal = idaapi.idc_set_local_type(previous_ordinal, cdecl_typedef, idaapi.PT_TYP)
    else:
        ordinal = idaapi.idc_set_local_type(-1, cdecl_typedef, idaapi.PT_TYP)
    return ordinal
示例#14
0
    def get_size(name, type, line):
        if type == "BasicType":
            try:
                return idc.SizeOf(idc.parse_decl(str(name), 0)[1])
            except:
                try:
                    idc.SizeOf(
                        idc.parse_decl(str(line.get("type").get("name")),
                                       0)[1])
                except:
                    return 1

        elif type == "ArrayType":
            subType = line.get("type")
            if not subType:
                return line.get("size")
            typeSize = IDAtools.get_size(str(subType.get("name")),
                                         subType.get("table"), subType)
            try:
                return (typeSize * int(line.get("size")))
            except TypeError:
                return 1
        elif type == "PointerType" or type == "ReferenceType" or type == "QualifierType":
            return 4
        elif type == "CFunctionType" or type == "CPPFunctionType":
            return 4
        elif type == "PDOMCEnumeration" or type == "PDOMCPPEnumeration":
            return idaapi.get_enum_size(idaapi.get_enum(str(name)))
        elif type == "PDOMCStructure" or type == "PDOMCPPClassType":
            return idaapi.get_struc_size(idaapi.get_struc_id(str(name)))
        elif type == "PDOMCTypedef" or type == "PDOMCPPTypedef":
            subType = line.get("type")
            if not subType:
                return 1
            return IDAtools.get_size(subType.get("name"), subType.get("table"),
                                     subType)
        else:
            raise Exception("Missing case", type)
示例#15
0
def mark_string(ea, name=None):
    strlen = len(idc.GetString(ea, -1))
    if strlen == 0:
        raise Exception(
            'tried marking {} as string, but it isn\'t (len 0)'.format(
                hex(ea)))
    ida_bytes.del_items(
        ea, ida_bytes.DELIT_EXPAND | ida_bytes.DELIT_DELNAMES
        | ida_bytes.DELIT_NOCMT, strlen + 1)
    ida_bytes.create_strlit(ea, strlen + 1, idc.get_inf_attr(idc.INF_STRTYPE))
    if name:
        ida_name.set_name(ea, name, ida_name.SN_CHECK)
    idc.apply_type(ea, idc.parse_decl('char const a[]', 0), idc.TINFO_DEFINITE)
    return idc.GetString(ea, -1)
示例#16
0
def apply_signature(ea, info):
    name = idc.GetFunctionName(ea)
    if info is None:
        log('WARN: no info found for %s', name)
        return
    log('apply 0x%x %s', ea, name)
    decl = '{} {}(JNIEnv* env, '.format(info['returnType'], name)
    if info['isStatic']:
        decl += 'jclass clazz'
    else:
        decl += 'jobject thiz'
    for idx, atype in enumerate(info['argumentTypes']):
        decl += ', {} arg{}'.format(atype, idx + 1)
    decl += ')'
    # log(decl)
    prototype_details = idc.parse_decl(decl, idc.PT_SILENT)
    # idc.set_name(ea, name)
    idc.apply_type(ea, prototype_details)
示例#17
0
    def __parse_declaration(declaration):
        m = re.search(r"^(\w+[ *]+)(\w+)$", declaration)
        if m is None:
            return

        type_name, field_name = m.groups()
        if field_name[0].isdigit():
            print "[ERROR] Bad field name"
            return

        result = idc.parse_decl(type_name, 0)
        if result is None:
            return

        _, tp, fld = result
        tinfo = idaapi.tinfo_t()
        tinfo.deserialize(idaapi.cvar.idati, tp, fld, None)
        return tinfo, field_name
示例#18
0
def fix_userpurge(funcea, flags=idc.TINFO_DEFINITE):
    """@return: True if __userpurge calling conv was found and fixed at funcea, otherwise False"""
    funcea = utils.get_func_start(funcea)
    if funcea == BADADDR:
        return False
    tif = utils.get_func_tinfo(funcea)
    if not tif:
        return False
    typestr = str(tif)
    if not typestr:
        return False
    if "__userpurge" not in typestr:
        return False
    typestr = typestr.replace("__userpurge", "(__thiscall)")
    typestr = re.sub(r"\@\<\w+\>", "", typestr)
    PT_SILENT = 1  # in IDA7.0 idc.PT_SILENT=2, which is incorrect
    py_type = idc.parse_decl(typestr, PT_SILENT)
    if not py_type:
        log.warn("%08X Failed to fix userpurge", funcea)
        return False
    return idc.apply_type(funcea, py_type[1:], flags)
示例#19
0
    def parse_declaration(declaration):
        m = re.search(r"^(\w+[ *]+)(\w+)(\[(\d+)\])?$", declaration)
        if m is None:
            logger.error("Member declaration should be like `TYPE_NAME NAME[SIZE]` (Array is optional)")
            return

        type_name, field_name, _, arr_size = m.groups()
        if field_name[0].isdigit():
            logger.error("Bad field name")
            return

        result = idc.parse_decl(type_name, 0)
        if result is None:
            logger.error("Failed to parse member type. It should be like `TYPE_NAME NAME[SIZE]` (Array is optional)")
            return

        _, tp, fld = result
        tinfo = idaapi.tinfo_t()
        tinfo.deserialize(idaapi.cvar.idati, tp, fld, None)
        if arr_size:
            assert tinfo.create_array(tinfo, int(arr_size))
        return tinfo, field_name
示例#20
0
def resolve_type(like, die_offset, log_fp, alias=None):
    if die_offset is None:
        return 'void'
    type = like.get(str(die_offset))
    if type is None:
        return DEFAULT_TYPE
    kind = type[0]
    if kind in ('struct', 'union'):
        if type[1] is None:
            if alias is None:
                struct_name = '{}_{}'.format(kind, hex(die_offset))
            else:
                struct_name = alias
        else:
            struct_name = type[1]
        if (not _is_uname(str(struct_name)) or
                (get_struc_id(str(struct_name)) == BADADDR and
                 get_name_ea(BADADDR, str(struct_name)) != BADADDR)):
            struct_name = '_' + struct_name
        struct_id = get_struc_id(str(struct_name))
        if struct_id != BADADDR:
            if len(type) == 4:
                type.append(struct_id)
            return struct_name
        log_fp.write('{}: ...\n'.format(struct_name))
        log_fp.flush()
        struct_id = add_struc(BADADDR, str(struct_name), kind == 'union')
        log_fp.write('... id={}\n'.format(hex(struct_id)))
        log_fp.flush()
        if struct_id == BADADDR:
            return DEFAULT_TYPE
        type.append(struct_id)
        if kind == 'struct' and type[2] != 0:
            ret = add_end_member(struct_id, struct_name, type[2], log_fp)
            have_end_member = ret == 0
        else:
            have_end_member = False
        for member_type_die_offset, member_name, member_offset in type[3]:
            if member_name is None:
                if kind == 'struct':
                    field_n = member_offset
                else:
                    field_n = sum(1 for _ in StructMembers(struct_id))
                member_name = 'field_{:X}'.format(field_n)
            elif not _is_uname(str(member_name)):
                member_name = '_' + member_name
            member_type_str = str(resolve_type(
                like, member_type_die_offset, log_fp))
            member_size = get_type_size(like, member_type_die_offset)
            if have_end_member and member_offset + member_size == type[2]:
                del_struc_member(struct_id, type[2] - 1)
                have_end_member = False
            log_fp.write('{} {}.{}: ...\n'.format(
                member_type_str, struct_name, member_name))
            log_fp.flush()
            ret = add_struc_member(
                struct_id,
                str(member_name),
                member_offset,
                DEFAULT_TYPE_FLAGS,
                DEFAULT_TYPE_ID,
                DEFAULT_TYPE_SIZE,
            )
            log_fp.write('... ret={}\n'.format(ret))
            log_fp.flush()
            if ret == 0:
                member_id = get_name_ea(
                    BADADDR, '{}.{}'.format(struct_name, member_name))
                apply_type(member_id, parse_decl(member_type_str, 0))
        return struct_name
    if kind == 'typedef':
        return resolve_type(like, type[2], log_fp, type[1])
    if kind == 'pointer':
        return resolve_type(like, type[1], log_fp) + '*'
    if kind == 'base':
        if type[1]:
            return '__int' + str(type[2] * 8)
        else:
            return 'unsigned __int' + str(type[2] * 8)
    if kind in ('const', 'volatile'):
        return resolve_type(like, type[1], log_fp)
    if kind == 'array':
        return '{}[{}]'.format(resolve_type(like, type[1], log_fp), type[2])
    return DEFAULT_TYPE
示例#21
0
def is_jni_header_loaded():
    # not work as expected:
    # return idaapi.get_struc_id('JNIInvokeInterface_') != idaapi.BADADDR
    ret = idc.parse_decl('JNIEnv *env', idc.PT_SILENT)
    return ret is not None