Пример #1
0
    def initialize_nodes(self):
        for ordinal in xrange(1, idc.GetMaxLocalType()):
            # if ordinal == 15:
            #     import pydevd
            #     pydevd.settrace("localhost", port=12345, stdoutToServer=True, stderrToServer=True)

            local_tinfo = StructureGraph.get_tinfo_by_ordinal(ordinal)
            if not local_tinfo:
                continue
            name = idc.GetLocalTypeName(ordinal)

            if local_tinfo.is_typeref():
                typeref_ordinal = local_tinfo.get_ordinal()
                members_ordinals = []
                if typeref_ordinal:
                    typeref_tinfo = StructureGraph.get_tinfo_by_ordinal(
                        typeref_ordinal)
                    if typeref_tinfo.is_typeref() or typeref_tinfo.is_udt(
                    ) or typeref_tinfo.is_ptr():
                        members_ordinals = [typeref_ordinal]
                cdecl_typedef = idaapi.print_tinfo(None, 4, 5, 0x3,
                                                   local_tinfo, None, None)
                self.local_types[ordinal] = LocalType(name,
                                                      members_ordinals,
                                                      cdecl_typedef,
                                                      is_typedef=True)
            elif local_tinfo.is_udt():
                # udt_data = idaapi.udt_type_data_t()
                # local_tinfo.get_udt_details(udt_data)
                members_ordinals = StructureGraph.get_members_ordinals(
                    local_tinfo)
                cdecl_typedef = idaapi.print_tinfo(None, 4, 5, 0x1,
                                                   local_tinfo, None, None)
                self.local_types[ordinal] = LocalType(
                    name,
                    members_ordinals,
                    cdecl_typedef,
                    is_union=local_tinfo.is_union())
            elif local_tinfo.is_ptr():
                typeref_ordinal = StructureGraph.get_ordinal(local_tinfo)
                members_ordinals = [typeref_ordinal] if typeref_ordinal else []
                cdecl_typedef = idaapi.print_tinfo(None, 4, 5, 0x2,
                                                   local_tinfo, None, None)
                self.local_types[ordinal] = LocalType(name,
                                                      members_ordinals,
                                                      cdecl_typedef + ' *',
                                                      is_typedef=True)
            elif local_tinfo.is_enum():
                cdecl_typedef = idaapi.print_tinfo(None, 4, 5, 0x21,
                                                   local_tinfo, None, None)
                self.local_types[ordinal] = LocalType(name, [],
                                                      cdecl_typedef,
                                                      is_enum=True)

        self.ordinal_list = set(self.ordinal_list).intersection(
            self.local_types)
        for ordinal in self.ordinal_list:
            self.local_types[ordinal].is_selected = True
Пример #2
0
def get_type(addr):
    tif = idaapi.tinfo_t()
    idaapi.get_tinfo2(addr, tif)
    funcdata = idaapi.func_type_data_t()
    tif.get_func_details(funcdata)
    func_type = idaapi.print_tinfo("", 0, 0, PRTYPE_1LINE, tif, "", "")
    ret_type = idaapi.print_tinfo("", 0, 0, PRTYPE_1LINE, funcdata.rettype, "", "")
    args = []
    for i in xrange(funcdata.size()):
        arg_type = idaapi.print_tinfo("", 0, 0, PRTYPE_1LINE, funcdata[i].type, "", "")
        args.append([i, funcdata[i].name, arg_type, funcdata[i].argloc.atype()])
    return [func_type, ret_type, args]
Пример #3
0
    def run(self):
        self.logger.info('Starting up')
        try:
            here = idc.here()
            self.logger.info('Using ea: 0x%08x', here)

            if not idc.GetMnem(here).startswith('call'):
                self.logger.info(
                    'Not running at a call instruction. Bailing out now')
                return
            if idc.GetOpType(here, 0) == idc.o_near:
                self.logger.info(
                    "Cannot (or shouldn't) run when call optype is o_near")
                return

            dlg = ApplyCalleeTypeWidget()
            oldTo = idaapi.set_script_timeout(0)
            res = dlg.exec_()
            idaapi.set_script_timeout(oldTo)

            if res == QtWidgets.QDialog.Accepted:
                self.logger.debug('Dialog accepted. Input type: %d',
                                  dlg.inputType)
            else:
                self.logger.debug('Dialog rejected')
                return

            tinfo = None
            #check user input type
            if dlg.inputType == dlg.USER_TYPE:
                decl = self.convertUserType(str(dlg.getUserText()))
                tinfo = self.getUserDeclType(decl)
            elif dlg.inputType == dlg.STANDARD_TYPE:
                tinfo = self.getBuiltinGlobalType()
            elif dlg.inputType == dlg.LOCAL_TYPE:
                tinfo = self.getLocalType()
            else:
                self.logger.info('Bad user input type')
                return
            if tinfo is None:
                self.logger.debug('Bailing due to null tinfo')
                return
            #self.logger.info('Deserialize result: %r', ret)
            #not 100% sure if i need to explicitly convert from func to funcptr - seemed
            # to pretty much work without this, but doing it just to be sure
            if not tinfo.is_funcptr():
                self.logger.debug('Converting to func pointer')
                tinfo.create_ptr(tinfo)
            typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, tinfo,
                                          '', '')
            self.logger.info('Applying tinfo: "%s"', str(typename))
            #both applying callee type & setting op type -> not sure if both are needed?
            # set op type causes change in hexrays decompilation
            # apply callee type updates ida's stack analysis
            ret = idaapi.apply_callee_tinfo(here, tinfo)
            ret = idaapi.set_op_tinfo2(here, 0, tinfo)
            self.logger.debug('set_op_tinfo2 result: %r', ret)

        except Exception, err:
            self.logger.exception("Exception caught: %s", str(err))
Пример #4
0
    def type_str(self):
        """
        A string representation of the argument type
        """
        typeStr = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, self.argtype, '', '')

        return typeStr
def build_structure_in_ida(udt_data, structure_name):
    # 结构体的创建
    final_tinfo = idaapi.tinfo_t()
    final_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT)
    cdecl = idaapi.print_tinfo(
        None, 4, 5,
        idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI,
        final_tinfo, structure_name, None)

    print cdecl
    # cdecl = "struct Test_Python_Type{int filed_1;};"

    # structure_name = idaapi.idc_parse_decl(idaapi.cvar.idati, cdecl, idaapi.PT_TYP)[0]

    # 先删除
    # tid = idaapi.del_numbered_type(idaapi.cvar.idati, struct_ordinal)
    # print tid
    # struct_ordinal = 21
    previous_ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati,
                                               structure_name)
    if previous_ordinal:
        struct_ordinal = previous_ordinal
        # 如果之前的编号存在,则删除编号,重新创建
        idaapi.del_numbered_type(idaapi.cvar.idati, previous_ordinal)
        # 创建type
        tid = idaapi.idc_set_local_type(struct_ordinal, cdecl, idaapi.PT_TYP)
        # print tid
    else:
        tid = idaapi.idc_set_local_type(-1, cdecl, idaapi.PT_TYP)
Пример #6
0
    def select_structure_by_size(size):
        result = TypeLibrary.choose_til()
        if result:
            selected_library, max_ordinal, is_local_type = result
            matched_types = []
            tinfo = idaapi.tinfo_t()
            for ordinal in xrange(1, max_ordinal):
                tinfo.create_typedef(selected_library, ordinal)
                if tinfo.get_size() == size:
                    name = tinfo.dstr()
                    description = idaapi.print_tinfo(None, 0, 0,
                                                     idaapi.PRTYPE_DEF, tinfo,
                                                     None, None)
                    matched_types.append([str(ordinal), name, description])

            type_chooser = Forms.MyChoose(
                matched_types, "Select Type",
                [["Ordinal", 5 | idaapi.Choose2.CHCOL_HEX], ["Type Name", 25],
                 ["Declaration", 50]], 165)
            selected_type = type_chooser.Show(True)
            if selected_type != -1:
                if is_local_type:
                    return int(matched_types[selected_type][0])
                return TypeLibrary.import_type(selected_library,
                                               matched_types[selected_type][1])
        return None
Пример #7
0
    def export(self):
        if self.existed() and not self.f_update:
            info('{}: The sample records are present in DB. skipped.'.format(self.sha256))
            return False

        self.cur.execute("REPLACE INTO sample values(?, ?)", (self.sha256, self.idb_path))

        pnum = tnum = 0
        records = []
        for fva in idautils.Functions():
            fname = get_func_name(fva)
            tnum += 1
            if self.exclude_libthunk(fva, fname):
                continue
            fhd, bsize = self.calc_fn_ssdeep(fva, fname)
            fhm, cfgnum = self.calc_fn_machoc(fva, fname)
            if fhd and fhm:
                pnum += 1
                f_ana = bool(self.ana_pat.search(fname)) if self.f_ana_exp else False
                tinfo = idaapi.tinfo_t()
                idaapi.get_tinfo(fva, tinfo)
                ptype = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, tinfo, fname, '')
                ptype = ptype + ';' if ptype is not None else ptype
                # fva is 64-bit int causing OverflowError
                records.append((self.sha256, '{:#x}'.format(fva), fname, fhd, fhm, f_ana, bsize, ptype)) 
                self.debug('EXPORT {} at {:#x}: ssdeep={} (size={}), machoc={} (num of CFG={})'.format(fname, fva, fhd, bsize, fhm, cfgnum))

        self.cur.executemany("REPLACE INTO function values (?, ?, ?, ?, ?, ?, ?, ?)", records)
        success ('{} of {} functions exported'.format(pnum, tnum))
        return True
