コード例 #1
0
 def getComment(self):
     # type: () -> str
     """
     Sometimes the comment is repeatable (created through decomp) or not (created through disass).
     Returning disass comment
     """
     cmt = idc.get_func_cmt(self.func_ea, 1)
     if not cmt: cmt = idc.get_func_cmt(self.func_ea, 0)
     return cmt
コード例 #2
0
ファイル: test_comments.py プロジェクト: pinam45/YaCo
 def yacheck_comments(self):
     eas = yaunit.load('comments')
     i = 0
     for offset in range(0, 3):
         for fn_cmt, fn_rpt, cmt, rpt, post, ant in tests:
             ea = eas[i]
             logger.debug("checking at 0x%08X : %r, %r, %r, %r, %r, %r" %
                          (ea, fn_cmt, fn_rpt, cmt, rpt, post, ant))
             i += 1
             self.assertEqual(idc.get_func_cmt(ea, False), fn_cmt)
             self.assertEqual(idc.get_func_cmt(ea, True), fn_rpt)
             self.assertEqual(idc.get_cmt(ea, False), cmt)
             self.assertEqual(idc.get_cmt(ea, True), rpt)
             self.assertEqual(self.get_extra(ea, idc.E_NEXT), post)
             self.assertEqual(self.get_extra(ea, idc.E_PREV), ant)
コード例 #3
0
    def update(self):
        global OPEN_TAG
        global CLOSE_TAG
        global TAG_SEPARATOR

        self.clear()

        for function_address in idautils.Functions():
            function_comment = idc.get_func_cmt(function_address, False)

            tag_list_start = function_comment.find(OPEN_TAG)
            if tag_list_start == -1:
                continue

            tag_list_end = function_comment.find(CLOSE_TAG, tag_list_start)
            if tag_list_end == -1:
                continue

            tag_list = function_comment[tag_list_start +
                                        len(OPEN_TAG): tag_list_end]
            if len(tag_list) == 0:
                continue

            current_function_name = idc.get_func_name(function_address)
            self._function_list[current_function_name] = tag_list.split(
                TAG_SEPARATOR)

            tag_list = tag_list.split(TAG_SEPARATOR)
            for tag_name in tag_list:
                if tag_name not in self._tag_list:
                    self._tag_list[tag_name] = []

                self._tag_list[tag_name].append(current_function_name)
コード例 #4
0
    def range_cmt_changed(self, kind, a, cmt, repeatable):
        print("range cmt changed")
        # verify it's a function comment
        cmt = idc.get_func_cmt(a.start_ea, repeatable)
        if cmt:
            self.ida_comment_changed(cmt, a.start_ea, "range")

        return 0
コード例 #5
0
 def getComment(self, repeatable=False):
     # type: () -> str
     """
     returns the comment associated with the function. This could be its repeatable comment to show in all
     disassembly, or just its docs
     """
     mode = 1 if repeatable else 0
     cmt = idc.get_func_cmt(self.func_ea, mode)
     return cmt
コード例 #6
0
ファイル: test_comments.py プロジェクト: pinam45/YaCo
    def get_func_item(self, offset):
        while True:
            ea = get_func_item(offset)
            skip = False

            def getlen(x):
                return len(x) if x else 0

            for x in [False, True]:
                skip |= getlen(idc.get_func_cmt(ea, x))
                skip |= getlen(idc.get_cmt(ea, x))
            for x in [idc.E_PREV, idc.E_NEXT]:
                skip |= getlen(self.get_extra(ea, x))
            if not skip:
                return ea
コード例 #7
0
    def rngInc(start_ea, end_ea):
        """
        Reports back the exposed (or public) symbols of the range
        The symbols are .global forwarded, and represent the symbols defined within the range
        :param start_ea: linear address of the start of the range
        :param end_ea: linear address of the end of the range, exclusive
        :return: a series of .equ's representing the public (and private) interface of the range
        """
        ea = start_ea
        pubrefs = []
        # fwdrefs = []
        while ea < end_ea:
                d = Data.Data(ea)
                if d.getName():
                    # check xrefs to the item, if any is outside the range, it's a public reference
                    isPublic = False
                    xrefsTo = d.getXRefsTo()
                    for cref in xrefsTo[0]:
                        if cref < start_ea or cref >= end_ea:
                            isPublic = True
                    for dref in xrefsTo[1]:
                        if dref < start_ea or dref >= end_ea:
                            isPublic = True
                    if isPublic:
                        pubrefs.append((d.getName(), d.ea))
                     # For debugging purposes
                    # else:
                    #     fwdrefs.append((d.getName(), d.ea))
                ea = ea + d.getSize()

        # string build includes
        inc = '/* Public Symbols */\n'
        for name, ea in pubrefs:
            d = Data.Data(ea)
            if d.isFunctionStart():
                cmt = idc.get_func_cmt(ea, repeatable=1)
                if cmt: cmt = ' // ' + cmt.replace('\n', '\n// ')
            else:
                cmt = ''
            inc += '.global %s%s\n' % (name, cmt)
        # For debugging purposes, defining forward references could be useful in include files
        # inc += "\n// Forward Reference\n"
        # for name, ea in fwdrefs:
        #     inc += ".equ %s, 0x%07X\n" % (name, ea)
        inc += "\n"
        return inc
コード例 #8
0
    def removeAllTags(self):
        global OPEN_TAG
        global CLOSE_TAG

        for function_address in idautils.Functions():
            function_comment = idc.get_func_cmt(function_address, False)

            tag_list_start = function_comment.find(OPEN_TAG)
            if tag_list_start == -1:
                continue

            tag_list_end = function_comment.find(CLOSE_TAG, tag_list_start)
            if tag_list_end == -1:
                continue

            set_func_cmt(function_address, function_comment.replace(
                function_comment[tag_list_start: tag_list_end + 1], ""), 0)
コード例 #9
0
    def _addTagToFunction(self, function_name, tag_name):
        global OPEN_TAG
        global CLOSE_TAG
        global TAG_SEPARATOR

        function_address = idc.get_name_ea_simple(function_name)
        function_comment = idc.get_func_cmt(function_address, False)

        tag_list_start = function_comment.find(OPEN_TAG)
        if tag_list_start == -1:
            idc.set_func_cmt(
                function_address,
                function_comment + OPEN_TAG + tag_name + CLOSE_TAG, False)
            return

        tag_list_end = function_comment.find(CLOSE_TAG, tag_list_start)
        if tag_list_end == -1:
            print(
                "IDA Function Tagger: Malformed tag list found at address 0x%X"
                % function_address)
            return

        tag_list = function_comment[tag_list_start:tag_list_end + 1]
        function_comment = function_comment.replace(tag_list, "")

        tag_list = tag_list[len(OPEN_TAG):len(tag_list) - len(CLOSE_TAG)]
        tag_list = tag_list.split(TAG_SEPARATOR)

        if tag_name not in tag_list:
            tag_list.append(tag_name)

        tag_list.sort()

        function_comment = function_comment + OPEN_TAG

        for tag in tag_list:
            function_comment = function_comment + tag + TAG_SEPARATOR

        function_comment = function_comment[:-1] + CLOSE_TAG
        idc.set_func_cmt(function_address, function_comment, False)
