mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
105 lines
3.1 KiB
Python
105 lines
3.1 KiB
Python
"""
|
|
summary: showcase (some of) the iterators available on a function
|
|
|
|
description:
|
|
This demonstrates how to use some of the iterators available on the func_t type.
|
|
|
|
This example will focus on:
|
|
|
|
* `func_t[.__iter__]`: the default iterator; iterates on instructions
|
|
* `func_t.data_items`: iterate on data items contained within a function
|
|
* `func_t.head_items`: iterate on 'heads' (i.e., addresses containing
|
|
the start of an instruction, or a data item.
|
|
* `func_t.addresses`: iterate on all addresses within function (code
|
|
and data, beginning of an item or not)
|
|
|
|
Type `help(ida_funcs.func_t)` for a full list of iterators.
|
|
|
|
In addition, one can use:
|
|
|
|
* `func_tail_iterator_t`: iterate on all the chunks (including
|
|
the main one) of the function
|
|
* `func_parent_iterator_t`: iterate on all the parent functions,
|
|
that include this chunk
|
|
|
|
keywords: funcs iterator
|
|
|
|
level: intermediate
|
|
"""
|
|
|
|
import ida_bytes
|
|
import ida_kernwin
|
|
import ida_funcs
|
|
import ida_ua
|
|
|
|
class logger_t(object):
|
|
|
|
class section_t(object):
|
|
def __init__(self, logger, header):
|
|
self.logger = logger
|
|
self.logger.log(header)
|
|
def __enter__(self):
|
|
self.logger.indent += 2
|
|
return self
|
|
def __exit__(self, tp, value, traceback):
|
|
self.logger.indent -= 2
|
|
if value:
|
|
return False # Re-raise
|
|
|
|
def __init__(self):
|
|
self.indent = 0
|
|
|
|
def log(self, *args):
|
|
print(" " * self.indent + "".join(args))
|
|
|
|
def log_ea(self, ea):
|
|
F = ida_bytes.get_flags(ea)
|
|
parts = ["0x%08x" % ea, ": "]
|
|
if ida_bytes.is_code(F):
|
|
parts.append("instruction (%s)" % ida_ua.print_insn_mnem(ea))
|
|
if ida_bytes.is_data(F):
|
|
parts.append("data")
|
|
if ida_bytes.is_tail(F):
|
|
parts.append("tail")
|
|
if ida_bytes.is_unknown(F):
|
|
parts.append("unknown")
|
|
if ida_funcs.get_func(ea) != ida_funcs.get_fchunk(ea):
|
|
parts.append(" (in function chunk)")
|
|
self.log(*parts)
|
|
|
|
def main():
|
|
# Get current ea
|
|
ea = ida_kernwin.get_screen_ea()
|
|
|
|
pfn = ida_funcs.get_func(ea)
|
|
|
|
if pfn is None:
|
|
print("No function defined at 0x%x" % ea)
|
|
return
|
|
|
|
func_name = ida_funcs.get_func_name(pfn.start_ea)
|
|
logger = logger_t()
|
|
logger.log("Function %s at 0x%x" % (func_name, ea))
|
|
|
|
with logger_t.section_t(logger, "Code items:"):
|
|
for item in pfn:
|
|
logger.log_ea(item)
|
|
|
|
with logger_t.section_t(logger, "'head' items:"):
|
|
for item in pfn.head_items():
|
|
logger.log_ea(item)
|
|
|
|
with logger_t.section_t(logger, "Addresses:"):
|
|
for item in pfn.addresses():
|
|
logger.log_ea(item)
|
|
|
|
with logger_t.section_t(logger, "Function chunks:"):
|
|
for chunk in ida_funcs.func_tail_iterator_t(pfn):
|
|
logger.log("%s chunk: 0x%08x..0x%08x" % (
|
|
"Main" if chunk.start_ea == pfn.start_ea else "Tail",
|
|
chunk.start_ea,
|
|
chunk.end_ea))
|
|
|
|
if __name__ == "__main__":
|
|
main()
|