Пример #8
0
    def ev_calc_purged_bytes(self, p_purged_bytes, fti):
        logging.debug("##########ev_calc_purged_bytes")
        logging.debug(fti.size())
        logging.debug(fti.get_call_method())
        logging.debug(fti.is_pure())
        logging.debug(fti.rettype.get_size())

        # Information about each argument IF there are any, NOTE that if the next instruction is unlink then NO purge is done
        ##########
        # NOTES:
        #   https://reverseengineering.stackexchange.com/questions/8870/extracting-arguments-from-ida
        #   https://github.com/gsmk/hexagon/blob/master/pmbase.h
        #   https://github.com/idapython/src/blob/master/pywraps/py_idp.hpp#L608
        #   LOCATION TYPE: https://www.hex-rays.com/products/ida/support/sdkdoc/group___a_l_o_c__.html
        #
        for i in xrange(fti.size()):
            logging.debug(
                "Arg %d: %s (of type %s, and of location: %s)" %
                (i, fti[i].name,
                 idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, fti[i].type,
                                    '', ''), fti[i].argloc.atype()))

        # Sort of wrong, there could be shorts or other odd sized things on the stack
        p_purged_bytes = fti.size() * 4

        return 1
Пример #9
0
    def import_struct(self):
        if self.has_name_collisions():
            self.resolve_name_collisions()

        cdecl_typedef = '#pragma pack(push, 1)\n' + idaapi.print_tinfo(
            None, 4, 5, idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE
            | idaapi.PRTYPE_SEMI, self.tinfo, self.name, None)

        previous_ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati,
                                                   self.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)

        if ordinal:
            self.ordinal = ordinal
            print 'Imported struct \'%s\', ordinal %#x' % (self.name,
                                                           self.ordinal)
            return idaapi.import_type(idaapi.cvar.idati, -1, self.name)
        else:
            print 'Error due importing struct \'%s\', ordinal %#x' % (
                self.name, ordinal)
            return idaapi.BADNODE
Пример #10
0
    def import_to_structures(self, ask=False):
        """
        Imports virtual tables and returns tid_t of new structure

        :return: idaapi.tid_t
        """
        cdecl_typedef = idaapi.print_tinfo(
            None, 4, 5,
            idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI,
            self.create_tinfo(), self.vtable_name, None)
        if ask:
            cdecl_typedef = idaapi.ask_text(
                0x10000, cdecl_typedef,
                "The following new type will be created")
            if not cdecl_typedef:
                return
        previous_ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati,
                                                   self.vtable_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)

        if ordinal:
            print("[Info] Virtual table " + self.vtable_name +
                  " added to Local Types")
            return idaapi.import_type(idaapi.cvar.idati, -1, self.vtable_name)
        else:
            print("[Error] Failed to create virtual table " + self.vtable_name)
            print("*" * 100)
            print(cdecl_typedef)
            print("*" * 100)
Пример #11
0
    def type_str(self):
        """
        A string representation of the argument type
        """
        typeStr = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE,
                                     self.argtype, '', '')

        return typeStr
