⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idc.py

📁 The sources of IDAPython, a plugin for IDA for using python for scripting in IDA, instead of IDC.
💻 PY
📖 第 1 页 / 共 5 页
字号:
#!/usr/bin/env python
#------------------------------------------------------------
# IDAPython - Python plugin for Interactive Disassembler Pro
#
# Original IDC.IDC:
# Copyright (c) 1990-2008 Ilfak Guilfanov
#
# Python conversion:
# Copyright (c) 2004-2008 Gergely Erdelyi <dyce@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, struct, re

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]):
        return getattr(obj, attrmap[attroffs])
    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
    """
    if attroffs in attrmap and hasattr(obj, attrmap[attroffs]):
        return setattr(obj, attrmap[attroffs], value)
    else:
        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

#
#      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?

# 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.

def byteValue(F):    return (F & MS_VAL)    # quick replacement for Byte()

# Is the byte initialized?

def isLoaded(ea):    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  # Mask for DATA typing

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

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

#
#      Bits for CODE bytes
#
MS_CODE  = idaapi.MS_CODE  
FF_FUNC  = idaapi.FF_FUNC  # function start?
FF_IMMD  = idaapi.FF_IMMD  # Has Immediate value ?
FF_JUMP  = idaapi.FF_JUMP  # 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_TIGHT  = idaapi.NEF_TIGHT  # Don't align segments (OMF)
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   # Autocreate 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 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 x: 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): rotate_left(x, count, 32, 0)
def rotate_word(x, count): rotate_left(x, count, 16, 0)
def rotate_byte(x, count): 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 

    @note: GUI version doesn't support hotkeys

    @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 Compile(filename):
    """
    Compile an IDC file.

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

    @param filename: name of file to compile

    @return: 0 - ok, otherwise it returns an error message
    """
    res = idaapi.Compile(filename)

    if res:
        return res
    else:
        return 0


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 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)


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -