Idapython常用命令

前言

idapython几乎所有api都有注解,在 path/to/your/ida/python/2(3)/ 里面,这里只是做个快速索引。

搜索

​ bin_search(start_ea, end_ea, image, imask, step, flags) -> ea_t
​ Search for a set of bytes in the program

​ @param start_ea: linear address, start of range to search
​ @param end_ea: linear address, end of range to search (exclusive)
​ @param image: the set of bytes to search for
​ @param imask: a bitfield representing the mask in ‘image’ (can be None)
​ @param step: either BIN_SEARCH_FORWARD, or BIN_SEARCH_BACKWARD
​ @param flags: combination of BIN_SEARCH_* flags
​ @return: the address of a match, or ida_idaapi.BADADDR if not found

BIN_SEARCH_CASE = _ida_bytes.BIN_SEARCH_CASE
“””
case sensitive
“””

BIN_SEARCH_NOCASE = _ida_bytes.BIN_SEARCH_NOCASE
“””
case insensitive
“””

BIN_SEARCH_NOBREAK = _ida_bytes.BIN_SEARCH_NOBREAK
“””
don’t check for Ctrl-Break
“””

BIN_SEARCH_INITED = _ida_bytes.BIN_SEARCH_INITED
“””
find_byte, find_byter: any initilized value
“””

BIN_SEARCH_NOSHOW = _ida_bytes.BIN_SEARCH_NOSHOW
“””
don’t show search progress or update screen
“””

BIN_SEARCH_FORWARD = _ida_bytes.BIN_SEARCH_FORWARD
“””
search forward for bytes
“””

BIN_SEARCH_BACKWARD = _ida_bytes.BIN_SEARCH_BACKWARD
“””
search backward for bytes
“””

Enum

idaapi.add_enum

​ Add new enum type.if idx== ‘BADADDR’ then add as the last idxif
​ name==NULL then generate a unique name “enum_%d”

​ add_enum(idx, name, flag) -> enum_t
​ @param idx (C++: size_t)
​ @param name (C++: const char *)
​ @param flag (C++: flags_t)

idx - serial number of the new enum. If another enum with the same serial number exists, then all enums with serial numbers >= the specified idx get their serial numbers incremented (in other words, the new enum is put in the middle of the list of enums).
If idx >= get_enum_qty() or idx == idaapi.BADNODE then the new enum is created at the end of the list of enums.

name - name of the enum.

flag - flags for representation of numeric constants in the definition of enum.

不知道干啥的,好像没啥影响

idaapi.add_enum_member

Add member to enum type.

add_enum_member(id, name, value, bmask=(bmask_t(-1))) -> int
@param id (C++: enum_t)
@param name (C++: const char *)
@param value (C++: uval_t)
@param bmask (C++: bmask_t)
@return: 0 if ok, otherwise one of Add enum member result codes

id - 可以使用idaapi.get_enum(name)获取

bmask - 一般使用 idaapi.DEFMASK

分析

idaapi.del_func

Delete a function.

del_func(ea) -> bool
@param ea: any address in the function entry chunk (C++: ea_t)
@return: success

idaapi.add_func

Add a new function. If the function end address is ‘BADADDR’ , then
IDA will try to determine the function bounds by calling
find_func_bounds(…, ‘FIND_FUNC_DEFINE’ ).

add_func(ea1, ea2=BADADDR) -> bool
@param ea1: start address (C++: ea_t)
@param ea2: end address (C++: ea_t)
@return: success

idaapi.create_insn

Create an instruction at the specified address. This function checks
if an instruction is present at the specified address and will try to
create one if there is none. It will fail if there is a data item or
other items hindering the creation of the new instruction. This
function will also fill the ‘out’ structure.

create_insn(ea, out=None) -> int
@param ea: linear address (C++: ea_t)
@param out: the resulting instruction (C++: insn_t *)
@return: the length of the instruction or 0

idaapi.del_items

