IDA 6.8 python / idc.py

#!/usr/bin/env python
#---------------------------------------------------------------------
# IDAPython - Python plugin for Interactive Disassembler
#
# Original IDC.IDC:
# Copyright (c) 1990-2010 Ilfak Guilfanov
#
# Python conversion:
# Copyright (c) 2004-2010 Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#
# All rights reserved.
#
# For detailed copyright information see the file COPYING in
# the root of the distribution archive.
#---------------------------------------------------------------------
# idc.py - IDC compatibility module
#---------------------------------------------------------------------
"""
IDC compatibility module

This file contains IDA built-in function declarations and internal bit
definitions.  Each byte of the program has 32-bit flags (low 8 bits keep
the byte value). These 32 bits are used in GetFlags/SetFlags functions.
You may freely examine these bits using GetFlags() but the use of the
SetFlags() function is strongly discouraged.

This file is subject to change without any notice.
Future versions of IDA may use other definitions.
"""
try:
    import idaapi
except ImportError:
    print "Could not import idaapi. Running in 'pydoc mode'."

import os
import re
import struct
import time
import types

__EA64__ = idaapi.BADADDR == 0xFFFFFFFFFFFFFFFFL
WORDMASK = 0xFFFFFFFFFFFFFFFF if __EA64__ else 0xFFFFFFFF
class DeprecatedIDCError(Exception):
    """
    Exception for deprecated function calls
    """
    pass


def _IDC_GetAttr(obj, attrmap, attroffs):
    """
    Internal function to generically get object attributes
    Do not use unless you know what you are doing
    """
    if attroffs in attrmap and hasattr(obj, attrmap[attroffs][1]):
        return getattr(obj, attrmap[attroffs][1])
    else:
        errormsg = "attribute with offset %d not found, check the offset and report the problem" % attroffs
        raise KeyError, errormsg


def _IDC_SetAttr(obj, attrmap, attroffs, value):
    """
    Internal function to generically set object attributes
    Do not use unless you know what you are doing
    """
    # check for read-only atributes
    if attroffs in attrmap:
        if attrmap[attroffs][0]:
            raise KeyError, "attribute with offset %d is read-only" % attroffs
        elif hasattr(obj, attrmap[attroffs][1]):
            return setattr(obj, attrmap[attroffs][1], value)
    errormsg = "attribute with offset %d not found, check the offset and report the problem" % attroffs
    raise KeyError, errormsg


BADADDR         = idaapi.BADADDR # Not allowed address value
BADSEL          = idaapi.BADSEL  # Not allowed selector value/number
MAXADDR         = idaapi.MAXADDR & WORDMASK
SIZE_MAX        = idaapi.SIZE_MAX
#
#      Flag bit definitions (for GetFlags())
#
MS_VAL  = idaapi.MS_VAL             # Mask for byte value
FF_IVL  = idaapi.FF_IVL             # Byte has value ?

# Do flags contain byte value? (i.e. has the byte a value?)
# if not, the byte is uninitialized.

def hasValue(F):     return ((F & FF_IVL) != 0)     # any defined value?

def byteValue(F):
    """
    Get byte value from flags
    Get value of byte provided that the byte is initialized.
    This macro works ok only for 8-bit byte machines.
    """
    return (F & MS_VAL)


def isLoaded(ea):
    """Is the byte initialized?"""
    return hasValue(GetFlags(ea))  # any defined value?

MS_CLS   = idaapi.MS_CLS   # Mask for typing
FF_CODE  = idaapi.FF_CODE  # Code ?
FF_DATA  = idaapi.FF_DATA  # Data ?
FF_TAIL  = idaapi.FF_TAIL  # Tail ?
FF_UNK   = idaapi.FF_UNK   # Unknown ?

def isCode(F):       return ((F & MS_CLS) == FF_CODE) # is code byte?
def isData(F):       return ((F & MS_CLS) == FF_DATA) # is data byte?
def isTail(F):       return ((F & MS_CLS) == FF_TAIL) # is tail byte?
def isUnknown(F):    return ((F & MS_CLS) == FF_UNK)  # is unexplored byte?
def isHead(F):       return ((F & FF_DATA) != 0)      # is start of code/data?

#
#      Common bits
#
MS_COMM  = idaapi.MS_COMM  # Mask of common bits
FF_COMM  = idaapi.FF_COMM  # Has comment?
FF_REF   = idaapi.FF_REF   # has references?
FF_LINE  = idaapi.FF_LINE  # Has next or prev cmt lines ?
FF_NAME  = idaapi.FF_NAME  # Has user-defined name ?
FF_LABL  = idaapi.FF_LABL  # Has dummy name?
FF_FLOW  = idaapi.FF_FLOW  # Exec flow from prev instruction?
FF_VAR   = idaapi.FF_VAR   # Is byte variable ?
FF_ANYNAME = FF_LABL | FF_NAME

def isFlow(F):       return ((F & FF_FLOW) != 0)
def isVar(F):        return ((F & FF_VAR ) != 0)
def isExtra(F):      return ((F & FF_LINE) != 0)
def isRef(F):        return ((F & FF_REF)  != 0)
def hasName(F):      return ((F & FF_NAME) != 0)
def hasUserName(F):  return ((F & FF_ANYNAME) == FF_NAME)

MS_0TYPE  = idaapi.MS_0TYPE  # Mask for 1st arg typing
FF_0VOID  = idaapi.FF_0VOID  # Void (unknown)?
FF_0NUMH  = idaapi.FF_0NUMH  # Hexadecimal number?
FF_0NUMD  = idaapi.FF_0NUMD  # Decimal number?
FF_0CHAR  = idaapi.FF_0CHAR  # Char ('x')?
FF_0SEG   = idaapi.FF_0SEG   # Segment?
FF_0OFF   = idaapi.FF_0OFF   # Offset?
FF_0NUMB  = idaapi.FF_0NUMB  # Binary number?
FF_0NUMO  = idaapi.FF_0NUMO  # Octal number?
FF_0ENUM  = idaapi.FF_0ENUM  # Enumeration?
FF_0FOP   = idaapi.FF_0FOP   # Forced operand?
FF_0STRO  = idaapi.FF_0STRO  # Struct offset?
FF_0STK   = idaapi.FF_0STK   # Stack variable?

MS_1TYPE  = idaapi.MS_1TYPE  # Mask for 2nd arg typing
FF_1VOID  = idaapi.FF_1VOID  # Void (unknown)?
FF_1NUMH  = idaapi.FF_1NUMH  # Hexadecimal number?
FF_1NUMD  = idaapi.FF_1NUMD  # Decimal number?
FF_1CHAR  = idaapi.FF_1CHAR  # Char ('x')?
FF_1SEG   = idaapi.FF_1SEG   # Segment?
FF_1OFF   = idaapi.FF_1OFF   # Offset?
FF_1NUMB  = idaapi.FF_1NUMB  # Binary number?
FF_1NUMO  = idaapi.FF_1NUMO  # Octal number?
FF_1ENUM  = idaapi.FF_1ENUM  # Enumeration?
FF_1FOP   = idaapi.FF_1FOP   # Forced operand?
FF_1STRO  = idaapi.FF_1STRO  # Struct offset?
FF_1STK   = idaapi.FF_1STK   # Stack variable?

# The following macros answer questions like
#   'is the 1st (or 2nd) operand of instruction or data of the given type'?
# Please note that data items use only the 1st operand type (is...0)

def isDefArg0(F):    return ((F & MS_0TYPE) != FF_0VOID)
def isDefArg1(F):    return ((F & MS_1TYPE) != FF_1VOID)
def isDec0(F):       return ((F & MS_0TYPE) == FF_0NUMD)
def isDec1(F):       return ((F & MS_1TYPE) == FF_1NUMD)
def isHex0(F):       return ((F & MS_0TYPE) == FF_0NUMH)
def isHex1(F):       return ((F & MS_1TYPE) == FF_1NUMH)
def isOct0(F):       return ((F & MS_0TYPE) == FF_0NUMO)
def isOct1(F):       return ((F & MS_1TYPE) == FF_1NUMO)
def isBin0(F):       return ((F & MS_0TYPE) == FF_0NUMB)
def isBin1(F):       return ((F & MS_1TYPE) == FF_1NUMB)
def isOff0(F):       return ((F & MS_0TYPE) == FF_0OFF)
def isOff1(F):       return ((F & MS_1TYPE) == FF_1OFF)
def isChar0(F):      return ((F & MS_0TYPE) == FF_0CHAR)
def isChar1(F):      return ((F & MS_1TYPE) == FF_1CHAR)
def isSeg0(F):       return ((F & MS_0TYPE) == FF_0SEG)
def isSeg1(F):       return ((F & MS_1TYPE) == FF_1SEG)
def isEnum0(F):      return ((F & MS_0TYPE) == FF_0ENUM)
def isEnum1(F):      return ((F & MS_1TYPE) == FF_1ENUM)
def isFop0(F):       return ((F & MS_0TYPE) == FF_0FOP)
def isFop1(F):       return ((F & MS_1TYPE) == FF_1FOP)
def isStroff0(F):    return ((F & MS_0TYPE) == FF_0STRO)
def isStroff1(F):    return ((F & MS_1TYPE) == FF_1STRO)
def isStkvar0(F):    return ((F & MS_0TYPE) == FF_0STK)
def isStkvar1(F):    return ((F & MS_1TYPE) == FF_1STK)

#
#      Bits for DATA bytes
#
DT_TYPE  = idaapi.DT_TYPE & 0xFFFFFFFF  # Mask for DATA typing

FF_BYTE      = idaapi.FF_BYTE & 0xFFFFFFFF      # byte
FF_WORD      = idaapi.FF_WORD & 0xFFFFFFFF      # word
FF_DWRD      = idaapi.FF_DWRD & 0xFFFFFFFF      # dword
FF_QWRD      = idaapi.FF_QWRD & 0xFFFFFFFF      # qword
FF_TBYT      = idaapi.FF_TBYT & 0xFFFFFFFF      # tbyte
FF_ASCI      = idaapi.FF_ASCI & 0xFFFFFFFF      # ASCII ?
FF_STRU      = idaapi.FF_STRU & 0xFFFFFFFF      # Struct ?
FF_OWRD      = idaapi.FF_OWRD & 0xFFFFFFFF      # octaword (16 bytes)
FF_FLOAT     = idaapi.FF_FLOAT & 0xFFFFFFFF     # float
FF_DOUBLE    = idaapi.FF_DOUBLE & 0xFFFFFFFF    # double
FF_PACKREAL  = idaapi.FF_PACKREAL & 0xFFFFFFFF  # packed decimal real
FF_ALIGN     = idaapi.FF_ALIGN & 0xFFFFFFFF     # alignment directive

def isByte(F):     return (isData(F) and (F & DT_TYPE) == FF_BYTE)
def isWord(F):     return (isData(F) and (F & DT_TYPE) == FF_WORD)
def isDwrd(F):     return (isData(F) and (F & DT_TYPE) == FF_DWRD)
def isQwrd(F):     return (isData(F) and (F & DT_TYPE) == FF_QWRD)
def isOwrd(F):     return (isData(F) and (F & DT_TYPE) == FF_OWRD)
def isTbyt(F):     return (isData(F) and (F & DT_TYPE) == FF_TBYT)
def isFloat(F):    return (isData(F) and (F & DT_TYPE) == FF_FLOAT)
def isDouble(F):   return (isData(F) and (F & DT_TYPE) == FF_DOUBLE)
def isPackReal(F): return (isData(F) and (F & DT_TYPE) == FF_PACKREAL)
def isASCII(F):    return (isData(F) and (F & DT_TYPE) == FF_ASCI)
def isStruct(F):   return (isData(F) and (F & DT_TYPE) == FF_STRU)
def isAlign(F):    return (isData(F) and (F & DT_TYPE) == FF_ALIGN)

#
#      Bits for CODE bytes
#
MS_CODE  = idaapi.MS_CODE & 0xFFFFFFFF
FF_FUNC  = idaapi.FF_FUNC & 0xFFFFFFFF  # function start?
FF_IMMD  = idaapi.FF_IMMD & 0xFFFFFFFF  # Has Immediate value ?
FF_JUMP  = idaapi.FF_JUMP & 0xFFFFFFFF  # Has jump table