コード例 #10
0
    def rngSyncedExterns(self, start_ea, end_ea):
        """
        The same as rngExterns(), except it includes header files if they exist.
        This is based on all header files for asm files in self.gameFiles.
        when a header file is included, used symbols from the header file are shown commented out after it
        :param start_ea: start ea of the range, inclusive
        :param end_ea: end ea of the range, exclusive
        :return: a string containing all the external symbol .equs and .includes
        """

        xrefs = self.rngExterns(start_ea, end_ea, toStr=False)
        includes = {}

        # compute includes, and find the ones not declared anywhere
        undeclaredXrefs = []
        dataFileLabels = [] # those are declared in _rom.s and must not be .equ'd.
        for xref in xrefs:
            # figure out if it's in any include (within asmFile ranges)
            isDeclared = False
            for file in sorted(self.gameFiles.keys(), key=self.gameFiles.__getitem__):
                if file.endswith('.s'):
                    # if xref is within file range
                    if self.gameFiles[file][0] <= xref < self.gameFiles[file][1]:
                        if file not in includes:
                            includes[file] = (self.gameFiles[file][0], [xref])
                        else:
                            includes[file][1].append(xref)
                        # we found what file that xref belongs to now
                        isDeclared = True
                        break
                else:
                    dataFileLabels.append(self.gameFiles[file][0])

            # xref doesn't belong to any header file
            if not isDeclared and xref not in undeclaredXrefs:
                undeclaredXrefs.append(xref)

        # output includes and specific usages
        output =  '/* External Symbols */\n'
        for include, _ in sorted(includes.items(), key=lambda x:x[1][0]):
            output += '.include "%s.inc"\n' % (include[:include.rindex('.')])
            for xref in includes[include][1]:
                # Only global if all symbols are defined somewhere.
                d = Data.Data(xref)
                if d.isFunctionStart():
                    cmt = idc.get_func_cmt(xref, repeatable=1)
                    if cmt: cmt = ' // ' + cmt.replace('\n', '\n// ')
                else:
                    cmt = ''
                # TODO: while debugging/actively disassembling .set is more convenient
                output += '// .global %s%s\n' % (d.getName(), cmt)
                # output += '.set %s, 0x%07X\n' % (Data.Data(xref).getName(), Data.Data(xref).ea)
            output += '\n'

        # output remaining xrefs
        if undeclaredXrefs:
            output += '\n/* Undeclared Symbols */\n'

        for xref in undeclaredXrefs:
            # make sure the undeclared xref is not declared in _rom.s (data files)
            d = Data.Data(xref)
            name = d.getName()
            xref = d.ea
            if xref in dataFileLabels:
                output += '// .global %s\n' % (name)
            # IWRAM/EWRAM are linked as their own objects
            elif xref >= 0x2000000 and xref < 0x3008000:
                output += '// .equ %s, 0x%07X\n' % (name, xref)
            else:
                output += '.equ %s, 0x%07X\n' % (name, xref)

        return output
コード例 #11
0
ファイル: idaremote.py プロジェクト: kernelsmith/metasm
 def cmd_get_function_comment(self, a):
     return idc.get_func_cmt(int(a, 0), 0)
コード例 #12
0
ファイル: func.py プロジェクト: xcode2010/bip
 def rcomment(self):
     """
         Property which allow access to the repeatable comment.
     """
     return idc.get_func_cmt(self.ea, True)
コード例 #13
0
ファイル: func.py プロジェクト: xcode2010/bip
 def comment(self):
     """
         Property which allow access to the comment.
     """
     return idc.get_func_cmt(self.ea, False)
コード例 #14
0
    def getFormattedDisasm(self, start_ea, end_ea):
        """
        puts together the name label, comment, and disassembly, as well as proper spacing
        :params (start_ea, end_ea): file range to determine if global or not
        :return:
        """
        name = self.getName()
        disasm = ''
        # include label
        if name:
            if self.isGlobal(start_ea, end_ea):
                disasm = name + '::'
            else:
                disasm = name + ':'
            # only add a new line for code labels
            if self.isCode():
                disasm += "\n"

        # include comment
        comment = ''
        inlineComment = ''
        # include the data item's comment
        comment = self.getComment()
        if comment:
            # TODO: parsing the force out of the comment, but replacing with original
            if '<force>' in comment:
                origDisasm = idc.GetDisasm(self.ea)
                if ';' in origDisasm:
                    origDisasm = origDisasm[:origDisasm.index(';')]
                comment = comment[:comment.index(
                    '<force>')] + '<il><force> ' + origDisasm
            if '<il>' in comment:
                splitIdx = comment.index('<il>')
                inlineComment = comment[splitIdx + len('<il>'):]
                comment = comment[:splitIdx]
            if comment:
                comment = "// " + comment.replace('\n', '\n\t// ') + '\n'
                if self.isCode():
                    disasm = disasm + '\t' + comment  # label comes before comment
                else:
                    # for data, comment comes before label
                    if name:
                        disasm = disasm + '\n'
                    disasm = disasm + '\t' + comment  # label comes before comment

        # include disassembly
        if self.isCode() or not name:
            disasm += '\t' + self.getDisasm()
        else:
            if comment:
                disasm += '\t' + self.getDisasm()
            else:
                disasm += ' ' + self.getDisasm()

        # include repeatable comments for function calls in the same line
        if self.isCode() and 'BL ' in self.getOrigDisasm():
            repCmt = idc.get_func_cmt(self.getXRefsFrom()[0][0], repeatable=1)
            repCmt = ' // ' + repCmt if repCmt else ''
            disasm += repCmt
        if inlineComment:
            disasm += ' // ' + inlineComment

        # TODO: tabs or spaces?
        # disasm = self._convertTabs(disasm)
        return disasm