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)
python类MakeRptCmt()的实例源码
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 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 label_and_fix_branch_islands(dsc_file, adrfind, jmp_to_code):
""" labels, comments and fixes code flow on branch islands """
jmpaddrs = sorted(set(jmp_to_code.keys()))
dsc_file.seek(0)
header = dsc_header(dsc_file)
dsc_file.seek(header.images_offset)
i = 0
jmpaddrslen = len(jmpaddrs)
for addr in jmpaddrs:
print "status: 0x%X %d/%d" % (addr, i, jmpaddrslen)
res = adrfind.find(addr)
if not res:
print "[!] coudln't find addr for addr:", addr
dylib_path, dsc_offset, macho_offset = res
exportname = adrfind.get_export_name_for_addr(addr)
if _IN_IDA:
eas = jmp_to_code[addr]
for ea in eas:
idc.MakeRptCmt(ea, "%s'%s" % (dylib_path, exportname))
if "branch_islands" in idc.SegName(ea):
make_name(ea, exportname)
# patch them to "RET" so they would return
memcpy(ea, "\xC0\x03\x5F\xD6")
make_islands_xrefs_force_bl_call(ea)
else:
print "[+] \\\\ %s" % exportname
i += 1
def annotate_code(self, enabled):
for ret_data in self.results:
addr = ret_data.addr
if not enabled: # Set the comment
status_s = ret_data.get_status()
labels_s = ''.join(["[%s]" % x for x in ret_data.get_labels()])
comment = "Status:%s %s" % (status_s, labels_s)
if ret_data.is_tampering():
comment += ' Ret:%s' % str(["%x" % x for x in ret_data.returnsites])
idc.MakeRptCmt(addr, comment)
else: # Remove the comment
idc.MakeRptCmt(addr, "")
self.actions[self.ANNOT_CODE] = (self.annotate_code, not enabled)
self.result_widget.action_selector_changed(self.ANNOT_CODE)
def annotate_code(self, enabled):
for addr, infos in self.results.items():
if not enabled:
status = to_status_name(infos.status)
idc.MakeRptCmt(addr, status)
else:
idc.MakeRptCmt(addr, "")
self.actions[self.ANNOT_CODE] = (self.annotate_code, not enabled)
self.result_widget.action_selector_changed(self.ANNOT_CODE)
def map_shared_bridges(dsc_file, adrfind):
""" finds branch islands in a given dyld_shared_cache file,
maps them to IDA's db and extract its addresses """
dsc_file.seek(0, 2)
filesize = dsc_file.tell()
dsc_file.seek(0)
ACCESS_READ = 1
a = mmap.mmap(dsc_file.fileno(), length=filesize, access=ACCESS_READ)
reexp = re.compile("\xcf\xfa\xed\xfe.{340,360}dyld_shared_cache_branch_islands")
print "[+] scanning dsc for BRANCH ISLANDS"
# this list will hold all our branch_islands segments
branch_islands_segments = []
jmp_to_code = collections.defaultdict(list)
for ma in reexp.finditer(a):
print "[+] WRITING BRANCH ISLAND: 0x%08X" % (ma.start())
fif = FileInFile(dsc_file, ma.start())
m = MachO_patched(fif)
if _IN_IDA:
for seg in m.segments:
for sec in seg.sections:
idc.AddSegEx(sec.addr,
sec.addr + sec.size, 0, 0,
idaapi.saRelPara, idaapi.scPub,
idc.ADDSEG_FILLGAP)
name = "branch_islands_%X%s%s" % (ma.start(), seg.segname, sec.sectname)
idc.RenameSeg(sec.addr, name)
idc.SetSegClass(sec.addr, "CODE")
idc.SetSegAddressing(sec.addr, 2)
dsc_file.seek(sec.offset)
memcpy(sec.addr, dsc_file.read(sec.size))
branch_islands_segments.append(sec.addr)
# make code
codeea = sec.addr
print "Going through the code!"
while codeea < (sec.addr + sec.size):
res = idc.MakeCode(codeea)
if not res:
print "[!] EA:0x%X ERR while making code" % codeea
codeea += 4
continue
d = idc.GetDisasm(codeea)
# if it's a "B 0x4dd13550"
if d.startswith("B "):
addr = d.split()[1]
if addr.startswith("0x"):
branchaddr = int(addr, 16)
jmp_to_code[branchaddr].append(codeea)
# idc.MakeRptCmt(codeea, "0x%X was taken!" % branchaddr)
codeea = idc.FindUnexplored(codeea, idc.SEARCH_DOWN)
label_and_fix_branch_islands(dsc_file, adrfind, jmp_to_code)