#
#      Loader flags
#
NEF_SEGS   = idaapi.NEF_SEGS   # Create segments
NEF_RSCS   = idaapi.NEF_RSCS   # Load resources
NEF_NAME   = idaapi.NEF_NAME   # Rename entries
NEF_MAN    = idaapi.NEF_MAN    # Manual load
NEF_FILL   = idaapi.NEF_FILL   # Fill segment gaps
NEF_IMPS   = idaapi.NEF_IMPS   # Create imports section
NEF_FIRST  = idaapi.NEF_FIRST  # This is the first file loaded
NEF_CODE   = idaapi.NEF_CODE   # for load_binary_file:
NEF_RELOAD = idaapi.NEF_RELOAD # reload the file at the same place:
NEF_FLAT   = idaapi.NEF_FLAT   # Autocreated FLAT group (PE)

#         List of built-in functions
#         --------------------------
#
# The following conventions are used in this list:
#   'ea' is a linear address
#   'success' is 0 if a function failed, 1 otherwise
#   'void' means that function returns no meaningful value (always 0)
#
#  All function parameter conversions are made automatically.
#
# ----------------------------------------------------------------------------
#                       M I S C E L L A N E O U S
# ----------------------------------------------------------------------------
def IsString(var): raise NotImplementedError, "this function is not needed in Python"
def IsLong(var):   raise NotImplementedError, "this function is not needed in Python"
def IsFloat(var):  raise NotImplementedError, "this function is not needed in Python"
def IsFunc(var):   raise NotImplementedError, "this function is not needed in Python"
def IsPvoid(var):  raise NotImplementedError, "this function is not needed in Python"
def IsInt64(var):  raise NotImplementedError, "this function is not needed in Python"

def MK_FP(seg, off):
    """
    Return value of expression: ((seg<<4) + off)
    """
    return (seg << 4) + off

def form(format, *args):
    raise DeprecatedIDCError, "form() is deprecated. Use python string operations instead."

def substr(s, x1, x2):
    raise DeprecatedIDCError, "substr() is deprecated. Use python string operations instead."

def strstr(s1, s2):
    raise DeprecatedIDCError, "strstr() is deprecated. Use python string operations instead."

def strlen(s):
    raise DeprecatedIDCError, "strlen() is deprecated. Use python string operations instead."

def xtol(s):
    raise DeprecatedIDCError, "xtol() is deprecated. Use python long() instead."


def atoa(ea):
    """
    Convert address value to a string
    Return address in the form 'seg000:1234'
    (the same as in line prefixes)

    @param ea: address to format
    """
    segname = SegName(ea)

    if segname == "":
        segname = "0"

    return "%s:%X" % (segname, ea)


def ltoa(n, radix):
    raise DeprecatedIDCError, "ltoa() is deprecated. Use python string operations instead."

def atol(s):
    raise DeprecatedIDCError, "atol() is deprecated. Use python long() instead."


def rotate_left(value, count, nbits, offset):
    """
    Rotate a value to the left (or right)

    @param value: value to rotate
    @param count: number of times to rotate. negative counter means
                  rotate to the right
    @param nbits: number of bits to rotate
    @param offset: offset of the first bit to rotate

    @return: the value with the specified field rotated
             all other bits are not modified
    """
    assert offset >= 0, "offset must be >= 0"
    assert nbits > 0, "nbits must be > 0"

    mask = 2**(offset+nbits) - 2**offset
    tmp = value & mask

    if count > 0:
        for x in xrange(count):
            if (tmp >> (offset+nbits-1)) & 1:
                tmp = (tmp << 1) | (1 << offset)
            else:
                tmp = (tmp << 1)
    else:
        for x in xrange(-count):
            if (tmp >> offset) & 1:
                tmp = (tmp >> 1) | (1 << (offset+nbits-1))
            else:
                tmp = (tmp >> 1)

    value = (value-(value&mask)) | (tmp & mask)

    return value


def rotate_dword(x, count): return rotate_left(x, count, 32, 0)
def rotate_word(x, count):  return rotate_left(x, count, 16, 0)
def rotate_byte(x, count):  return rotate_left(x, count, 8, 0)


# AddHotkey return codes
IDCHK_OK        =  0   # ok
IDCHK_ARG       = -1   # bad argument(s)
IDCHK_KEY       = -2   # bad hotkey name
IDCHK_MAX       = -3   # too many IDC hotkeys

def AddHotkey(hotkey, idcfunc):
    """
    Add hotkey for IDC function

    @param hotkey: hotkey name ('a', "Alt-A", etc)
    @param idcfunc: IDC function name

    @return: None
    """
    return idaapi.add_idc_hotkey(hotkey, idcfunc)


def DelHotkey(hotkey):
    """
    Delete IDC function hotkey

    @param hotkey: hotkey code to delete
    """
    return idaapi.del_idc_hotkey(hotkey)


def Jump(ea):
    """
    Move cursor to the specifed linear address

    @param ea: linear address
    """
    return idaapi.jumpto(ea)


def Wait():
    """
    Process all entries in the autoanalysis queue
    Wait for the end of autoanalysis

    @note:    This function will suspend execution of the calling script
            till the autoanalysis queue is empty.
    """
    return idaapi.autoWait()


def CompileEx(input, isfile):
    """
    Compile an IDC script

    The input should not contain functions that are
    currently executing - otherwise the behaviour of the replaced
    functions is undefined.

    @param input: if isfile != 0, then this is the name of file to compile
                  otherwise it holds the text to compile
    @param isfile: specify if 'input' holds a filename or the expression itself

    @return: 0 - ok, otherwise it returns an error message
    """
    if isfile:
        res = idaapi.Compile(input)
    else:
        res = idaapi.CompileLine(input)

    if res:
        return res
    else:
        return 0


def Eval(expr):
    """
    Evaluate an IDC expression

    @param expr: an expression

    @return: the expression value. If there are problems, the returned value will be "IDC_FAILURE: xxx"
             where xxx is the error description

    @note: Python implementation evaluates IDC only, while IDC can call other registered languages
    """
    rv = idaapi.idc_value_t()

    err = idaapi.calc_idc_expr(BADADDR, expr, rv)
    if err:
        return "IDC_FAILURE: "+err
    else:
        if rv.vtype == '\x01':   # VT_STR
            return rv.str
        elif rv.vtype == '\x02': # long
            return rv.num
        elif rv.vtype == '\x07': # VT_STR2
            return rv.c_str()
        else:
            raise NotImplementedError, "Eval() supports only expressions returning strings or longs"