Пример #12
0
    def pack(self, start=0, stop=None):
        if self.collisions[start:stop].count(True):
            print "[Warning] Collisions detected"
            return

        final_tinfo = idaapi.tinfo_t()
        udt_data = idaapi.udt_type_data_t()
        origin = self.items[start].offset if start else 0
        offset = origin

        for item in filter(lambda x: x.enabled, self.items[start:stop]):    # Filter disabled members
            gap_size = item.offset - offset
            if gap_size:
                udt_data.push_back(TemporaryStructureModel.get_padding_member(offset - origin, gap_size))
            if item.is_array:
                array_size = self.calculate_array_size(bisect.bisect_left(self.items, item))
                if array_size:
                    udt_data.push_back(item.get_udt_member(array_size, offset=origin))
                    offset = item.offset + item.size * array_size
                    continue
            udt_data.push_back(item.get_udt_member(offset=origin))
            offset = item.offset + item.size

        final_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT)
        cdecl = idaapi.print_tinfo(None, 4, 5, idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI,
                                   final_tinfo, self.structure_name, None)
        cdecl = idaapi.asktext(0x10000, '#pragma pack(push, 1)\n' + cdecl, "The following new type will be created")

        if cdecl:
            structure_name = idaapi.idc_parse_decl(idaapi.cvar.idati, cdecl, idaapi.PT_TYP)[0]
            previous_ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, structure_name)

            if previous_ordinal:
                reply = QtGui.QMessageBox.question(
                    None,
                    "HexRaysPyTools",
                    "Structure already exist. Do you want to overwrite it?",
                    QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
                )
                if reply == QtGui.QMessageBox.Yes:
                    idaapi.del_numbered_type(idaapi.cvar.idati, previous_ordinal)
                    ordinal = idaapi.idc_set_local_type(previous_ordinal, cdecl, idaapi.PT_TYP)
                else:
                    return
            else:
                ordinal = idaapi.idc_set_local_type(-1, cdecl, idaapi.PT_TYP)
            if ordinal:
                print "[Info] New type {0} was added to Local Types".format(structure_name)
                tid = idaapi.import_type(idaapi.cvar.idati, -1, structure_name)
                if tid:
                    tinfo = idaapi.create_typedef(structure_name)
                    ptr_tinfo = idaapi.tinfo_t()
                    ptr_tinfo.create_ptr(tinfo)
                    for scanned_var in self.get_unique_scanned_variables(origin):
                        scanned_var.apply_type(ptr_tinfo)
                    return tinfo
            else:
                print "[ERROR] Structure {0} probably already exist".format(structure_name)
Пример #13
0
    def run(self):
        self.logger.info('Starting up')
        try:
            here = idc.here()
            self.logger.info('Using ea: 0x%08x', here)
        
            if not idc.GetMnem(here).startswith('call'):
                self.logger.info('Not running at a call instruction. Bailing out now')
                return
            if idc.GetOpType(here, 0) == idc.o_near:
                self.logger.info("Cannot (or shouldn't) run when call optype is o_near")
                return

            dlg = ApplyCalleeTypeWidget()
            oldTo = idaapi.set_script_timeout(0)
            res = dlg.exec_()
            idaapi.set_script_timeout(oldTo)

            if res == QtGui.QDialog.DialogCode.Accepted:
                self.logger.debug('Dialog accepted. Input type: %d', dlg.inputType)
            else:
                self.logger.debug('Dialog rejected')
                return

            tinfo = None
            #check user input type
            if dlg.inputType == dlg.USER_TYPE:
                decl = self.convertUserType(str(dlg.getUserText()))
                tinfo = self.getUserDeclType(decl)
            elif dlg.inputType == dlg.STANDARD_TYPE:
                tinfo = self.getBuiltinGlobalType()
            elif dlg.inputType == dlg.LOCAL_TYPE:
                tinfo = self.getLocalType()
            else:
                self.logger.info('Bad user input type')
                return
            if tinfo is None:
                self.logger.debug('Bailing due to null tinfo')
                return
            #self.logger.info('Deserialize result: %r', ret)
            #not 100% sure if i need to explicitly convert from func to funcptr - seemed
            # to pretty much work without this, but doing it just to be sure
            if not tinfo.is_funcptr():
                self.logger.debug('Converting to func pointer')
                tinfo.create_ptr(tinfo)
            typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, tinfo, '', '')
            self.logger.info('Applying tinfo: "%s"', str(typename))
            #both applying callee type & setting op type -> not sure if both are needed?
            # set op type causes change in hexrays decompilation
            # apply callee type updates ida's stack analysis
            ret = idaapi.apply_callee_tinfo(here, tinfo)
            ret = idaapi.set_op_tinfo2(here, 0, tinfo)
            self.logger.debug('set_op_tinfo2 result: %r', ret)

        except Exception, err:
            self.logger.exception("Exception caught: %s", str(err))
    def pack(self, start=0, stop=None):
        if self.collisions[start:stop].count(True):
            print "[Warning] Collisions detected"
            return

        final_tinfo = idaapi.tinfo_t()
        udt_data = idaapi.udt_type_data_t()
        origin = self.items[start].offset
        offset = origin

        for item in filter(lambda x: x.enabled,
                           self.items[start:stop]):  # Filter disabled members
            gap_size = item.offset - offset
            if gap_size:
                udt_data.push_back(
                    TemporaryStructureModel.get_padding_member(
                        offset - origin, gap_size))
            if item.is_array:
                array_size = self.calculate_array_size(
                    bisect.bisect_left(self.items, item))
                if array_size:
                    udt_data.push_back(
                        item.get_udt_member(array_size, offset=origin))
                    offset = item.offset + item.size * array_size
                    continue
            udt_data.push_back(item.get_udt_member(offset=origin))
            offset = item.offset + item.size

        final_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT)
        cdecl = idaapi.print_tinfo(
            None, 4, 5,
            idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI,
            final_tinfo, self.structure_name, None)
        cdecl = idaapi.asktext(0x10000, cdecl,
                               "The following new type will be created")

        if cdecl:
            structure_name = idaapi.idc_parse_decl(idaapi.cvar.idati, cdecl,
                                                   idaapi.PT_TYP)[0]
            ordinal = idaapi.idc_set_local_type(-1, cdecl, idaapi.PT_TYP)
            if ordinal:
                print "[Info] New type {0} was added to Local Types".format(
                    structure_name)
                tid = idaapi.import_type(idaapi.cvar.idati, -1, structure_name)
                if tid:
                    tinfo = idaapi.create_typedef(structure_name)
                    ptr_tinfo = idaapi.tinfo_t()
                    ptr_tinfo.create_ptr(tinfo)
                    for scanned_var in self.get_scanned_variables(origin):
                        scanned_var.apply_type(ptr_tinfo)
                    return tinfo
            else:
                print "[ERROR] Structure {0} probably already exist".format(
                    structure_name)
        return None
