IdaPython手册

全网的IdaPython完整手册好少,做个记录

声明

这篇文章是根据《The Beginner’s Guide to IDAPython》翻译的,如果侵权,请联系作者删除

因为本人英文水平有限,如果有理解错的地方,欢迎来联系我邮箱 xkittener@gmail.com

操作数

idc.get_operand_type(ea,n)

获取操作数类型

ea:当前地址,n:参数(指第几个操作数)

返回值:

  • 如果没有操作数,返回0,如retn
  • 如果为寄存器,返回1
  • 如果为内存引用,返回2,如ds:dword_A152B8
  • 如果为变址或/和基址寄存器,返回3
  • 如果为基址寄存器+立即数,返回4
  • 如果为立即数,返回5
  • 如果为远地址,返回6
  • 如果为近地址,返回7

idc.op_plain_offset(ea, n, base)

将操作数变为偏移

ea:当前地址,n:参数,base:当前基地址

Ida基本块

基本块是一个没有分支的代码序列,由单个入口点和单个出口点组成。

idaapi.FlowChart(f=None, bounds=None, flags=0)

f参数需要func_t类,用idaapi.get_func(ea)获得该类

bounds:传递一个元组,包括开始与结束

flags:在ida7.4版本中,如果前驱块被计算,flags必须设置为idaapi.FC_PREDS

返回值:

包含ida_gdl.FlowChart,内部包含所有遍历块

每个块都包含以下属性:

  • id,每个块都有独一无二的id号,第一块的id为0
  • type,类型
    • fcb_normal 一个普通块,代表值为0
    • fcb_indjump 块结束时间接跳转,值为1
    • fcb_ret 块结束时用return,值为2。ida_gdl.is_ret_block(block.type)也可以识别这种块
    • fcb_cndret 有条件判断的return,值为3
    • fcb_noret 没有return,值为4
    • fcb_enoret 没有return并且不属于任何一个函数,值为5
    • fcb_extern extern普通块,值为6
    • fcb_error is a block that passes execution past the function end(翻译不出来了,估计是通过函数传递执行),值为7
  • start_ea 块开头
  • end_ea 块结束
  • preds 返回所有全部前驱地址的生成器
  • succs 返回所有全部后驱地址的生成器

ps:preds和succs在给的例子中,中间的block块都给出了前驱后驱

结构

idc.add_default_til(name)

加载TIL表

TIL表是ida对于C/C++结构独有的文件头,可以按(SHIFT+F11)导入不同的TIL表

返回值:

是否加载成功

idc.import_type(idx, type_name)

加载不同的定义

idx:每种type都有自己的id,若值为-1,则表示该加载type列表中的最后一个。因为加载项每次不固定,所以-1使用的很常见

一般有三种 _TEB, PEB and PEB_LDR_DATA

idc.get_struc_id(string_name)

获取加载type的ID

idc.op_stroff(ea, n, strid, delta)

参数:

ea:包含偏移的指令,即将被加载

n:操作数数量

strid:需要用于将偏移量转换为结构体的type id

delta: the delta between the structures base and the pointer into the structure.(意思应该是结构体基址和指针的中间量)

idc.del_struc(sid)

删除结构体

idc.add_struc(index, name, is_union)

创建一个结构体

index:新结构体的序号,最好是-1

name:名字

is_union:判断是否是union

idc.add_struc_member(sid, name, offset, flag, typeid, nbytes)

添加结构体成员

offset:一般都是-1

flag:数据类型

typeid:更多更复杂的定义(作者没说)

nbytes:分配的空间,和flag相匹配

已枚举的Types

对于已经strip的常量,可以重新赋名