IDAPython for IDA 7.7

This commit is contained in:
Arnaud Diederen
2022-01-17 11:28:09 +01:00
parent 839d93ac96
commit 3ce5b7f06d
167 changed files with 206524 additions and 134608 deletions
+25 -32
View File
@@ -35,6 +35,8 @@ import types
import os
import sys
# TO_REFACTOR_ON_PY2_REMOVAL
# this internal function can be dropped
def refs(ea, funcfirst, funcnext):
"""
Generic reference collector - INTERNAL USE ONLY.
@@ -60,6 +62,13 @@ def CodeRefsTo(ea, flow):
for ref in CodeRefsTo(get_screen_ea(), 1):
print(ref)
"""
# TO_REFACTOR_ON_PY2_REMOVAL
# we can use the new generators
# xref = ida_xref.xrefblk_t()
# if flow == 1:
# yield from xref.crefs_to(ea)
# else:
# yield from xref.fcrefs_to(ea)
if flow == 1:
return refs(ea, ida_xref.get_first_cref_to, ida_xref.get_next_cref_to)
else:
@@ -81,6 +90,7 @@ def CodeRefsFrom(ea, flow):
for ref in CodeRefsFrom(get_screen_ea(), 1):
print(ref)
"""
# TO_REFACTOR_ON_PY2_REMOVAL
if flow == 1:
return refs(ea, ida_xref.get_first_cref_from, ida_xref.get_next_cref_from)
else:
@@ -100,6 +110,7 @@ def DataRefsTo(ea):
for ref in DataRefsTo(get_screen_ea()):
print(ref)
"""
# TO_REFACTOR_ON_PY2_REMOVAL
return refs(ea, ida_xref.get_first_dref_to, ida_xref.get_next_dref_to)
@@ -116,6 +127,7 @@ def DataRefsFrom(ea):
for ref in DataRefsFrom(get_screen_ea()):
print(ref)
"""
# TO_REFACTOR_ON_PY2_REMOVAL
return refs(ea, ida_xref.get_first_dref_from, ida_xref.get_next_dref_from)
@@ -144,16 +156,6 @@ def XrefTypeName(typecode):
assert typecode in _ref_types, "unknown reference type %d" % typecode
return _ref_types[typecode]
def _copy_xref(xref):
""" Make a private copy of the xref class to preserve its contents """
class _xref(object):
pass
xr = _xref()
for attr in [ 'frm', 'to', 'iscode', 'type', 'user' ]:
setattr(xr, attr, getattr(xref, attr))
return xr
def XrefsFrom(ea, flags=0):
"""
@@ -168,10 +170,7 @@ def XrefsFrom(ea, flags=0):
'from', hex(xref.frm), 'to', hex(xref.to))
"""
xref = ida_xref.xrefblk_t()
if xref.first_from(ea, flags):
yield _copy_xref(xref)
while xref.next_from():
yield _copy_xref(xref)
return xref.refs_from(ea, flags)
def XrefsTo(ea, flags=0):
@@ -187,10 +186,7 @@ def XrefsTo(ea, flags=0):
'from', hex(xref.frm), 'to', hex(xref.to))
"""
xref = ida_xref.xrefblk_t()
if xref.first_to(ea, flags):
yield _copy_xref(xref)
while xref.next_to():
yield _copy_xref(xref)
return xref.refs_to(ea, flags)
def Threads():
@@ -253,18 +249,16 @@ def Functions(start=None, end=None):
def Chunks(start):
"""
Get a list of function chunks
See also ida_funcs.func_tail_iterator_t
@param start: address of the function
@return: list of funcion chunks (tuples of the form (start_ea, end_ea))
@return: list of function chunks (tuples of the form (start_ea, end_ea))
belonging to the function
"""
func_iter = ida_funcs.func_tail_iterator_t( ida_funcs.get_func( start ) )
status = func_iter.main()
while status:
chunk = func_iter.chunk()
for chunk in func_iter:
yield (chunk.start_ea, chunk.end_ea)
status = next(func_iter)
def Modules():
@@ -319,19 +313,13 @@ def Entries():
def FuncItems(start):
"""
Get a list of function items (instruction or data items inside function boundaries)
See also ida_funcs.func_item_iterator_t
@param start: address of the function
@return: ea of each item in the function
"""
func = ida_funcs.get_func(start)
if not func:
return
fii = ida_funcs.func_item_iterator_t()
ok = fii.set(func)
while ok:
yield fii.current()
ok = fii.next_code()
return ida_funcs.func_item_iterator_t(ida_funcs.get_func(start))
def Structs():
@@ -691,7 +679,12 @@ class _procregs(object):
class _cpu(object):
"Simple wrapper around get_reg_value/set_reg_value"
def __getattr__(self, name):
return idc.get_reg_value(name)
try:
return idc.get_reg_value(name)
except Exception as ex:
raise AttributeError("_cpu: \"{}\" is not a register;"
" inner exception: [{}] {}"
.format(name, type(ex).__name__, ex))
def __setattr__(self, name, value):
return idc.set_reg_value(value, name)
+14 -98
View File
@@ -70,7 +70,7 @@ import types
import sys
__EA64__ = ida_idaapi.BADADDR == 0xFFFFFFFFFFFFFFFF
WORDMASK = 0xFFFFFFFFFFFFFFFF if __EA64__ else 0xFFFFFFFF
WORDMASK = 0xFFFFFFFFFFFFFFFF if __EA64__ else 0xFFFFFFFF # just there for bw-compat purposes; please don't use
class DeprecatedIDCError(Exception):
"""
Exception for deprecated function calls
@@ -115,8 +115,13 @@ def _IDC_SetAttr(obj, attrmap, attroffs, value):
BADADDR = ida_idaapi.BADADDR # Not allowed address value
BADSEL = ida_idaapi.BADSEL # Not allowed selector value/number
MAXADDR = ida_ida.MAXADDR & WORDMASK
SIZE_MAX = _ida_idaapi.SIZE_MAX
ida_ida.__set_module_dynattrs(
__name__,
{
"MAXADDR" : (lambda: ida_ida.inf_get_privrange_start_ea(), None),
})
#
# Flag bit definitions (for get_full_flags())
#
@@ -1748,15 +1753,13 @@ SEARCH_NOBRK = ida_search.SEARCH_NOBRK # don't test ctrl-break
SEARCH_NOSHOW = ida_search.SEARCH_NOSHOW # don't display the search progress
def find_text(ea, flag, y, x, searchstr, from_bc695=False):
if not from_bc695:
__warn_once_deprecated_proto_confusion("find_text", "ida_search.find_text")
def find_text(ea, flag, y, x, searchstr):
__warn_once_deprecated_proto_confusion("find_text", "ida_search.find_text")
return ida_search.find_text(ea, y, x, searchstr, flag)
def find_binary(ea, flag, searchstr, radix=16, from_bc695=False):
if not from_bc695:
__warn_once_deprecated_proto_confusion("find_binary", "ida_search.find_binary")
def find_binary(ea, flag, searchstr, radix=16):
__warn_once_deprecated_proto_confusion("find_binary", "ida_search.find_binary")
endea = flag & 1 and ida_ida.cvar.inf.max_ea or ida_ida.cvar.inf.min_ea
return ida_search.find_binary(ea, endea, searchstr, radix, flag)
@@ -1918,7 +1921,8 @@ INF_LISTNAMES = 39 # uchar; What names should be included in the li
# DISASSEMBLY LISTING DETAILS
INF_INDENT = 40 # char; Indention for instructions
INF_COMMENT = 41 # char; Indention for comments
INF_CMT_INDENT = 41 # char; Indention for comments
INF_COMMENT = 41 # for compatibility
INF_MARGIN = 42 # ushort; max length of data lines
INF_LENXREF = 43 # ushort; max length of line with xrefs
INF_OUTFLAGS = 44 # uint32; output flags
@@ -1997,7 +2001,7 @@ _INF_attrs_accessors = {
INF_CC_SIZE_LL : (ida_ida.inf_get_cc_size_ll, ida_ida.inf_set_cc_size_ll),
INF_CC_SIZE_S : (ida_ida.inf_get_cc_size_s, ida_ida.inf_set_cc_size_s),
INF_CMTFLAG : (ida_ida.inf_get_cmtflg, ida_ida.inf_set_cmtflg),
INF_COMMENT : (ida_ida.inf_get_comment, ida_ida.inf_set_comment),
INF_CMT_INDENT : (ida_ida.inf_get_cmt_indent, ida_ida.inf_set_cmt_indent),
INF_DATABASE_CHANGE_COUNT : (ida_ida.inf_get_database_change_count, ida_ida.inf_set_database_change_count),
INF_DATATYPES : (ida_ida.inf_get_datatypes, ida_ida.inf_set_datatypes),
INF_DEMNAMES : (ida_ida.inf_get_demnames, ida_ida.inf_set_demnames),
@@ -5928,94 +5932,6 @@ def set_flag(off, bit, value):
v = v & ~bit
set_inf_attr(off, v)
#--------------------------------------------------------------------------
# Compatibility macros (auto-generated part. Comes first so
# that any re-definition below will override auto-generated part)
if sys.modules["__main__"].IDAPYTHON_COMPAT_695_API:
# see header.i.in
bc695redef = ida_idaapi.bc695redef
# although many things have changed in the 'inf' structure,
# let's still try and do the best we can here even though
# some INF_* accessor enumerators don't exist anymore
GetCharPrm=get_inf_attr
GetLongPrm=get_inf_attr
GetShortPrm=get_inf_attr
SetCharPrm=set_inf_attr
SetLongPrm=set_inf_attr
SetShortPrm=set_inf_attr
#--------------------------------------------------------------------------
# Compatibility macros (non-auto-generated part)
def CompileEx(inp, isfile): return compile_idc_file(inp) if isfile else compile_idc_text(inp)
def WriteMap(filepath):
return gen_file(OFILE_MAP, filepath, 0, BADADDR, GENFLG_MAPSEG|GENFLG_MAPNAME)
def WriteTxt(filepath, ea1, ea2):
return gen_file(OFILE_ASM, filepath, ea1, ea2, 0)
def WriteExe(filepath):
return gen_file(OFILE_EXE, filepath, 0, BADADDR, 0)
UTP_STRUCT = ida_typeinf.UTP_STRUCT
UTP_ENUM = ida_typeinf.UTP_ENUM
def begin_type_updating(utp):
"""
Begin type updating. Use this function if you
plan to call AddEnumConst or similar type modification functions
many times or from inside a loop
@param utp: one of UTP_xxxx consts
@return: None
"""
return ida_typeinf.begin_type_updating(utp)
def end_type_updating(utp):
"""
End type updating. Refreshes the type system
at the end of type modification operations
@param utp: one of ida_typeinf.UTP_xxxx consts
@return: None
"""
return ida_typeinf.end_type_updating(utp)
from idc_bc695 import *
SendDbgCommand=send_dbg_command
def MakeFunction(start, end=ida_idaapi.BADADDR):
return ida_funcs.add_func(start, end)
ApplyType = apply_type
GetManyBytes = get_bytes
GetString = get_strlit_contents
ClearTraceFile = clear_trace
def FindBinary(ea, flag, searchstr, radix=16):
return find_binary(ea, flag, searchstr, radix, from_bc695=True)
def FindText(ea, flag, y, x, text):
return find_text(ea, flag, y, x, text, from_bc695=True)
NextHead = next_head
ParseTypes = parse_decls
PrevHead = prev_head
ProcessUiAction = process_ui_action
SaveBase = save_database
Eval = eval_idc
def MakeStr(ea, endea):
return create_strlit(ea, endea)
def GetProcessorName():
return ida_ida.cvar.inf.procname
def SegStart(ea): return get_segm_start(ea)
def SegEnd(ea): return get_segm_end(ea)
def SetSegmentType(ea, type): return set_segm_type(ea, type)
# Convenience functions:
def here(): return get_screen_ea()
def is_mapped(ea): return (prev_addr(ea+1)==ea)
+8 -2
View File
@@ -129,11 +129,17 @@ if os.getcwd() in sys.path:
if not IDAPYTHON_REMOVE_CWD_SYS_PATH:
sys.path.append(os.getcwd())
# Additional $IDAUSR-derived paths
if IDAPYTHON_IDAUSR_SYSPATH:
idausr_python_list = ida_diskio.get_ida_subdirs("python")
for idausr_python in idausr_python_list:
one = os.path.join(idausr_python, str(sys.version_info.major))
if one not in sys.path:
sys.path.append(one)
if IDAPYTHON_COMPAT_AUTOIMPORT_MODULES:
# Import all the required modules
from idaapi import get_user_idadir, cvar, Appcall, Form
if IDAPYTHON_COMPAT_695_API:
from idaapi import Choose2
from idc import *
from idautils import *
import idaapi