Пример #15
0
    def typeName(self):
        """
        Get the type human readable ASCII based name (in all upper case letters)
        """
        if self.type is None:
            return None

        typeName = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, self.type, '', '')
        if typeName is None or typeName == "":
            return None

        return typeName.upper()
Пример #16
0
    def typeName(self):
        """
        Get the type human readable ASCII based name (in all upper case letters)
        """
        if self.type is None:
            return None

        typeName = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, self.type, '', '')
        if typeName is None or typeName == "":
            return None

        return typeName.upper()
Пример #17
0
    def get_struc_name(self):

        x = self.target.operands['x']
        m = self.target.operands['m']

        xtype = x.type
        xtype.remove_ptr_or_array()
        typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, xtype, '', '')

        sid = idc.GetStrucIdByName(typename)
        member = idc.GetMemberName(sid, m)

        return '%s::%s' % (typename, member)
Пример #18
0
    def get_struc_name(self):

        x = self.target.operands['x']
        m = self.target.operands['m']

        xtype = x.type
        xtype.remove_ptr_or_array()
        typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, xtype, '', '')

        sid = idc.GetStrucIdByName(typename)
        member = idc.GetMemberName(sid, m)

        return '%s::%s' % (typename, member)
Пример #19
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
Пример #20
0
    def run(self):
        '''Start the plugin.'''

        if not idaapi.init_hexrays_plugin():
            print "HRDEV Error: Failed to initialise Hex-Rays plugin."
            return

        function_name = idaapi.get_func_name(idaapi.get_screen_ea())
        demangled_name = self.tools.demangle_name(function_name)

        src = idaapi.decompile(idaapi.get_screen_ea())

        file_name = '{}.cpp'.format(self.tools.to_file_name(demangled_name))
        cache_path = os.path.sep.join(
            [tempfile.gettempdir(), 'hrdev_cache', self._bin_name])

        # Create required directories if they dont exist
        tmp_dir_path = os.path.sep.join([tempfile.gettempdir(), 'hrdev_cache'])
        if not os.path.isdir(tmp_dir_path):
            os.mkdir(tmp_dir_path)

        if not os.path.isdir(cache_path):
            os.mkdir(cache_path)

        complete_path = os.path.sep.join([cache_path, file_name])
        idaapi.msg("HRDEV cache path: {}\n".format(complete_path))

        # Check if file is already in cache
        if not os.path.isfile(complete_path) or \
           self.config_main.getboolean('etc', 'disable_cache'):
            self.tools.save_file(complete_path, str(src))

        self.tools.set_file_path(complete_path)

        lvars = {}
        for v in src.lvars:
            _type = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, v.tif,
                                       '', '')
            lvars[str(v.name)] = "{} {} {}".\
                format(_type, str(v.name), str(v.cmt))

        max_title = self.config_main.getint('etc', 'max_title')
        self.gui = hrdev_plugin.include.gui.Canvas(self.config_main,
                                                   self.config_theme,
                                                   self.tools, lvars,
                                                   demangled_name[:max_title])
        self.gui.Show('HRDEV')

        self.parser = hrdev_plugin.include.syntax.Parser(self, lvars)
        self.parser.run(complete_path)
        return
Пример #21
0
    def run(self):
        '''Start the plugin.'''

        if not idaapi.init_hexrays_plugin():
            print "HRDEV Error: Failed to initialise Hex-Rays plugin."
            return

        function_name = idaapi.get_func_name(idaapi.get_screen_ea())
        demangled_name = self.tools.demangle_name(function_name)
        file_name = '{}.cpp'.format(self.tools.to_file_name(demangled_name))

        cache_path = os.path.sep.join([tempfile.gettempdir(),
                                       'hrdev_cache',
                                       self._bin_name])

        # Create require directories if they dont exist
        tmp_dir_path = os.path.sep.join([tempfile.gettempdir(), 'hrdev_cache'])
        if not os.path.isdir(tmp_dir_path):
            os.mkdir(tmp_dir_path)

        if not os.path.isdir(cache_path):
            os.mkdir(cache_path)

        complete_path = os.path.sep.join([cache_path, file_name])
        idaapi.msg("HRDEV cache path: {}\n".format(complete_path))

        src = idaapi.decompile(idaapi.get_screen_ea())

        lvars = {}
        for v in src.lvars:
            _type = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, v.tif, '', '')
            lvars[str(v.name)] = "{} {} {}".\
                format(_type, str(v.name), str(v.cmt))

        # Check if file is already in cache
        if not os.path.isfile(complete_path):
            self.tools.save_file(complete_path, str(src))

        self.tools.set_file_path(complete_path)

        max_title = self.config_main.getint('etc', 'max_title')
        self.gui = hrdev_plugin.include.gui.Canvas(self.config_main,
                                                   self.config_theme,
                                                   self.tools,
                                                   lvars,
                                                   demangled_name[:max_title])
        self.gui.Show('HRDEV')

        self.parser = hrdev_plugin.include.syntax.Parser(self)
        self.parser.run(complete_path)
        return
Пример #22
0
    def __get_enum_values(self):
        try:
            enum_name = idaapi.print_tinfo("", 0, 0, idaapi.PRTYPE_1LINE,
                                           self.type, "", "")

            enum = sark.Enum(name=enum_name)
            for member in enum.members:
                if member.value == self.rawValue:
                    self.parsedValues.append(
                        ParsedValue("{}.{}".format(enum_name,
                                                   member.name), "Enum",
                                    MAX_SCORE, hex(self.rawValue), "enum"))
                    return True
            return False
        except Exception as ex:
            self.logger.exception("Error while retrieving enum values: %s", ex)
            return False
Пример #23
0
    def getStructData(self):
        """
        Extract the struct data from tinfo_t object and populate all relevant class properties.
        @return: True if successful, otherwise False
        """

        if self.type_info.is_udt():
            if self.type_info.get_udt_details(self.udt_type_data):

                self.name = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, self.type_info, '', '')
                self.size = self.udt_type_data.size
                self.element_num = len(self.udt_type_data)
                self.is_union = self.udt_type_data.is_union

                return True

        return False
Пример #24
0
    def __get_enum_values(self):
        try:
            enum_name = idaapi.print_tinfo("", 0, 0, idaapi.PRTYPE_1LINE, self.type, "", "")

            enum = sark.Enum(name=enum_name)
            for member in enum.members:
                if member.value == self.rawValue:
                    self.parsedValues.append(
                        ParsedValue("{}.{}".format(
                            enum_name, member.name), "Enum", MAX_SCORE, hex(self.rawValue), "enum"
                        )
                    )
                    return True
            return False
        except Exception as ex:
            self.logger.exception("Error while retrieving enum values: %s", ex)
            return False
Пример #25
0
    def ParseData(self, rawData, type=None, loc=None, custom_parser=None):
        """
        Parse Data
        @param rawData: The raw data to be parsed
        @param type: The data type (If unknown should be None)
        @param loc: raw value (memory) location
        @param custom_parser: A custom parser to use.
        @return: A list of ParsedValue objects (containing the guessed\exact parsed values)
        """
        parsedValues = []

        try:
            # If custom parser was defined
            if custom_parser is not None:
                custom_parser.run(rawData, type, match_override=True)
                ret_vals = custom_parser.getParsedValues()
                parsedValues.extend(ret_vals)

                return parsedValues

            # if type is known, try to look it up in the parser_type dict
            if type is not None:
                type_name = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE,
                                               type, '', '')
                type_name = self.typeName_norm(type_name)

                if type_name in self.type_parsers:
                    for parser_plugin in self.type_parsers[type_name]:
                        parser_plugin.run(rawData, type)
                        ret_vals = parser_plugin.getParsedValues()
                        parsedValues.extend(ret_vals)

                    return parsedValues

            # Otherwise, the entire plugin list has to be iterated
            for pluginInfo in self.pManager.getAllPlugins():
                if pluginInfo.is_activated:
                    pluginInfo.plugin_object.run(rawData, type)
                    ret_vals = pluginInfo.plugin_object.getParsedValues()
                    parsedValues.extend(ret_vals)

            return parsedValues

        except Exception as ex:
            self.logger.exception("Error while parsing data: %s", ex)
