IDA Python
常用的代码
参考#
- 示例代码在 /opt/ida-pro/python/examples
- IDAPython 官方文档 其实并没有什么用,不如直接看源码
补全#
在 .py 文件顶部加上
import sys
sys.path.append("/opt/ida-pro/python")
这里的 /opt/ida-pro/ 换成 ida 安装目录,代码补全就会自动识别了(vim+ycm可以识别)
根据 /opt/ida-pro/python/idautils.py
,以下面的代码作为头部,可以获得与 IDA 内 Python 解释器相同的环境,复制代码只需要赋值除了头以外的即可执行
# IDA default imports
# ====================================
import sys
sys.path.append("/opt/ida-pro/python")
import ida_bytes
import ida_dbg
import ida_entry
import ida_funcs
import ida_ida
import ida_idaapi
import ida_idd
import ida_idp
import ida_kernwin
import ida_loader
import ida_nalt
import ida_name
import ida_netnode
import ida_segment
import ida_strlist
import ida_typeinf
import ida_ua
import ida_xref
import idc
import types
import os
import sys
# ====================================
一些概念#
EA#
EA 是 Effective Address(有效地址)的缩写
UA#
ida_ua 是 IDA Pro 的反汇编引擎接口模块,UA 代表 Universal Assembler(通用汇编器)。它提供了底层的指令分析功能。
def analyze_instruction(ea):
# 创建指令对象
insn = ida_ua.insn_t()
# 解码指令
length = ida_ua.decode_insn(insn, ea)
if length <= 0:
return "Not a valid instruction"
# 获取指令信息
print(f"指令长度: {length}")
print(f"指令类型: {insn.itype}")
print(f"操作数数量: {insn.Op1.type != ida_ua.o_void}")
# 分析操作数
for i in range(8): # UA_MAXOP = 8
op = insn.ops[i]
if op.type == ida_ua.o_void:
break
print(f"操作数 {i}:")
print(f" 类型: {op.type}") # o_reg(寄存器), o_imm(立即数)等
print(f" 值: {op.value}")
ida_name#
名称对应地址?
信息类#
模块/类 | 函数 | 描述 |
ida_name | get_name_ea(_from, name) | 获取函数名对应的地址,如果失败,就返回 ida_idaapi.BADADDR |
ida_funcs | get_func(ea) | 获取一个 ida_funcs.func_t 对象,常用 start_ea 和 end_ea 属性 |
del_func(ea) | ||
idautils | Heads(start_ea, end_ea) | 返回一个 Generator,包含指令/数据的头 地址 |
idc | print_insn_mnem(ea) | 汇编的 mnemonic,如 call, lea |
print_operand(ea, n) | 汇编的第 n 个操作数 | |
0000021800000218000002180000021800000218000002180000021800000218000002180000021800000218000002180000021800000218000002180000021800000218 | 获取完整的汇编指令 | |
ida_ua | insn_t() | 初始化一个 ida_ua.insn_t 对象,用于之后的指令解析 |
decode_insn(out: 'insn_t', ea) -> int | 解析位于 ea 的指令,返回长度(一般只用于长度,因为其他参数都过于底层) | |
ida_ua.insn_t | Op1, Op2…, Op8 | ida_ua.op_t,即 opcode 常用属性 ida_ua::type ,详见附录I |
ops: list | 同上,只是以列表的形式 | |
ida_idp | get_reg_name(reg: int, width: 'size_t', reghi: int) | 根据寄存器号获取寄存器的名字 |
ph_get_regnames() | 当前处理器可用寄存器 | |
ida_bytes | ida_bytes.create_strlit(ea,len,ida_nalt.STRTYPE_C) | 相当于用户在地址上按 “A” |
idaapi | prev_head(ea, minea) | 获取上一条汇编(或Head) |
Patch 类#
ida_bytes.patch_byte(ea, x:int)
ida_bytes.patch_bytes(ea, buf:bytes)
ida_funcs.func_t#
- start_ea
- end_ea
附录I ida_ua.insn_t 的 Op 类型#
以下描述均可在 ida-pro/python/ida_ua.py 中找到
常量 | 值 | 描述 |
ida_ua.o_void | 0 | 空类型,意思是当前位置没有 opcode,且之后也没有了 |
ida_ua.o_reg | 1 | 寄存器,寄存器存在 op_t::reg,可以用 ida_idp.get_reg_name 获取名字 |
ida_ua.o_mem | 2 | 直接内存引用(数据),可用 op_t::addr 获取地址。[] 中的只能是数据,例如 [0x1234] |
ida_ua.o_phrase | 3 | 内存引用[基寄存器+定位寄存器]。注意框中不能有常数(除了缩放),有的话就是 o_displ |
ida_ua.o_displ | 4 | 内存引用[基寄存器+定位寄存器+偏移],可用 op_t:addr 获取偏移。 |
ida_ua.imm | 5 | 立即数,可用 op_t::value 获取值。 |
ida_ua.o_far | 6 | 远地址,可用 op_t::addr 获取 |
ida_ua.o_near | 7 | 近地址,可用 op_t::addr 获取 |
这里的 phrase 定义还是未知的,目前只能猜。比如 [rax]
是 0,[rax+rcx]
是 4,[rcx]
是 1