Convert item (instruction/data) to unexplored bytes. The whole item
(including the head and tail bytes) will be destroyed. It is allowed
to pass any address in the item to this function

del_items(ea, flags=0, nbytes=1, may_destroy=None) -> bool
@param ea: any address within the first item to delete (C++: ea_t)
@param flags: combination of Unexplored byte conversion flags (C++:
int)
@param nbytes: number of bytes in the range to be undefined (C++:
asize_t)
@param may_destroy: optional routine invoked before deleting a head
item. If callback returns false then item has not
to be deleted and operation fails (C++:
may_destroy_cb_t *)
@return: true on sucessful operation, otherwise false

交叉引用

idautils.CodeRefsTo

idautils.CodeRefsFrom

Get a list of code references to(from) ‘ea’

@param ea: Target address
@param flow: Follow normal code flow or not
@type flow: Boolean (0/1, False/True)

@return: list of references (may be empty list)

Example::
for ref in CodeRefsTo(get_screen_ea(), 1):
print(ref)

idautils.DataRefsTo

idautils.DataRefsFrom

Get a list of data references to(from) ‘ea’

@param ea: Target address

@return: list of references (may be empty list)

Example::
for ref in DataRefsTo(get_screen_ea()):
print(ref)

idautils.XrefsTo

idautils.XrefsFrom

Return all references to(from) address ‘ea’

@param ea: Reference address
@param flags: one of ida_xref.XREF_ALL (default), ida_xref.XREF_FAR, ida_xref.XREF_DATA

Example::
for xref in XrefsTo(here(), 0):
print(xref.type, XrefTypeName(xref.type),
‘from’, hex(xref.frm), ‘to’, hex(xref.to))

idautils.XrefsTypeName

Convert cross-reference type codes to readable names

@param typecode: cross-reference type code

汇编

idaapi.print_insn_mnem

Print instruction mnemonics.

print_insn_mnem(ea) -> str
@param ea: linear address of the instruction (C++: ea_t)
@return: success

ea位置如果在ida中是undefined的话会读不出来,它不会去decode而是直接读asm出来。

像这种image-20210616202525303

idc.GetDisasm

Get disassembly line

@param ea: linear address of instruction

@return: “” - could not decode instruction at the specified location

@note: this function may not return exactly the same mnemonics
as you see on the screen.

就是获取ea位置的asm,如果是undefined的话会读出来 db 57h 这种东西,并且会读出来 ; 后面的注释内容

像这样image-20210617153806003

idaapi.decode_insn

Analyze the specified address and fill ‘out’. This function does not
modify the database. It just tries to interpret the specified address
as an instruction and fills the ‘out’ structure.

decode_insn(out, ea) -> int
@param out: the resulting instruction (C++: insn_t *)
@param ea: linear address (C++: ea_t)
@return: the length of the (possible) instruction or 0

解析ea出的机器码,输出到 out 指向的 insn_t 中,实际使用时 out 参数传入idaapi.insn_t()返回的一个对象,之后再通过这个对象去获取对应位置指令信息

example:

1
2
3
ins = idaapi.insn_t()
idaapi.decode_insn(ins, 0x401000) # push r15
ins.get_canon_mnem() # return 'push'

idc.get_operand_type

Get type of instruction operand

@param ea: linear address of instruction
@param n: number of operand:
0 - the first operand
1 - the second operand

@return: any of o_* constants or -1 on error

o_*定义再 idc 中

o_void = ida_ua.o_void # No Operand ———-
o_reg = ida_ua.o_reg # General Register (al,ax,es,ds…) reg
o_mem = ida_ua.o_mem # Direct Memory Reference (DATA) addr
o_phrase = ida_ua.o_phrase # Memory Ref [Base Reg + Index Reg] phrase
o_displ = ida_ua.o_displ # Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr
o_imm = ida_ua.o_imm # Immediate Value value
o_far = ida_ua.o_far # Immediate Far Address (CODE) addr
o_near = ida_ua.o_near # Immediate Near Address (CODE) addr
o_idpspec0 = ida_ua.o_idpspec0 # Processor specific type
o_idpspec1 = ida_ua.o_idpspec1 # Processor specific type
o_idpspec2 = ida_ua.o_idpspec2 # Processor specific type
o_idpspec3 = ida_ua.o_idpspec3 # Processor specific type
o_idpspec4 = ida_ua.o_idpspec4 # Processor specific type
o_idpspec5 = ida_ua.o_idpspec5 # Processor specific type
# There can be more processor specific types

# x86

o_trreg = ida_ua.o_idpspec0 # trace register
o_dbreg = ida_ua.o_idpspec1 # debug register
o_crreg = ida_ua.o_idpspec2 # control register
o_fpreg = ida_ua.o_idpspec3 # floating point register
o_mmxreg = ida_ua.o_idpspec4 # mmx register
o_xmmreg = ida_ua.o_idpspec5 # xmm register

# arm

o_reglist = ida_ua.o_idpspec1 # Register list (for LDM/STM)
o_creglist = ida_ua.o_idpspec2 # Coprocessor register list (for CDP)
o_creg = ida_ua.o_idpspec3 # Coprocessor register (for LDC/STC)
o_fpreglist = ida_ua.o_idpspec4 # Floating point register list
o_text = ida_ua.o_idpspec5 # Arbitrary text stored in the operand
o_cond = (ida_ua.o_idpspec5+1) # ARM condition as an operand

# ppc

o_spr = ida_ua.o_idpspec0 # Special purpose register
o_twofpr = ida_ua.o_idpspec1 # Two FPRs
o_shmbme = ida_ua.o_idpspec2 # SH & MB & ME
o_crf = ida_ua.o_idpspec3 # crfield x.reg
o_crb = ida_ua.o_idpspec4 # crbit x.reg
o_dcr = ida_ua.o_idpspec5 # Device control register

idc.get_operand_value

Get number used in the operand

This function returns an immediate number used in the operand

@param ea: linear address of instruction
@param n: the operand number

@return: value
operand is an immediate value => immediate value
operand has a displacement => displacement
operand is a direct memory ref => memory address
operand is a register => register number
operand is a register phrase => phrase number
otherwise => -1

idc.next_head

Get next defined item (instruction or data) in the program

@param ea: linear address to start search from
@param maxea: the search will stop at the address
maxea is not included in the search range

@return: BADADDR - no (more) defined items

通常用于遍历下一条指令,对应的有prev_head

idc.print_operand

Get operand of an instruction or data

@param ea: linear address of the item
@param n: number of operand:
0 - the first operand
1 - the second operand

@return: the current text representation of operand or “”

数据

idc.get_strlit_contents

get_strlit_contents(ea, length = -1, strtype = STRTYPE_C)

Get string contents
@param ea: linear address
@param length: string length. -1 means to calculate the max string length
@param strtype: the string type (one of STRTYPE_… constants)

@return: string contents or empty string

# Character-terminated string. The termination characters
# are kept in the next bytes of string type.
STRTYPE_TERMCHR = ida_nalt.STRTYPE_TERMCHR
# C-style string.
STRTYPE_C = ida_nalt.STRTYPE_C
# Zero-terminated 16bit chars
STRTYPE_C_16 = ida_nalt.STRTYPE_C_16
# Zero-terminated 32bit chars
STRTYPE_C_32 = ida_nalt.STRTYPE_C_32
# Pascal-style, one-byte length prefix
STRTYPE_PASCAL = ida_nalt.STRTYPE_PASCAL
# Pascal-style, 16bit chars, one-byte length prefix
STRTYPE_PASCAL_16 = ida_nalt.STRTYPE_PASCAL_16
# Pascal-style, two-byte length prefix
STRTYPE_LEN2 = ida_nalt.STRTYPE_LEN2
# Pascal-style, 16bit chars, two-byte length prefix
STRTYPE_LEN2_16 = ida_nalt.STRTYPE_LEN2_16
# Pascal-style, four-byte length prefix
STRTYPE_LEN4 = ida_nalt.STRTYPE_LEN4
# Pascal-style, 16bit chars, four-byte length prefix
STRTYPE_LEN4_16 = ida_nalt.STRTYPE_LEN4_16

# alias
STRTYPE_C16 = STRTYPE_C_16

获取指定位置值

idaapi.get_byte

idaapi.get_word

idaapi.get_dword

idaapi.get_qword

Get one byte (8-bit) of the program at ‘ea’ from the database. Works
even if the debugger is active. See also ‘get_dbg_byte()’ to read the
process memory directly. This function works only for 8bit byte
processors.

get_db_byte(ea) -> uchar
@param ea (C++: ea_t)

不使用调试过程中的值。

idc.read_dbg_byte

idc.read_dbg_word

idc.read_dbg_dword

idc.read_dbg_qword

Get value of program byte using the debugger memory

@param ea: linear address
@return: The value or None on failure.

使用调试过程中的值。

获取指定位置开始的bytes

idc.get_bytes

get_bytes(ea, size, use_dbg = False)
Return the specified number of bytes of the program
@param ea: linear address
@param size: size of buffer in normal 8-bit bytes
@param use_dbg: if True, use debugger memory, otherwise just the database
@return: None on failure
otherwise a string containing the read bytes

修改指定位置的值

idaapi.patch_byte

idaapi.patch_word

idaapi.patch_dword

idaapi.patch_qword

Patch a byte of the program. The original value of the byte is saved
and can be obtained by ‘get_original_byte()’ . This function works for
wide byte processors too.

patch_byte(ea, x) -> bool
@param ea (C++: ea_t)
@param x (C++: uint64)
@retval: true - the database has been modified,
@retval: false - the debugger is running and the process’ memory has
value ‘x’ at address ‘ea’, or the debugger is not
running, and the IDB has value ‘x’ at address ‘ea
already.

修改指定位置开始的bytes

idaapi.patch_bytes

Patch the specified number of bytes of the program. Original values of
bytes are saved and are available with get_original…() functions.
See also ‘put_bytes()’ .

patch_bytes(ea, buf)
@param ea: linear address (C++: ea_t)
@param buf: buffer with new values of bytes (C++: const void *)

调试

idaapi.add_bpt

Add a new breakpoint in the debugged process. \sq{Type, Synchronous
function - available as request, Notification, none (synchronous
function)}Only one breakpoint can exist at a given address.

add_bpt(ea, size=0, type=BPT_DEFAULT) -> bool
@param ea: any address in the process memory space. Depending on the
architecture, hardware breakpoints always be setup at
random address. For example, on x86, hardware breakpoints
should be aligned depending on their size. Moreover, on the
x86 architecture, it is impossible to setup more than 4
hardware breakpoints. (C++: ea_t)
@param size: size of the breakpoint (irrelevant for software
breakpoints): As for the address, hardware breakpoints
can’t always be setup with random size. (C++: asize_t)
@param type: type of the breakpoint ( BPT_SOFT for software
breakpoint) special case BPT_DEFAULT ( BPT_SOFT |
BPT_EXEC ): try to add instruction breakpoint of the
appropriate type as follows: software bpt if supported,
hwbpt otherwise (C++: bpttype_t)

add_bpt(bpt) -> bool
bpt: bpt_t const &

BPT_WRITE = cvar.BPT_WRITE
BPT_READ = cvar.BPT_READ
BPT_RDWR = cvar.BPT_RDWR
BPT_SOFT = cvar.BPT_SOFT
BPT_EXEC = cvar.BPT_EXEC
BPT_DEFAULT = cvar.BPT_DEFAULT

idaapi.continue_process

idaapi.continue_process()

Continue the execution of the process in the debugger. \sq{Type,
Synchronous function - available as Request, Notification, none
(synchronous function)}The ‘continue_process()’ function can be called
from a notification handler to force the continuation of the process.
In this case the request queue will not be examined, IDA will simply
resume execution. Usually it makes sense to call
‘request_continue_process()’ followed by ‘run_requests()’ , so that
IDA will first start a queued request (if any) and then resume the
application.

idaapi.wait_for_next_event

Wait for the next event.This function (optionally) resumes the process
execution, and waits for a debugger event until a possible timeout
occurs.

wait_for_next_event(wfne, timeout) -> dbg_event_code_t
@param wfne: combination of Wait for debugger event flags constants
(C++: int)
@param timeout: number of seconds to wait, -1-infinity (C++: int)
@return: either an event_id_t (if > 0), or a dbg_event_code_t (if <=
0)

WFNE_ANY = _ida_dbg.WFNE_ANY
“””
return the first event (even if it doesn’t suspend the process)
“””

WFNE_SUSP = _ida_dbg.WFNE_SUSP
“””
wait until the process gets suspended
“””

WFNE_SILENT = _ida_dbg.WFNE_SILENT
“””
1: be slient, 0:display modal boxes if necessary
“””

WFNE_CONT = _ida_dbg.WFNE_CONT
“””
continue from the suspended state
“””

WFNE_NOWAIT = _ida_dbg.WFNE_NOWAIT
“””
(to be used with ‘WFNE_CONT’ )

do not wait for any event, immediately return ‘DEC_TIMEOUT’
“””

WFNE_USEC = _ida_dbg.WFNE_USEC
“””
(minimum non-zero timeout is 40000us)

timeout is specified in microseconds
“””

如果希望程序运行到下一个断点可以这样写:

1
2
# continue process,并且等待下一次suspended
idaapi.wait_for_next_event(idaapi.WFNE_SUSP | idaapi.WFNE_CONT, -1)

idc.set_bpt_cond

Set breakpoint condition

@param ea: any address in the breakpoint range
@param cnd: breakpoint condition
@param is_lowcnd: 0 - regular condition, 1 - low level condition

@return: success

可以设置断点为条件断点,并且设置condition,但是无法从这里设置condition的语言,默认是IDC

目前我还没有找到比较优雅的直接设置python条件断点的方式,只能硬改 bpt_t 中的 elang 来改

example:

1
2
3
4
5
6
# 设置python条件断点
bpt = idaapi.get_bpt(ea)
bpt.elang = "Python" # or "IDC"
bpt.condition = "print('Hello World')" # 或者再add_bpt之后使用set_bpt_cond改
idaapi.del_bpt(ea)
idaapi.add_bpt(bpt)

杂项

idaapi.set_cmt

Set an indented comment.

set_cmt(ea, comm, rptble) -> bool
@param ea: linear address (C++: ea_t)
@param comm: comment string nullptr: do nothing (return 0) “” :
delete comment (C++: const char *)
@param rptble: is repeatable? (C++: bool)
@return: success

idaapi.get_name

get_name(ea) -> qstring
@param ea (C++: ea_t)

idaapi.set_name

Set or delete name of an item at the specified address. An item can be
anything: instruction, function, data byte, word, string, structure,
etc… Include name into the list of names.

set_name(ea, name, flags=0) -> bool
@param ea: linear address. do nothing if ea is not valid (return 0).
tail bytes can’t have names. (C++: ea_t)
@param name: new name. NULL: do nothing (return 0). “” : delete
name. otherwise this is a new name. (C++: const char *)
@param flags: Set name flags . If a bit is not specified, then the
corresponding action is not performed and the name will
retain the same bits as before calling this function.
For new names, default is: non-public, non-weak, non-
auto. (C++: int)
@retval: 1 - ok, name is changed
@retval: 0 - failure, a warning is displayed

idc.get_name_ea_simple

Get linear address of a name

@param name: name of program byte

@return: address of the name
BADADDR - No such name