def EVAL_FAILURE(code):
    """
    Check the result of Eval() for evaluation failures

    @param code: result of Eval()

    @return: True if there was an evaluation error
    """
    return type(code) == types.StringType and code.startswith("IDC_FAILURE: ")


def SaveBase(idbname, flags=0):
    """
    Save current database to the specified idb file

    @param idbname: name of the idb file. if empty, the current idb
                    file will be used.
    @param flags: combination of idaapi.DBFL_... bits or 0
    """
    if len(idbname) == 0:
        idbname = GetIdbPath()
    saveflags = idaapi.cvar.database_flags
    mask = idaapi.DBFL_KILL | idaapi.DBFL_COMP | idaapi.DBFL_BAK
    idaapi.cvar.database_flags &= ~mask
    idaapi.cvar.database_flags |= flags & mask
    res = idaapi.save_database(idbname, 0)
    idaapi.cvar.database_flags = saveflags
    return res

DBFL_BAK = idaapi.DBFL_BAK # for compatiblity with older versions, eventually delete this

def ValidateNames():
    """
    check consistency of IDB name records
    @return: number of inconsistent name records
    """
    return idaapi.validate_idb_names()

def Exit(code):
    """
    Stop execution of IDC program, close the database and exit to OS

    @param code: code to exit with.

    @return: -
    """
    idaapi.qexit(code)


def Exec(command):
    """
    Execute an OS command.

    @param command: command line to execute

    @return: error code from OS

    @note:
    IDA will wait for the started program to finish.
    In order to start the command in parallel, use OS methods.
    For example, you may start another program in parallel using
    "start" command.
    """
    return os.system(command)


def Sleep(milliseconds):
    """
    Sleep the specified number of milliseconds
    This function suspends IDA for the specified amount of time

    @param milliseconds: time to sleep
    """
    time.sleep(float(milliseconds)/1000)


def RunPlugin(name, arg):
    """
    Load and run a plugin

    @param name: The plugin name is a short plugin name without an extension
    @param arg: integer argument

    @return: 0 if could not load the plugin, 1 if ok
    """
    return idaapi.load_and_run_plugin(name, arg)


def ApplySig(name):
    """
    Load (plan to apply) a FLIRT signature file

    @param name:  signature name without path and extension

    @return: 0 if could not load the signature file, !=0 otherwise
    """
    return idaapi.plan_to_apply_idasgn(name)


#----------------------------------------------------------------------------
#      C H A N G E   P R O G R A M   R E P R E S E N T A T I O N
#----------------------------------------------------------------------------


def DeleteAll():
    """
    Delete all segments, instructions, comments, i.e. everything
    except values of bytes.
    """
    ea = idaapi.cvar.inf.minEA

    # Brute-force nuke all info from all the heads
    while ea != BADADDR and ea <= idaapi.cvar.inf.maxEA:
        idaapi.del_local_name(ea)
        idaapi.del_global_name(ea)
        func = idaapi.get_func(ea)
        if func:
            idaapi.del_func_cmt(func, False)
            idaapi.del_func_cmt(func, True)
            idaapi.del_func(ea)
        idaapi.del_hidden_area(ea)
        seg = idaapi.getseg(ea)
        if seg:
            idaapi.del_segment_cmt(seg, False)
            idaapi.del_segment_cmt(seg, True)
            idaapi.del_segm(ea, idaapi.SEGDEL_KEEP | idaapi.SEGDEL_SILENT)

        ea = idaapi.next_head(ea, idaapi.cvar.inf.maxEA)


def MakeCode(ea):
    """
    Create an instruction at the specified address

    @param ea: linear address

    @return: 0 - can not create an instruction (no such opcode, the instruction
    would overlap with existing items, etc) otherwise returns length of the
    instruction in bytes
    """
    return idaapi.create_insn(ea)


def AnalyzeArea(sEA, eEA):
    """
    Perform full analysis of the area

    @param sEA: starting linear address
    @param eEA: ending linear address (excluded)

    @return: 1-ok, 0-Ctrl-Break was pressed.
    """
    return idaapi.analyze_area(sEA, eEA)


def MakeNameEx(ea, name, flags):
    """
    Rename an address

    @param ea: linear address
    @param name: new name of address. If name == "", then delete old name
    @param flags: combination of SN_... constants

    @return: 1-ok, 0-failure
    """
    return idaapi.set_name(ea, name, flags)

SN_CHECK      = idaapi.SN_CHECK    # Fail if the name contains invalid
                                   # characters
                                   # If this bit is clear, all invalid chars
                                   # (those !is_ident_char()) will be replaced
                                   # by SubstChar (usually '_')
                                   # List of valid characters is defined in
                                   # ida.cfg
SN_NOCHECK    = idaapi.SN_NOCHECK  # Replace invalid chars with SubstChar
SN_PUBLIC     = idaapi.SN_PUBLIC   # if set, make name public
SN_NON_PUBLIC = idaapi.SN_NON_PUBLIC # if set, make name non-public
SN_WEAK       = idaapi.SN_WEAK     # if set, make name weak
SN_NON_WEAK   = idaapi.SN_NON_WEAK # if set, make name non-weak
SN_AUTO       = idaapi.SN_AUTO     # if set, make name autogenerated
SN_NON_AUTO   = idaapi.SN_NON_AUTO # if set, make name non-autogenerated
SN_NOLIST     = idaapi.SN_NOLIST   # if set, exclude name from the list
                                   # if not set, then include the name into
                                   # the list (however, if other bits are set,
                                   # the name might be immediately excluded
                                   # from the list)
SN_NOWARN     = idaapi.SN_NOWARN   # don't display a warning if failed
SN_LOCAL      = idaapi.SN_LOCAL    # create local name. a function should exist.
                                   # local names can't be public or weak.
                                   # also they are not included into the list
                                   # of names they can't have dummy prefixes

def MakeComm(ea, comment):
    """
    Set an indented regular comment of an item

    @param ea: linear address
    @param comment: comment string

    @return: None
    """
    return idaapi.set_cmt(ea, comment, 0)


def MakeRptCmt(ea, comment):
    """
    Set an indented repeatable comment of an item

    @param ea: linear address
    @param comment: comment string

    @return: None
    """
    return idaapi.set_cmt(ea, comment, 1)


