摘要:记录一些关于IDA python的一些记录。

参考资料

IDA python的教程:
the beginner's guide to idapython 中文版_2.pdf

IDA python的各个函数的详细说明:
IDA plugin wirting(all chapter).pdf

对上面参考资料修正

以下适用于IDA pro 7.0版本,因为IDA pro的版本问题,有些api被取消

  • idaapi.ua_outop2(curr_addr,0)被idaapi.print_operand(curr_addr,0)代替,也可以直接使用idc.GetMnem(curr_addr)直接代替。此外idaapi.ua_outop2(curr_addr,0)需要idaapi.tag_remove(idaapi.ua_outop2(curr_addr,0))这样使用,而idaapi.print_operand(curr_addr,0)和idc.GetMnem(curr_addr)可以直接用。

    下面是idaapi.tag_remove的函数说明(详情见上面的 IDA python的各个函数的详细说明

    idaman int ida_export
    tag_remove(const char *instr, char *buf, int bufsize)
    含义 删除*instr中的任何颜色标记,并将结果保存到*buf,限定长
    度为bufsize。在bufsize为0的情况下,指定*instr和*buf为同
    一指针也是允许的。该函数定义在ines.hpp。 

    代码示例:

    import idautils
    import idaapi
    displace = {}
    # for each known function
    for func in idautils.Functions():
        flags = idc.GetFunctionFlags(func)
        # skip library & thunk functions
        if flags & FUNC_LIB or flags & FUNC_THUNK:
            continue
        dism_addr = list(idautils.FuncItems(func))
        for curr_addr in dism_addr:
            op = None
            index = None
            # same as idc.GetOptype, just a different way of accessing the types
            idaapi.decode_insn(curr_addr)
            if idaapi.cmd.Op1.type == idaapi.o_displ:
                op = 1
            if idaapi.cmd.Op2.type == idaapi.o_displ:
                op = 2
            if op == None:
                continue
            if "bp" in idc.GetOpnd(curr_addr,0) or "bp" in idc.GetOpnd(curr_addr, 1):
            # ebp will return a negative number
                if op == 1:
                    index = (~(int(idaapi.cmd.Op1.addr) - 1) &0xFFFFFFFF)
                else:
                    index = (~(int(idaapi.cmd.Op2.addr) - 1) &0xFFFFFFFF)
            else:
                if op == 1:
                    index = int(idaapi.cmd.Op1.addr)
                else:
                    index = int(idaapi.cmd.Op2.addr)
                # create key for each unique displacement value
            if index:
                    if displace.has_key(index) == False:
                        displace[index] = []
                    displace[index].append(curr_addr)
    
    # 使用方法 for x in displace[4]: print hex(x),GetDisasm(x)
    # displace是一个字典,可以打印查看参数

    此外idaapi.cmd.Op1.type 与 idc.GetOpType(ea,n) 功能一样。都是获取操作数的类型

  • 下面这个实例,因为现在的IDA pro已经很智能了,所以效果不太能提体现

    import idautils
    import idaapi
    min = MinEA()
    max = MaxEA()
    for func in idautils.Functions():
        flags = idc.GetFunctionFlags(func)
        if flags & FUNC_LIB or flags & FUNC_THUNK:
            continue
        dism_addr = list(idautils.FuncItems(func))
        for curr_addr in dism_addr:
            if idc.GetOpType(curr_addr,0) == 5 and (min <idc.GetOperandValue(curr_addr,0) < max):
                idc.OpOff(curr_addr, 0, 0)
            if idc.GetOpType(curr_addr,1) == 5 and (min <idc.GetOperandValue(curr_addr,1) < max):
                idc.OpOff(curr_addr, 1, 0)
  • 关于idc.isTail(f) idc.isHead(f)
    idc.isTail(f) idc.isHead(f)文档中写的不太清,去读<module 'idc' from 'E:\BaiduNetdiskDownload\IDA_Pro_v7.0_Portable\python\idc.pyc'>看实现原理还是不明白,太难了。
  • idc.GetCommentEx和idc.SetFunctionCmt(ea,cmt,bool)
    文档写错了,下面的结论经过实验才是对的。

    1. idc.GetCommentEx获取不到重复的注释,以及系统添加的注释,也就是带灰色字体的注释。
      并且手动添加的重复注释必须使用idc.GetCommentEx(ea,True)才能获得,
    2. 系统添加的蓝色注释必须使用idc.GetCommentEx(ea,False)才能获得。
    3. 通过函数 idc.SetFunctionCmt(ea,cmt,bool)进行一个函数注释。ea 为函数体中任意一处指令的地址,cmt 为需要注释的内容,bool 为布尔值,其中 True 表示重复注释,False 为普通注释。