Пример #26
0
    def getStructData(self):
        """
        Extract the struct data from tinfo_t object and populate all relevant class properties.
        @return: True if successful, otherwise False
        """

        if self.type_info.is_udt():
            if self.type_info.get_udt_details(self.udt_type_data):

                self.name = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE,
                                               self.type_info, '', '')
                self.size = self.udt_type_data.size
                self.element_num = len(self.udt_type_data)
                self.is_union = self.udt_type_data.is_union

                return True

        return False
Пример #27
0
    def ParseData(self, rawData, type=None, loc=None, custom_parser=None):
        """
        Parse Data
        @param rawData: The raw data to be parsed
        @param type: The data type (If unknown should be None)
        @param loc: raw value (memory) location
        @param custom_parser: A custom parser to use.
        @return: A list of ParsedValue objects (containing the guessed\exact parsed values)
        """
        parsedValues = []

        try:
            # If custom parser was defined
            if custom_parser is not None:
                custom_parser.run(rawData, type, match_override=True)
                ret_vals = custom_parser.getParsedValues()
                parsedValues.extend(ret_vals)

                return parsedValues

            # if type is known, try to look it up in the parser_type dict
            if type is not None:
                type_name = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, type, '', '')
                type_name = self.typeName_norm(type_name)

                if type_name in self.type_parsers:
                    for parser_plugin in self.type_parsers[type_name]:
                        parser_plugin.run(rawData, type)
                        ret_vals = parser_plugin.getParsedValues()
                        parsedValues.extend(ret_vals)

                    return parsedValues

            # Otherwise, the entire plugin list has to be iterated
            for pluginInfo in self.pManager.getAllPlugins():
                if pluginInfo.is_activated:
                    pluginInfo.plugin_object.run(rawData, type)
                    ret_vals = pluginInfo.plugin_object.getParsedValues()
                    parsedValues.extend(ret_vals)

            return parsedValues

        except Exception as ex:
            self.logger.exception("Error while parsing data: %s", ex)
Пример #28
0
    def ev_calc_arglocs(self, fti):
        logging.debug("##########ev_calc_arglocs")
        logging.debug("is_void() = " + str(fti.rettype.is_void()))

        # Set the location of each argument
        #    NOTE: LOCATION TYPE: https://www.hex-rays.com/products/ida/support/sdkdoc/group___a_l_o_c__.html
        #
        for i in xrange(fti.size()):
            logging.debug(
                "Arg %d: %s (of type %s, and of location: %s)" %
                (i, fti[i].name,
                 idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, fti[i].type,
                                    '', ''), fti[i].argloc.atype()))
            # Set funciton argument #i location as register number "i"
            #            fti[i].argloc.set_reg1(i)
            # Set funciton argument #i location as stack at location "i"*4
            fti[i].argloc.set_stkoff(i * 4)
        # Return value is D0
        fti.retloc.set_reg1(0)  # D0
        # Set size of stack arguments passed
        fti.stkargs = fti.size() * 4
        return 1
Пример #29
0
    def __init__(self, type):

        self.logger = logging.getLogger(__name__)

        self.name = ""
        self.size = 0
        self.element_num = 0
        self.is_union = False

        self.elements = []

        self.type_info = type
        self.udt_type_data = idaapi.udt_type_data_t()


        try:
            if self.getStructData():
                self.getElements()

        except Exception as ex:
            self.logger.exception("Error while extracting Struct data: %s",
                          idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, type, '', ''), ex)
            return False
Пример #30
0
    def __init__(self, type):

        self.logger = logging.getLogger(__name__)

        self.name = ""
        self.size = 0
        self.element_num = 0
        self.is_union = False

        self.elements = []

        self.type_info = type
        self.udt_type_data = idaapi.udt_type_data_t()

        try:
            if self.getStructData():
                self.getElements()

        except Exception as ex:
            self.logger.exception(
                "Error while extracting Struct data: %s",
                idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, type, '',
                                   ''), ex)
            return False
Пример #31
0
    def checkSupportedType(self, type):
        """
        Check if a type name string is supported
        @param type: IDA type_into_t object
        @return: True if type name is supported or otherwise False
        """
        try:
            tname = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, type, '',
                                       '')

            type_name = None
            if self.typeName_norm_cb is not None:
                type_name = self.typeName_norm_cb(tname)

            for (stype, sparams) in self.supported_types:
                if type_name == stype:
                    self.type_params = sparams
                    return True

            return False

        except Exception as ex:
            self.logger.exception(
                "Error while checking for supported type: %s", ex)
Пример #32
0
    def get_items_for_type(self):

        x = self.target.operands['x']
        m = self.target.operands['m']

        xtype = x.type
        xtype.remove_ptr_or_array()
        typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, xtype, '', '')

        addresses = []
        for ea in idautils.Functions():

            try:
                cfunc = idaapi.decompile(ea)
            except:
                print 'Decompilation of %x failed' % (ea, )
                continue

            str(cfunc)

            for citem in cfunc.treeitems:
                citem = citem.to_specific_type
                if not (type(citem) == idaapi.cexpr_t and citem.opname in ('memptr', 'memref')):
                    continue

                _x = citem.operands['x']
                _m = citem.operands['m']
                _xtype = _x.type
                _xtype.remove_ptr_or_array()
                _typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, _xtype, '', '')

                #~ print 'in', hex(cfunc.entry_ea), _typename, _m

                if not (_typename == typename and _m == m):
                    continue

                parent = citem
                while parent:
                    if type(parent.to_specific_type) == idaapi.cinsn_t:
                        break
                    parent = cfunc.body.find_parent_of(parent)

                if not parent:
                    print 'cannot find parent statement (?!)'
                    continue

                if parent.ea in addresses:
                    continue

                if parent.ea == idaapi.BADADDR:
                    print 'parent.ea is BADADDR'
                    continue

                addresses.append(parent.ea)

                self.functions.append(cfunc.entry_ea)
                self.items.append((
                        parent.ea,
                        idc.GetFunctionName(cfunc.entry_ea),
                        self.get_decompiled_line(cfunc, parent.ea)))


        return []
def type_str(the_type, name_='', extra_flags=0):
    return idaapi.print_tinfo(
        '', 0, 0, idaapi.PRTYPE_1LINE | idaapi.PRTYPE_CPP
        | idaapi.PRTYPE_PRAGMA | extra_flags, the_type, name_, '')
Пример #34
0
def print_tinfo(name, ti):
    '''str -> tinfo_t -> str'''
    return idaapi.print_tinfo('', 0, 0,
                              idaapi.PRTYPE_1LINE | idaapi.PRTYPE_SEMI, ti,
                              name, '')
Пример #35
0
 def type_name(self):
     """
     Get type name (int, char, LPCSTR etc.)
     """
     idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, self.type, '', '')
Пример #36
0
 def type_name(self):
     """
     Get type name (int, char, LPCSTR etc.)
     """
     idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, self.type, '', '')
Пример #37
0
    def get_items_for_type(self):

        x = self.target.operands['x']
        m = self.target.operands['m']

        xtype = x.type
        xtype.remove_ptr_or_array()
        typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, xtype, '',
                                      '')

        addresses = []
        for ea in idautils.Functions():

            try:
                cfunc = idaapi.decompile(ea)
            except:
                print 'Decompilation of %x failed' % (ea, )
                continue

            str(cfunc)

            for citem in cfunc.treeitems:
                citem = citem.to_specific_type
                if not (type(citem) == idaapi.cexpr_t
                        and citem.opname in ('memptr', 'memref')):
                    continue

                _x = citem.operands['x']
                _m = citem.operands['m']
                _xtype = _x.type
                _xtype.remove_ptr_or_array()
                _typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE,
                                               _xtype, '', '')

                #~ print 'in', hex(cfunc.entry_ea), _typename, _m

                if not (_typename == typename and _m == m):
                    continue

                parent = citem
                while parent:
                    if type(parent.to_specific_type) == idaapi.cinsn_t:
                        break
                    parent = cfunc.body.find_parent_of(parent)

                if not parent:
                    print 'cannot find parent statement (?!)'
                    continue

                if parent.ea in addresses:
                    continue

                if parent.ea == idaapi.BADADDR:
                    print 'parent.ea is BADADDR'
                    continue

                addresses.append(parent.ea)

                self.functions.append(cfunc.entry_ea)
                self.items.append(
                    (parent.ea, idc.GetFunctionName(cfunc.entry_ea),
                     self.get_decompiled_line(cfunc, parent.ea)))

        return []
Пример #38
0
def print_tinfo(name, ti):
    '''str -> tinfo_t -> str'''
    return idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE | idaapi.PRTYPE_SEMI, ti, name, '')
Пример #39
0
def string(ti):
    prefix = ''
    name, indent = '', 4
    cmt, cindent = '', 4
    flags = idaapi.PRTYPE_DEF | idaapi.PRTYPE_MULTI
    return idaapi.print_tinfo(prefix, indent, cindent, flags, ti, name, cmt)