def MakeArray(ea, nitems):
    """
    Create an array.

    @param ea: linear address
    @param nitems: size of array in items

    @note: This function will create an array of the items with the same type as
    the type of the item at 'ea'. If the byte at 'ea' is undefined, then
    this function will create an array of bytes.
    """
    flags = idaapi.getFlags(ea)

    if idaapi.isCode(flags) or idaapi.isTail(flags) or idaapi.isAlign(flags):
        return False

    if idaapi.isUnknown(flags):
        flags = idaapi.FF_BYTE

    if idaapi.isStruct(flags):
        ti = idaapi.opinfo_t()
        assert idaapi.get_opinfo(ea, 0, flags, ti), "get_opinfo() failed"
        itemsize = idaapi.get_data_elsize(ea, flags, ti)
        tid = ti.tid
    else:
        itemsize = idaapi.get_item_size(ea)
        tid = BADADDR

    return idaapi.do_data_ex(ea, flags, itemsize*nitems, tid)


def MakeStr(ea, endea):
    """
    Create a string.

    This function creates a string (the string type is determined by the
    value of GetLongPrm(INF_STRTYPE))

    @param ea: linear address
    @param endea: ending address of the string (excluded)
        if endea == BADADDR, then length of string will be calculated
        by the kernel

    @return: 1-ok, 0-failure

    @note: The type of an existing string is returned by GetStringType()
    """
    return idaapi.make_ascii_string(ea, 0 if endea == BADADDR else endea - ea, GetLongPrm(INF_STRTYPE))


def MakeData(ea, flags, size, tid):
    """
    Create a data item at the specified address

    @param ea: linear address
    @param flags: FF_BYTE..FF_PACKREAL
    @param size: size of item in bytes
    @param tid: for FF_STRU the structure id

    @return: 1-ok, 0-failure
    """
    return idaapi.do_data_ex(ea, flags, size, tid)


def MakeByte(ea):
    """
    Convert the current item to a byte

    @param ea: linear address

    @return: 1-ok, 0-failure
    """
    return idaapi.doByte(ea, 1)


def MakeWord(ea):
    """
    Convert the current item to a word (2 bytes)

    @param ea: linear address

    @return: 1-ok, 0-failure
    """
    return idaapi.doWord(ea, 2)


def MakeDword(ea):
    """
    Convert the current item to a double word (4 bytes)

    @param ea: linear address

    @return: 1-ok, 0-failure
    """
    return idaapi.doDwrd(ea, 4)


def MakeQword(ea):
    """
    Convert the current item to a quadro word (8 bytes)

    @param ea: linear address

    @return: 1-ok, 0-failure
    """
    return idaapi.doQwrd(ea, 8)


def MakeOword(ea):
    """
    Convert the current item to an octa word (16 bytes/128 bits)

    @param ea: linear address

    @return: 1-ok, 0-failure
    """
    return idaapi.doOwrd(ea, 16)


def MakeYword(ea):
    """
    Convert the current item to a ymm word (32 bytes/256 bits)

    @param ea: linear address

    @return: 1-ok, 0-failure
    """
    return idaapi.doYwrd(ea, 32)


def MakeFloat(ea):
    """
    Convert the current item to a floating point (4 bytes)

    @param ea: linear address

    @return: 1-ok, 0-failure
    """
    return idaapi.doFloat(ea, 4)


def MakeDouble(ea):
    """
    Convert the current item to a double floating point (8 bytes)

    @param ea: linear address

    @return: 1-ok, 0-failure
    """
    return idaapi.doDouble(ea, 8)


def MakePackReal(ea):
    """
    Convert the current item to a packed real (10 or 12 bytes)

    @param ea: linear address

    @return: 1-ok, 0-failure
    """
    return idaapi.doPackReal(ea, idaapi.ph_get_tbyte_size())


def MakeTbyte(ea):
    """
    Convert the current item to a tbyte (10 or 12 bytes)

    @param ea: linear address

    @return: 1-ok, 0-failure
    """
    return idaapi.doTbyt(ea, idaapi.ph_get_tbyte_size())


def MakeStructEx(ea, size, strname):
    """
    Convert the current item to a structure instance

    @param ea: linear address
    @param size: structure size in bytes. -1 means that the size
        will be calculated automatically
    @param strname: name of a structure type

    @return: 1-ok, 0-failure
    """
    strid = idaapi.get_struc_id(strname)

    if size == -1:
        size = idaapi.get_struc_size(strid)

    return idaapi.doStruct(ea, size, strid)


def MakeCustomDataEx(ea, size, dtid, fid):
    """
    Convert the item at address to custom data.

    @param ea: linear address.
    @param size: custom data size in bytes.
    @param dtid: data type ID.
    @param fid: data format ID.

    @return: 1-ok, 0-failure
    """
    return idaapi.doCustomData(ea, size, dtid, fid)



def MakeAlign(ea, count, align):
    """
    Convert the current item to an alignment directive

    @param ea: linear address
    @param count: number of bytes to convert
    @param align: 0 or 1..32
              if it is 0, the correct alignment will be calculated
              by the kernel

    @return: 1-ok, 0-failure
    """
    return idaapi.doAlign(ea, count, align)


def MakeLocal(start, end, location, name):
    """
    Create a local variable

    @param start: start of address range for the local variable
    @param end: end of address range for the local variable
    @param location: the variable location in the "[bp+xx]" form where xx is
                     a number. The location can also be specified as a
                     register name.
    @param name: name of the local variable

    @return: 1-ok, 0-failure

    @note: For the stack variables the end address is ignored.
           If there is no function at 'start' then this function.
           will fail.
    """
    func = idaapi.get_func(start)

    if not func:
        return 0

    # Find out if location is in the [bp+xx] form
    r = re.compile("\[([a-z]+)([-+][0-9a-fx]+)", re.IGNORECASE)
    m = r.match(location)

    if m:
        # Location in the form of [bp+xx]
        register = idaapi.str2reg(m.group(1))
        offset = int(m.group(2), 0)
        frame = idaapi.get_frame(func)

        if register == -1 or not frame:
            return 0

        offset += func.frsize
        member = idaapi.get_member(frame, offset)

        if member:
            # Member already exists, rename it
            if idaapi.set_member_name(frame, offset, name):
                return 1
            else:
                return 0
        else:
            # No member at the offset, create a new one
            if idaapi.add_struc_member(frame,
                                       name,
                                       offset,
                                       idaapi.byteflag(),
                                       None, 1) == 0:
                return 1
            else:
                return 0
    else:
        # Location as simple register name
        return idaapi.add_regvar(func, start, end, location, name, None)


