第一个函数为PrevHead,该函数用于获取一段代码段中的指令,ea为开始,mines为结尾,
    注意这个函数的搜索为降序搜索,说白了就是往前找。
    通过这个函数我们就可以获取解密函数之前的指令,
    即push offset xxxxx指令所在的代码区域了

    long PrevHead (long ea, long minea);

    第二个函数为GetMnem,用于获取ea指定地址附近的指令

    string GetMnem (long ea);

    第三个函数为GetOpnd,用于获取操作指定地址ea附近指令的操作码,
    注意此处的n为操作码的编号,由0开始,
    比如指令push offset xxxxx,0号操作码为push

    string GetOpnd (long ea,long n);

    第四个函数为GetOperandValue,用于获取指定地址ea附近指令的操作数,通用n为操作数的编号,
    由0开始,比如指令push offset xxxxx,0号操作码为xxxxx

    long GetOperandValue (long ea,long n);

    ================================================================================

    ScreenEA()
    获取 IDA 调试窗口中,光标指向代码的地址。通过这个函数,我们就能够从一个已知 的点运行我们的脚本。

    GetInputFileMD5()
    返回 IDA 加载的二进制文件的 MD5 值,通过这个值能够判断一个文件的不同版本是否 有改变。

    FirstSeg()
    访问程序中的第一个段。

    NextSeg()
    访问下一个段,如果没有就返回 BADADDR

    SegByName( string SegmentName )
    通过段名字返回段基址,举个例子,如果调用.text 作为参数,就会返回程序中代码段的开始位置。

    SegEnd( long Address )
    通过段内的某个地址,获得段尾的地址。

    SegStart( long Address )
    通过段内的某个地址,获得段头的地址。

    SegName( long Address )
    通过段内的某个地址,获得段名。

    Segments()
    返回目标程序中的所有段的开始地址。

    Functions( long StartAddress, long EndAddress )
    返回一个列表,包含了从 StartAddress 到 EndAddress 之间的所有函数。

    Chunks( long FunctionAddress )
    返回一个列表,包含了函数片段。每个列表项都是一个元组(chunk start, chunk end)

    LocByName( string FunctionName )
    通过函数名返回函数的地址。

    GetFuncOffset( long Address )
    通过任意一个地址,然后得到这个地址所属的函数名,以及给定地址和函数的相对位移。 然后把这些信息组成字符串以”名字+位移”的形式返回。

    GetFunctionName( long Address )
    通过一个地址,返回这个地址所属的函数。

    CodeRefsTo( long Address, bool Flow )
    返回一个列表,告诉我们 Address 处代码被什么地方引用了,Flow 告诉 IDAPython 是否要 跟踪这些代码。

    CodeRefsFrom( long Address, bool Flow )
    返回一个列表,告诉我们 Address 地址上的代码引用何处的代码。

    DataRefsTo( long Address )
    返回一个列表,告诉我们 Address 处数据被什么地方引用了。常用于跟踪全局变量。

    DataRefsFrom( long Address )
    返回一个列表,告诉我们 Address 地址上的代码引用何处的数据。

    Heads(start=None, end=None)
    得到两个地址之间所有的元素

    GetDisasm(addr)
    得到addr的反汇编语句

    GetMnem(addr)
    得到addr地址的操作码

    BADADDR
    验证是不是错误地址

    GetOpnd(addr,long n)
    第一个参数是地址,第二个long n是操作数索引。第一个操作数是0和第二个是1。

    idaapi.decode_insn(ea)
    得到当前地址指令的长度

    idc.FindFuncEnd(ea)
    找到当前地址的函数结束地址

    Entries()
    入口点信息

    Structs()
    遍历结构体

    StructMembers(sid)
    遍历结构体成员

    DecodePrecedingInstruction(ea) 获取指令结构
    DecodePreviousInstruction(ea)
    DecodeInstruction(ea)

    Strings(object) 获取字符串
    GetIdbDir() 获取idb目录
    GetRegisterList() 获取寄存器名表
    GetInstructionList 获取汇编指令表

    atoa(ea) 获取所在段
    Jump(ea) 移动光标
    Eval(expr) 计算表达式
    Exec(command) 执行命令行
    MakeCode(ea) 分析代码区
    MakeNameEx(ea, name, flags) 重命名地址
    MakeArray(ea, nitems) 创建数组
    MakeStr(ea, endea) 创建字符串
    MakeData(ea, flags, size, tid) 创建数据
    MakeByte(ea)
    MakeWord(ea)
    MakeDWord(ea)
    MakeQWord(ea)
    MakeOWord(ea)
    MakeYWord(ea)
    MakeFlot(ea)
    MakeDouble(ea)
    MakePackReal(ea)
    MakeTbyte(ea)
    MakeStructEx(ea)
    MakeCustomDataEx(ea)

    PatchByte(ea, value) 修改程序字节
    PatchWord(ea, value)
    PatchDword(ea, value)
    PatchByte(ea, value)
    PatchByte(ea, value)

    Byte(ea) 将地址解释为Byte
    Word(ea)
    DWord(ea)
    QWord(ea)
    GetFloat(ea)
    GetDouble(ea)
    GetString(ea, length = -1, strtype = ASCSTR_C) 获取字符串
    GetCurrentLine() 获取光标所在行反汇编

    ItemSize(ea) 获取指令或数据长度

    FindText(ea, flag, y, x, searchstr)查找文本
    FindBinary(ea, flag, searchstr, radix=16) 查找16进制

    GetEntryPointQty() 获取入口点个数
    GetEntryOrdinal(index) 获取入口点地址
    GetEntryName(ordinal) 入口名

    1. idc.GetFunctionAttr(ea, attr) //得到当前地址所在函数的数据
    2. (
    3. FUNCATTR_START = 0 # function start address
    4. FUNCATTR_END = 4 # function end address
    5. FUNCATTR_FLAGS = 8 # function flags
    6. FUNCATTR_FRAME = 10 # function frame id
    7. FUNCATTR_FRSIZE = 14 # size of local variables
    8. FUNCATTR_FRREGS = 18 # size of saved registers area
    9. FUNCATTR_ARGSIZE = 20 # number of bytes purged from the stack
    10. FUNCATTR_FPD = 24 # frame pointer delta
    11. FUNCATTR_COLOR = 28 # function color code
    12. FUNCATTR_OWNER = 10 # chunk owner (valid only for tail chunks)
    13. FUNCATTR_REFQTY = 14 # number of chunk parents (valid only for tail chunks)
    14. )
    1. class DbgHook(DBG_Hooks):
    2. # Event handler for when the process starts
    3. def dbg_process_start(self, pid, tid, ea, name, base, size)
    4. return
    5. # Event handler for process exit
    6. def dbg_process_exit(self, pid, tid, ea, code):
    7. return
    8. # Event handler for when a shared library gets loaded def
    9. dbg_library_load(self, pid, tid, ea, name, base, size):
    10. return
    11. # Breakpoint handler
    12. def dbg_bpt(self, tid, ea):
    13. return

    这个类包含了我们在创建调试脚本时,会经常用到的几个调试事件处理函数。安装 hook 的方式如下:
    debugger = DbgHook()
    debugger.hook()
    现在运行调试器,hook 会捕捉所有的调试事件,这样就能非常精确的控制 IDA 调试器。 下面的函数在调试的时候非常有用:
    AddBpt( long Address )
    在指定的地点设置软件断点。
    GetBptQty()
    返回当前设置的断点数量。
    GetRegValue( string Register )
    通过寄存器名获得寄存器值。
    SetRegValue( long Value, string Register )

    查找strCpy的参数

    1. def is_stack_buffer(addr, idx):
    2. inst = DecodeInstruction(addr)
    3. # IDA < 7.0
    4. try:
    5. ret = get_stkvar(inst[idx], inst[idx].addr) != None
    6. # IDA >= 7.0
    7. except:
    8. from ida_frame import *
    9. v = inst[idx].addr
    10. if sys.maxint < v:
    11. v = twos_compl(v)
    12. ret = get_stkvar(inst, inst[idx], v)
    13. return ret
    14. def find_arg(addr,arg_num): ##This is x86
    15. function_h=LocByName(GetFunctionName(addr))
    16. step=0
    17. arg_cou=0
    18. while step<0 :
    19. step=step+1
    20. addr=idc.PrevHead(addr)
    21. op=GetMnem(addr).lower()
    22. if op in ("ret","jmp","retn","b") or addr<function_h:
    23. return
    24. if op =="push":
    25. arg_count=arg_count+1
    26. if arg_count==arg_num:
    27. return GetOpnd(addr,0)
    28. for functionaddr in Functions():
    29. if "strcpy" in GetFunctionName(functionaddr):
    30. xref=CodeRefsTo(functionaddr,0)
    31. for xxx in xref:
    32. if GetMnem(xxx).lower()=="call":
    33. oped= find_arg(xxx,1)
    34. function_h=LocByName(GetFunctionName(xxx))
    35. addr_=xxx
    36. lalal=xxx
    37. while True:
    38. __add=idc.PrevHead(addr_)
    39. __op=GetMnem(__add).lower()
    40. if __op in ("ret", "retn", "jmp", "b") or __add < function_h:
    41. break
    42. if __op == "lea" and GetOpnd(__add,0)==oped:
    43. if is_stack_buffer(addr_,1):
    44. prinf "STACK at 0x%X"%lalal
    45. break
    46. if __op == "mov" and GetOpnd(addr_,0)==oped:
    47. op_type = GetOpType(addr_, 1)
    48. if op_type == o_reg:
    49. oped = GetOpnd(addr_, 1)
    50. lalal = addr_
    51. else:
    52. break

    ================================================================================