Skip to content

Instantly share code, notes, and snippets.

@michal-kapala
Last active August 11, 2023 20:51
Show Gist options
  • Save michal-kapala/e27386392cfd54fa2506a814dc5a3e5d to your computer and use it in GitHub Desktop.
Save michal-kapala/e27386392cfd54fa2506a814dc5a3e5d to your computer and use it in GitHub Desktop.
Advanced IDAPython cheatsheet

Advanced IDAPython cheatsheet

Gotta love Hex-Rays docs, don't you?

Functions

Get return type

def get_ret_type(ea):
  tif = idaapi.tinfo_t()
  ida_nalt.get_tinfo(tif, ea)
  details = idaapi.func_type_data_t();
  tif.get_func_details(details)
  type_name = str(details.rettype)

Get calling convention

Shoutout to icecr4ck for insight on calling conventions 'enum', which is actually an incomplete list of global variables with missing values.

def get_call_conv(ea):
  """Returns the calling convention of a function."""
  tif = idaapi.tinfo_t()
  ida_nalt.get_tinfo(tif, ea)
  funcdata = idaapi.func_type_data_t()
  tif.get_func_details(funcdata)
  return translate_cc(funcdata.cc)

def translate_cc(cc):
  """Returns calling convention string from `CM_CC_*` global var enum-like values."""
  # CM_CC_INVALID = 0
  if cc == ida_typeinf.CM_CC_INVALID:
    return "invalid"
  # CM_CC_UNKNOWN = 16
  if cc == ida_typeinf.CM_CC_UNKNOWN:
    return "unknown"
  # CM_CC_VOIDARG = 32
  if cc == ida_typeinf.CM_CC_VOIDARG:
    return "(void)"
  # CM_CC_CDECL = 48
  if cc == ida_typeinf.CM_CC_CDECL:
    return "__cdecl"
  # __cdecl for library functions
  # hex-rays didnt document this
  if cc == 49:
    return "__cdecl"

  # CM_CC_ELLIPSIS = 64
  if cc == ida_typeinf.CM_CC_ELLIPSIS:
    return "__cdecl(...)"
  # CM_CC_STDCALL = 80
  if cc == ida_typeinf.CM_CC_STDCALL:
    return "__stdcall"
  # CM_CC_PASCAL = 96
  if cc == ida_typeinf.CM_CC_PASCAL:
    return "__pascal"
  # CM_CC_FASTCALL = 112
  if cc == ida_typeinf.CM_CC_FASTCALL:
    return "__fastcall"
  # CM_CC_THISCALL = 128
  if cc == ida_typeinf.CM_CC_THISCALL:
    return "__thiscall"
  # CM_CC_SPOILED = 160
  if cc == ida_typeinf.CM_CC_SPOILED:
    return "spoiled"
  # CM_CC_RESERVE3 = 192
  if cc == ida_typeinf.CM_CC_RESERVE3:
    return "__reserve3"
  # CM_CC_SPECIALE = 208
  if cc == ida_typeinf.CM_CC_SPECIALE:
    return "special(...)"
  # CM_CC_SPECIALP = 224
  if cc == ida_typeinf.CM_CC_SPECIALP:
    return "special purged"
  # CM_CC_GOLANG doesnt exist in this module
  # CM_CC_SWIFT doesnt exist in this module
  # CM_CC_MASK = CM_CC_SPECIAL = 240
  if cc == ida_typeinf.CM_CC_SPECIAL:
    return "special"
  
  # not in the docs (???)
  return "undefined"

Get number of unique referrers

def get_nb_xref_to(ea):
  """Returns the number of code references to a function."""
  xrefs_to = idautils.XrefsTo(ea)
  unique = []

  for xref in xrefs_to:
    # is_code
    # reference: https://github.com/tmr232/Sark/blob/b1bd8fbd079ca6c5a9e01150c48e7d5283b670a8/sark/code/xref.py#L49
    if xref.type & 0x10:
      func = ida_funcs.get_func(xref.frm)
      if func is not None and func.start_ea not in unique:
        unique.append(func.start_ea)

  return len(unique)

Strings

Get a UTF-16 value

def getUTF16(ea):
  return idc.get_strlit_contents(ea, -1, 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment