Ejemplo n.º 1
0
 def on_pre_update(cls, patch_type, name, address, data):
     added_comment = str(cls.comment_format % (name, address))
     if idc.RptCmt(address) is not None and added_comment in idc.RptCmt(
             address):
         comment = idc.RptCmt(address).replace("\n" + added_comment,
                                               "").replace(
                                                   added_comment, "")
         idc.MakeRptCmt(address, comment)
Ejemplo n.º 2
0
def append_comment(ea, s, repeatable=False):
    """
    add the given string as a (possibly repeating) comment to the given address.
    does not add the comment if it already exists.
    adds the comment on its own line.

    Args:
      ea (int): the address at which to add the comment.
      s (str): the comment text.
      repeatable (bool): if True, set a repeatable comment.

    Raises:
      UnicodeEncodeError: if the given string is not ascii.
    """
    # see: http://blogs.norman.com/2011/security-research/improving-ida-analysis-of-x64-exception-handling

    s = s.encode("ascii")

    if repeatable:
        string = idc.RptCmt(ea)
    else:
        string = idc.Comment(ea)

    if not string:
        string = s  # no existing comment
    else:
        if s in string:  # ignore duplicates
            return
        string = string + "\\n" + s

    if repeatable:
        idc.MakeRptCmt(ea, string)
    else:
        idc.MakeComm(ea, string)
Ejemplo n.º 3
0
def get_single_comment(ea, is_func=False):
    """IDA has repeatable and regular comments. BN only has regular comments.
    This function constructs a single comment from both repeatable and regular
    comments
    """
    regular_comment = ""
    repeatable_comment = ""

    if is_func:
        regular_comment = idc.GetFunctionCmt(ea, 0)
        repeatable_comment = idc.GetFunctionCmt(ea, 1)
    else:
        regular_comment = idc.Comment(ea)
        repeatable_comment = idc.RptCmt(ea)

    if regular_comment is None:
        return repeatable_comment
    elif repeatable_comment is None:
        return regular_comment
    elif repeatable_comment is None and regular_comment is None:
        return None
    else:
        if len(regular_comment) == 0:
            return repeatable_comment

        if len(repeatable_comment) == 0:
            return repeatable_comment

        return regular_comment + "\n" + repeatable_comment

    return None
Ejemplo n.º 4
0
    def get_patch_byte(self, ea, fpos, org_val, patched_val):
        org_byte = "%02x" % org_val
        patched_byte = "%02x" % patched_val

        if self.prev_addr is None or ea != (self.prev_addr + 1):
            name = idc.SegName(ea)
            if idc.GetFunctionName(ea) or idc.Name(ea):
                name += ": %s" % idc.GetFunctionName(ea) or idc.Name(ea)

            comment = idc.Comment(ea) or idc.RptCmt(ea) or ""

            self.patched_bytes.append({
                'name': name,
                'begin_addr': ea,
                'original': org_byte,
                'patched': patched_byte,
                'comment': comment
            })

        else:
            self.patched_bytes[-1]['original'] += org_byte
            self.patched_bytes[-1]['patched'] += patched_byte

        self.prev_addr = ea

        return 0
Ejemplo n.º 5
0
    def get_patch_byte(self, ea, fpos, org_val, patch_val):

        # Aggregate contiguous bytes (base ea + length)
        # NOTE: Looking at the last item [-1] is sufficient
        #       since we are dealing with sorted data.
        if len(self.items_data) and (ea - self.items_data[-1][0] == self.items_data[-1][2]):

            # Increment length
            self.items_data[-1][2] += 1
            self.items[-1][2] = str(self.items_data[-1][2])

            # Append patched bytes
            self.items_data[-1][3].append(patch_val)
            self.items[-1][3] = " ".join(["%02X" % x for x in self.items_data[-1][3]])

            # Append original bytes
            self.items_data[-1][4].append(org_val)
            self.items[-1][4] =  " ".join(["%02X" % x for x in self.items_data[-1][4]])


        # Add new patch byte to the list
        else:

            name = idc.SegName(ea)

            if idc.GetFunctionName(ea) or idc.Name(ea):
                name += ": %s" % idc.GetFunctionName(ea) or idc.Name(ea)


            comment = idc.Comment(ea) or idc.RptCmt(ea) or ""
            # DATA STORAGE FORMAT:      address, function / fpos, len,    patched byte(s), original byte(s), comments
            self.items.append(     ["%08X" % ea,            name, "1", "%02X" % patch_val, "%02X" % org_val, comment])
            self.items_data.append([         ea,            fpos,   1,        [patch_val],        [org_val], None]   )

        return 0
Ejemplo n.º 6
0
 def on_perform_post_operations(cls, patch_type, name, address, data):
     original = idc.RptCmt(address)
     if original is not None:
         prefix = original + "\n"
     else:
         prefix = ""
     idc.MakeRptCmt(address,
                    str(prefix + cls.comment_format % (name, address)))
Ejemplo n.º 7
0
 def target_addr_button_clicked(self):
     ea = idc.here()
     self.target_addr_field.setText(hex(ea))
     cmt = idc.RptCmt(ea)
     if cmt is not None:
         if cmt.startswith("//@assert:"):
             expr = cmt.split(":")[1].lstrip()
             self.dba_expr_field.setText(expr)
Ejemplo n.º 8
0
 def get_comments(self, _start, _end):
     comments = ''
     # parse all the instructions
     for instr in idautils.Heads(_start, _end):
         if idc.GetFlags(instr) & idc.FF_COMM:
             # is it a repeatable comment?
             tmp_comment = idc.Comment(instr)
             if tmp_comment is not None:
                 # add the current regular comment
                 comments += struct.pack(
                     '>I', len(tmp_comment)) + struct.pack(
                         ">I", instr - _start) + tmp_comment
             else:
                 # add the current repeatable comment
                 comments += struct.pack('>I', len(
                     idc.RptCmt(instr))) + struct.pack(
                         ">I", instr - _start) + idc.RptCmt(instr)
     return comments
Ejemplo n.º 9
0
 def cmt_changed(self, *args):
     """
         A comment changed somewhere
     """
     addr, rpt = args
     if rpt:
         cmt = idc.RptCmt(addr)
     else:
         cmt = idc.Comment(addr)
     if not SkelUtils.filter_coms_blacklist(cmt):
         self.skel_conn.push_comment(addr, cmt)
     return idaapi.IDB_Hooks.cmt_changed(self, *args)
Ejemplo n.º 10
0
    def execute_comment(comment):
        """
            Thread safe comment wrapper
        """
        def make_rpt():
            idc.MakeRptCmt(comment["address"],
                           comment["data"].encode('ascii', 'replace'))

        cmt = idc.Comment(comment["address"])
        if cmt != comment["data"] and idc.RptCmt(
                comment["address"]) != comment["data"]:
            g_logger.debug("[x] Adding comment %s @ 0x%x ", comment["data"],
                           comment["address"])
            return idaapi.execute_sync(make_rpt, idaapi.MFF_WRITE)
        else:
            pass
Ejemplo n.º 11
0
def AppendComment(ea, s, repeatable=False):
    # see williutils and http://blogs.norman.com/2011/security-research/improving-ida-analysis-of-x64-exception-handling
    if repeatable:
        string = idc.RptCmt(ea)
    else:
        string = idc.Comment(ea)
    if not string:
        string = s  # no existing comment
    else:
        if s in string:  # ignore duplicates
            return
        string = string + "\n" + s
    if repeatable:
        idc.MakeRptCmt(ea, string)
    else:
        idc.MakeComm(ea, string)
Ejemplo n.º 12
0
def get_comments(ea):
    comments = []
    text = idc.RptCmt(ea)
    if text and len(text) > 0:
        comments.append({
            'type':
            'repeatable',
            'comment':
            text,
            'offset':
            str(hex(ea)).rstrip("L").upper().replace("0X", "0x")
        })
    text = idc.Comment(ea)
    if text and len(text) > 0:
        comments.append({
            'type':
            'regular',
            'comment':
            text,
            'offset':
            str(hex(ea)).rstrip("L").upper().replace("0X", "0x")
        })
    text = _iter_extra_comments(ea, idaapi.E_PREV)
    if text and len(text) > 0:
        comments.append({
            'type':
            'anterior',
            'comment':
            text,
            'offset':
            str(hex(ea)).rstrip("L").upper().replace("0X", "0x")
        })
    text = _iter_extra_comments(ea, idaapi.E_NEXT)
    if text and len(text) > 0:
        comments.append({
            'type':
            'posterior',
            'comment':
            text,
            'offset':
            str(hex(ea)).rstrip("L").upper().replace("0X", "0x")
        })
    return comments
Ejemplo n.º 13
0
 def annotate_code(self, enabled):
     if not enabled:  #Annotate
         s = ":[" + self.results.get_status() + "]"
         if self.results.has_values():
             s += " vals:[" + ''.join(
                 ["%x," % x for x in self.results.values])[:-1] + "]"
         cmt = idc.RptCmt(self.results.target)
         if cmt != "":
             self.backup_comment[self.results.target] = cmt
             if cmt.startswith("//@assert"):
                 s = cmt + s
             else:
                 s = cmt + "\n" + self.results.query + s
         else:
             s = self.results.query + s
             self.backup_comment[self.results.target] = ""
         idc.MakeRptCmt(self.results.target, s.encode("utf-8", "ignore"))
     else:
         for addr, cmt in self.backup_comment.items():
             idc.MakeRptCmt(addr, cmt)
         self.backup_comment.clear()
     self.actions[self.ANNOT_CODE] = (self.annotate_code, not (enabled))
     self.result_widget.action_selector_changed(self.ANNOT_CODE)
Ejemplo n.º 14
0
def linearize_comment(ea, function_comment=False):
    regular_comment = ""
    repeatable_comment = ""

    if function_comment:
        regular_comment = idc.GetFunctionCmt(ea, 0)
        repeatable_comment = idc.GetFunctionCmt(ea, 1)
    else:
        regular_comment = idc.Comment(ea)
        repeatable_comment = idc.RptCmt(ea)

    if regular_comment is None and repeatable_comment is None:
        return None
    elif regular_comment is not None and repeatable_comment is None:
        return regular_comment
    elif repeatable_comment is not None and regular_comment is None:
        return repeatable_comment
    else:
        if len(regular_comment) == 0:
            return repeatable_comment
        if len(repeatable_comment) == 0:
            return repeatable_comment
        return regular_comment + "\n" + repeatable_comment
    return None
Ejemplo n.º 15
0
 def repeat(self):
     """Repeatable Comment"""
     return idc.RptCmt(self._ea)