def MakeUnkn(ea, flags):
    """
    Convert the current item to an explored item

    @param ea: linear address
    @param flags: combination of DOUNK_* constants

    @return: None
    """
    return idaapi.do_unknown(ea, flags)


def MakeUnknown(ea, size, flags):
    """
    Convert the current item to an explored item

    @param ea: linear address
    @param size: size of the range to undefine (for MakeUnknown)
    @param flags: combination of DOUNK_* constants

    @return: None
    """
    return idaapi.do_unknown_range(ea, size, flags)


DOUNK_SIMPLE   = idaapi.DOUNK_SIMPLE   # simply undefine the specified item
DOUNK_EXPAND   = idaapi.DOUNK_EXPAND   # propogate undefined items, for example
                                       # if removing an instruction removes all
                                       # references to the next instruction, then
                                       # plan to convert to unexplored the next
                                       # instruction too.
DOUNK_DELNAMES = idaapi.DOUNK_DELNAMES # delete any names at the specified address(es)


def SetArrayFormat(ea, flags, litems, align):
    """
    Set array representation format

    @param ea: linear address
    @param flags: combination of AP_... constants or 0
    @param litems: number of items per line. 0 means auto
    @param align: element alignment
                  - -1: do not align
                  - 0:  automatic alignment
                  - other values: element width

    @return: 1-ok, 0-failure
    """
    return Eval("SetArrayFormat(0x%X, 0x%X, %d, %d)"%(ea, flags, litems, align))

AP_ALLOWDUPS    = 0x00000001L     # use 'dup' construct
AP_SIGNED       = 0x00000002L     # treats numbers as signed
AP_INDEX        = 0x00000004L     # display array element indexes as comments
AP_ARRAY        = 0x00000008L     # reserved (this flag is not stored in database)
AP_IDXBASEMASK  = 0x000000F0L     # mask for number base of the indexes
AP_IDXDEC       = 0x00000000L     # display indexes in decimal
AP_IDXHEX       = 0x00000010L     # display indexes in hex
AP_IDXOCT       = 0x00000020L     # display indexes in octal
AP_IDXBIN       = 0x00000030L     # display indexes in binary

def OpBinary(ea, n):
    """
    Convert an operand of the item (instruction or data) to a binary number

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands

    @return: 1-ok, 0-failure

    @note: the data items use only the type of the first operand
    """
    return idaapi.op_bin(ea, n)


def OpOctal(ea, n):
    """
    Convert an operand of the item (instruction or data) to an octal number

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    """
    return idaapi.op_oct(ea, n)


def OpDecimal(ea, n):
    """
    Convert an operand of the item (instruction or data) to a decimal number

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    """
    return idaapi.op_dec(ea, n)


def OpHex(ea, n):
    """
    Convert an operand of the item (instruction or data) to a hexadecimal number

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    """
    return idaapi.op_hex(ea, n)


def OpChr(ea, n):
    """
    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    """
    return idaapi.op_chr(ea, n)


def OpOff(ea, n, base):
    """
    Convert operand to an offset
    (for the explanations of 'ea' and 'n' please see OpBinary())

    Example:
    ========

        seg000:2000 dw      1234h

        and there is a segment at paragraph 0x1000 and there is a data item
        within the segment at 0x1234:

        seg000:1234 MyString        db 'Hello, world!',0

        Then you need to specify a linear address of the segment base to
        create a proper offset:

        OpOff(["seg000",0x2000],0,0x10000);

        and you will have:

        seg000:2000 dw      offset MyString

    Motorola 680x0 processor have a concept of "outer offsets".
    If you want to create an outer offset, you need to combine number
    of the operand with the following bit:

    Please note that the outer offsets are meaningful only for
    Motorola 680x0.

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    @param base: base of the offset as a linear address
        If base == BADADDR then the current operand becomes non-offset
    """
    return idaapi.set_offset(ea, n, base)


OPND_OUTER = idaapi.OPND_OUTER # outer offset base


def OpOffEx(ea, n, reftype, target, base, tdelta):
    """
    Convert operand to a complex offset expression
    This is a more powerful version of OpOff() function.
    It allows to explicitly specify the reference type (off8,off16, etc)
    and the expression target with a possible target delta.
    The complex expressions are represented by IDA in the following form:

    target + tdelta - base

    If the target is not present, then it will be calculated using

    target = operand_value - tdelta + base

    The target must be present for LOW.. and HIGH.. reference types

    @param ea: linear address of the instruction/data
    @param n: number of operand to convert (the same as in OpOff)
    @param reftype: one of REF_... constants
    @param target: an explicitly specified expression target. if you don't
              want to specify it, use -1. Please note that LOW... and
              HIGH... reference type requre the target.
    @param base: the offset base (a linear address)
    @param tdelta: a displacement from the target which will be displayed
              in the expression.

    @return: success (boolean)
    """
    return idaapi.op_offset(ea, n, reftype, target, base, tdelta)


REF_OFF8    = idaapi.REF_OFF8    # 8bit full offset
REF_OFF16   = idaapi.REF_OFF16   # 16bit full offset
REF_OFF32   = idaapi.REF_OFF32   # 32bit full offset
REF_LOW8    = idaapi.REF_LOW8    # low 8bits of 16bit offset
REF_LOW16   = idaapi.REF_LOW16   # low 16bits of 32bit offset
REF_HIGH8   = idaapi.REF_HIGH8   # high 8bits of 16bit offset
REF_HIGH16  = idaapi.REF_HIGH16  # high 16bits of 32bit offset
REF_VHIGH   = idaapi.REF_VHIGH   # high ph.high_fixup_bits of 32bit offset (processor dependent)
REF_VLOW    = idaapi.REF_VLOW    # low  (32-ph.high_fixup_bits) of 32bit offset (processor dependent)
REF_OFF64   = idaapi.REF_OFF64   # 64bit full offset
REFINFO_RVA     = 0x10 # based reference (rva)
REFINFO_PASTEND = 0x20 # reference past an item it may point to an nonexistitng
                       # do not destroy alignment dirs
REFINFO_NOBASE  = 0x80 # offset base is a number
                       # that base have be any value
                       # nb: base xrefs are created only if base
                       # points to the middle of a segment
REFINFO_SUBTRACT = 0x0100 # the reference value is subtracted from
                          # the base value instead of (as usual)
                          # being added to it
REFINFO_SIGNEDOP = 0x0200 # the operand value is sign-extended (only
                          # supported for REF_OFF8/16/32/64)

def OpSeg(ea, n):
    """
    Convert operand to a segment expression

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    """
    return idaapi.op_seg(ea, n)


def OpNumber(ea, n):
    """
    Convert operand to a number (with default number base, radix)

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    """
    return idaapi.op_num(ea, n)


def OpFloat(ea, n):
    """
    Convert operand to a floating-point number

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands

    @return: 1-ok, 0-failure
    """
    return idaapi.op_flt(ea, n)


def OpAlt(ea, n, opstr):
    """
    Specify operand represenation manually.

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    @param opstr: a string represenation of the operand

    @note: IDA will not check the specified operand, it will simply display
    it instead of the orginal representation of the operand.
    """
    return idaapi.set_forced_operand(ea, n, opstr)


def OpSign(ea, n):
    """
    Change sign of the operand

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    """
    return idaapi.toggle_sign(ea, n)


def OpNot(ea, n):
    """
    Toggle the bitwise not operator for the operand

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    """
    idaapi.toggle_bnot(ea, n)
    return True


def OpEnumEx(ea, n, enumid, serial):
    """
    Convert operand to a symbolic constant

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    @param enumid: id of enumeration type
    @param serial: serial number of the constant in the enumeration
             The serial numbers are used if there are more than
             one symbolic constant with the same value in the
             enumeration. In this case the first defined constant
             get the serial number 0, then second 1, etc.
             There could be 256 symbolic constants with the same
             value in the enumeration.
    """
    return idaapi.op_enum(ea, n, enumid, serial)


def OpStroffEx(ea, n, strid, delta):
    """
    Convert operand to an offset in a structure

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    @param strid: id of a structure type
    @param delta: struct offset delta. usually 0. denotes the difference
                    between the structure base and the pointer into the structure.

    """
    path = idaapi.tid_array(1)
    path[0] = strid
    return idaapi.op_stroff(ea, n, path.cast(), 1, delta)


def OpStkvar(ea, n):
    """
    Convert operand to a stack variable

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    """
    return idaapi.op_stkvar(ea, n)


def OpHigh(ea, n, target):
    """
    Convert operand to a high offset
    High offset is the upper 16bits of an offset.
    This type is used by TMS320C6 processors (and probably by other
    RISC processors too)

    @param ea: linear address
    @param n: number of operand
        - 0 - the first operand
        - 1 - the second, third and all other operands
        - -1 - all operands
    @param target: the full value (all 32bits) of the offset
    """
    return idaapi.op_offset(ea, n, idaapi.REF_HIGH16, target)


def MakeVar(ea):
    """
    Mark the location as "variable"

    @param ea: address to mark

    @return: None

    @note: All that IDA does is to mark the location as "variable".
    Nothing else, no additional analysis is performed.
    This function may disappear in the future.
    """
    idaapi.doVar(ea, 1)


def ExtLinA(ea, n, line):
    """
    Specify an additional line to display before the generated ones.

    @param ea: linear address
    @param n: number of anterior additional line (0..MAX_ITEM_LINES)
    @param line: the line to display

    @return: None

    @note: IDA displays additional lines from number 0 up to the first unexisting
    additional line. So, if you specify additional line #150 and there is no
    additional line #149, your line will not be displayed.  MAX_ITEM_LINES is
    defined in IDA.CFG
    """
    idaapi.update_extra_cmt(ea, idaapi.E_PREV + n, line)
    idaapi.doExtra(ea)


def ExtLinB(ea, n, line):
    """
    Specify an additional line to display after the generated ones.

    @param ea: linear address
    @param n: number of posterior additional line (0..MAX_ITEM_LINES)
    @param line: the line to display

    @return: None

    @note: IDA displays additional lines from number 0 up to the first
    unexisting additional line. So, if you specify additional line #150
    and there is no additional line #149, your line will not be displayed.
    MAX_ITEM_LINES is defined in IDA.CFG
    """
    idaapi.update_extra_cmt(ea, idaapi.E_NEXT + n, line)
    idaapi.doExtra(ea)


def DelExtLnA(ea, n):
    """
    Delete an additional anterior line

    @param ea: linear address
    @param n: number of anterior additional line (0..500)

    @return: None
    """
    idaapi.del_extra_cmt(ea, idaapi.E_PREV + n)


def DelExtLnB(ea, n):
    """
    Delete an additional posterior line

    @param ea: linear address
    @param n: number of posterior additional line (0..500)

    @return: None
    """
    idaapi.del_extra_cmt(ea, idaapi.E_NEXT + n)


def SetManualInsn(ea, insn):
    """
    Specify instruction represenation manually.

    @param ea: linear address
    @param insn: a string represenation of the operand

    @note: IDA will not check the specified instruction, it will simply
    display it instead of the orginal representation.
    """
    return idaapi.set_manual_insn(ea, insn)


def GetManualInsn(ea):
    """
    Get manual representation of instruction

    @param ea: linear address

    @note: This function returns value set by SetManualInsn earlier.
    """
    return idaapi.get_manual_insn(ea)


def PatchDbgByte(ea,value):
    """
    Change a byte in the debugged process memory only

    @param ea: address
    @param value: new value of the byte

    @return: 1 if successful, 0 if not
    """
    return idaapi.put_dbg_byte(ea, value)


def PatchByte(ea, value):
    """
    Change value of a program byte
    If debugger was active then the debugged process memory will be patched too

    @param ea: linear address
    @param value: new value of the byte

    @return: 1 if the database has been modified,
             0 if either the debugger is running and the process' memory
               has value 'value' at address 'ea',
               or the debugger is not running, and the IDB
               has value 'value' at address 'ea already.
    """
    return idaapi.patch_byte(ea, value)


def PatchWord(ea, value):
    """
    Change value of a program word (2 bytes)

    @param ea: linear address
    @param value: new value of the word

    @return: 1 if the database has been modified,
             0 if either the debugger is running and the process' memory
               has value 'value' at address 'ea',
               or the debugger is not running, and the IDB
               has value 'value' at address 'ea already.
    """
    return idaapi.patch_word(ea, value)


def PatchDword(ea, value):
    """
    Change value of a double word

    @param ea: linear address
    @param value: new value of the double word

    @return: 1 if the database has been modified,
             0 if either the debugger is running and the process' memory
               has value 'value' at address 'ea',
               or the debugger is not running, and the IDB
               has value 'value' at address 'ea already.
    """
    return idaapi.patch_long(ea, value)


def PatchQword(ea, value):
    """
    Change value of a quad word

    @param ea: linear address
    @param value: new value of the quad word

    @return: 1 if the database has been modified,
             0 if either the debugger is running and the process' memory
               has value 'value' at address 'ea',
               or the debugger is not running, and the IDB
               has value 'value' at address 'ea already.
    """
    return idaapi.patch_qword(ea, value)


def SetFlags(ea, flags):
    """
    Set new value of flags
    This function should not used be used directly if possible.
    It changes properties of a program byte and if misused, may lead to
    very-very strange results.

    @param ea: adress
    @param flags: new flags value
    """
    return idaapi.setFlags(ea, flags)

def SetRegEx(ea, reg, value, tag):
    """
    Set value of a segment register.

    @param ea: linear address
    @param reg: name of a register, like "cs", "ds", "es", etc.
    @param value: new value of the segment register.
    @param tag: of SR_... constants

    @note: IDA keeps tracks of all the points where segment register change their
           values. This function allows you to specify the correct value of a segment
           register if IDA is not able to find the corrent value.

           See also SetReg() compatibility macro.
    """
    reg = idaapi.str2reg(reg);
    if reg >= 0:
        return idaapi.splitSRarea1(ea, reg, value, tag)
    else:
        return False

SR_inherit      = 1 # value is inherited from the previous area
SR_user         = 2 # value is specified by the user
SR_auto         = 3 # value is determined by IDA
SR_autostart    = 4 # as SR_auto for segment starting address


def AutoMark2(start, end, queuetype):
    """
    Plan to perform an action in the future.
    This function will put your request to a special autoanalysis queue.
    Later IDA will retrieve the request from the queue and process
    it. There are several autoanalysis queue types. IDA will process all
    queries from the first queue and then switch to the second queue, etc.
    """
    return idaapi.auto_mark_range(start, end, queuetype)


def AutoUnmark(start, end, queuetype):
    """
    Remove range of addresses from a queue.
    """
    return idaapi.autoUnmark(start, end, queuetype)


def AutoMark(ea,qtype):
    """
    Plan to analyze an address
    """
    return AutoMark2(ea,ea+1,qtype)

AU_UNK   = idaapi.AU_UNK   # make unknown
AU_CODE  = idaapi.AU_CODE  # convert to instruction
AU_PROC  = idaapi.AU_PROC  # make function
AU_USED  = idaapi.AU_USED  # reanalyze
AU_LIBF  = idaapi.AU_LIBF  # apply a flirt signature (the current signature!)
AU_FINAL = idaapi.AU_FINAL # coagulate unexplored items


#----------------------------------------------------------------------------
#               P R O D U C E   O U T P U T   F I L E S
#----------------------------------------------------------------------------

def GenerateFile(filetype, path, ea1, ea2, flags):
    """
    Generate an output file

    @param filetype:  type of output file. One of OFILE_... symbols. See below.
    @param path:  the output file path (will be overwritten!)
    @param ea1:   start address. For some file types this argument is ignored
    @param ea2:   end address. For some file types this argument is ignored
    @param flags: bit combination of GENFLG_...

    @returns: number of the generated lines.
                -1 if an error occured
                OFILE_EXE: 0-can't generate exe file, 1-ok
    """
    f = idaapi.fopenWT(path)

    if f:
        retval = idaapi.gen_file(filetype, f, ea1, ea2, flags)
        idaapi.eclose(f)
        return retval
    else:
        return -1


# output file types:
OFILE_MAP  = idaapi.OFILE_MAP
OFILE_EXE  = idaapi.OFILE_EXE
OFILE_IDC  = idaapi.OFILE_IDC
OFILE_LST  = idaapi.OFILE_LST
OFILE_ASM  = idaapi.OFILE_ASM
OFILE_DIF  = idaapi.OFILE_DIF

# output control flags:
GENFLG_MAPSEG  = idaapi.GENFLG_MAPSEG  # map: generate map of segments
GENFLG_MAPNAME = idaapi.GENFLG_MAPNAME # map: include dummy names
GENFLG_MAPDMNG = idaapi.GENFLG_MAPDMNG # map: demangle names
GENFLG_MAPLOC  = idaapi.GENFLG_MAPLOC  # map: include local names
GENFLG_IDCTYPE = idaapi.GENFLG_IDCTYPE # idc: gen only information about types
GENFLG_ASMTYPE = idaapi.GENFLG_ASMTYPE # asm&lst: gen information about types too
GENFLG_GENHTML = idaapi.GENFLG_GENHTML # asm&lst: generate html (gui version only)
GENFLG_ASMINC  = idaapi.GENFLG_ASMINC  # asm&lst: gen information only about types

def GenFuncGdl(outfile, title, ea1, ea2, flags):
    """
    Generate a flow chart GDL file

    @param outfile: output file name. GDL extension will be used
    @param title: graph title
    @param ea1: beginning of the area to flow chart
    @param ea2: end of the area to flow chart.
    @param flags: combination of CHART_... constants

    @note: If ea2 == BADADDR then ea1 is treated as an address within a function.
           That function will be flow charted.
    """
    return idaapi.gen_flow_graph(outfile, title, None, ea1, ea2, flags)


CHART_PRINT_NAMES = 0x1000 # print labels for each block?
CHART_GEN_GDL     = 0x4000 # generate .gdl file (file extension is forced to .gdl)
CHART_WINGRAPH    = 0x8000 # call wingraph32 to display the graph
CHART_NOLIBFUNCS  = 0x0400 # don't include library functions in the graph


def
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值