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)
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)
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
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
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
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)))
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)
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
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)
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
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)
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
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)
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
def repeat(self): """Repeatable Comment""" return idc.RptCmt(self._ea)