LOADING

加载过慢请开启缓存 浏览器默认开启

IDApy的初步学习

ida版本为IDA9.0

用VScode编写IDApython

  • 找到这个项目IDAcode,把下来的文件加到你ida的plugins文件夹中。
  • 修改idacode_utils/settings.py中的PYTHON路径为本地的python路径
  • 在本地中用控制台安装依赖
python -m pip install --user debugpy tornado
  • 在VScode中安装IDAcode插件
  • 在VScode按CTRL+Shift+P输入”Open User Settings(JSON)”打开后添加如下代码。
"python.autoComplete.extraPaths": [
        "E:\\CTFtoolsNEW\\Reverse\\IDA90\\python\\3"   //你的ida库路径
     ],
     "python.analysis.extraPaths": [
        "E:\\CTFtoolsNEW\\Reverse\\IDA90\\python\\3"   //你的ida库路径
   ],
  • 在VScode按CTRL+Shift+P,搜索ida即可找到想要的功能。
  • 在ida插件中打开idacode,显示Listening on 127.0.0.1:7065即成功。
  • 如果出现找不到依赖的报错,请在ida目录下找到并运行idapyswitch.exe,选择同样的python解释器(切换解释器可能会导致库的缺失,请自行安装缺失的库)。
  • 如果写的命令发到ida执行报错,请在VScode中选择同样的python解释器,不要用虚拟解释器。

函数

import idc
idc.get_screen_ea()      #获取当前光标的地址
idc.here()               #获取当前光标的地址
idc.get_segm_name()      #(addr)->(str)获取当前的地址的区段名
idc.print_insn_mnem()    #(addr)->(str)获取地址的助记符(操作符)
idc.print_operand()  #(addr,ptr)->(str)获取操作数(被操作的数据),ptr为操作数的序号

idc.get_inf_attr() 获取属性

[!NOTE]

在ida9中idc库似乎有些内容被弃用,我们可以用ida_ida库实现相同的功能。官方也说明了idc库中的某些内容可能在将来的版本中被弃用。”This file is subject to change without any notice. Future versions of IDA may use other definitions.”

[]: https://python.docs.hex-rays.com/namespaceidc.html “hex-rays”

对于一些ida90的兼容性问题可参考: https://www.52pojie.cn/thread-1957552-1-1.html

idc.get_inf_attr() 是 IDAPython 中一个用于获取全局信息的函数。它可以用来访问 IDA 数据库的各种设置和属性。

idc.get_inf_attr(attr)

参数

  • attr:一个常量,表示需要获取的属性。常量通常以 idc.INF_ 开头。

返回值

  • 返回对应属性的值。不同的属性类型可能会返回整数、字符串或其他数据。

常用的 idc.INF_ 常量

常量 描述
idc.INF_MIN_EA 返回程序的最小地址。
idc.INF_MAX_EA 返回程序的最大地址。
idc.INF_FILETYPE 返回文件类型(整型,参考 ida_loader.FILE_ 常量)。
idc.INF_START_IP 返回程序的入口点(如 _start 的地址)。
idc.INF_BIN_PREFIX_SIZE 返回 IDA 设置的二进制文件加载时的前缀大小。
idc.INF_LFLAGS 返回加载标志(如加载时的选项)。

idc_idc库获得属性

[!NOTE]

用ida_ida库替换idc库的idc.get_inf_attr(attr),这是在高版本的实现方式。

import ida_ida as ida
ida.inf_get_max_ea()  #()->(程序最大地址)
ida.inf_get_min_ea()  #()->(程序最小地址)
ida.inf_get_start_ip() #()->(start的地址/入口点)

一些ida9的api替换

ida_search.find_binary() --> ida_bytes.bin_search()
ida_bytes.compiled_binpat_vec_t() #ida内部定义的类型,要使用此类型需要通过ida_bytes.parse_binpat_str(data,ea,bin_str,16)转化

去花指令

import idautils
import idc
import idaapi

def nop_jzjnz(start_addr,endaddr,pattern):
    length =len(pattern)
    flag = 0
    while start_addr < endaddr:
        getbytes =idc.get_bytes(start_addr,length) #获取指定范围内指定地址的字节码并返回成列表
        if(getbytes[0]==pattern[0] and getbytes[2]==pattern[2] and getbytes[4] == pattern[4] ):  #匹配花指令模板
            flag = 1
            for i in range(length):        
                idc.patch_byte(start_addr + i,0x90)  #nop
            print(f"success! nop 0x{hex(start_addr)} to 0x{hex(start_addr + length -1)} length:{length}")
            start_addr += length - 1
        start_addr += 1
    if(flag == 0):
        print("Not find!!!")
        
def nop_range(start_addr,end_addr):
    while(start_addr <= end_addr):
        idc.patch_byte(start_addr,0x90)
        start_addr += 1
    print(f"success! nop 0x{start_addr} to 0x{end_addr}")

def remount(): #重建光标所指内的函数
    try:
        addr = idc.get_screen_ea()
        func = idaapi.get_func(addr)
        func_start = func.start_ea
        idaapi.del_func(func_start)
        idaapi.add_func(func_start)
        print(f"success!! remount the func in 0X{func}")
    except Exception as a:
        print("some errors occur, remount falrue")
        print(f"error : {a}")

start_addr = 0x0401020   
end_addr = 0x040122F    

pattern_jzjnz1 = [0x74, 0x00, 0x75, 0x00, 0xE8] # call
pattern_jzjnz2 = [0x74, 0x00, 0x75, 0x00, 0xE9] # jmp


#nop_jzjnz(start_addr,end_addr,pattern_jzjnz1)
#nop_range(0x04010C3,0x04010CB)
#remount()
import ida_dbg
ecx = ida_dbg.get_reg_val("ecx")
print(",",ecx,end="")
#在断点处右键edit用三个点输入脚本以dump寄存器的值
idc.get_bytes() #获取指定范围内指定地址的字节码并返回成列表

idc.patch_byte()  #修改地址字节码

idaapi.get_func(addr) #输入一个在函数内的地址,返回一个函数对象,包含了函数的各种信息,可用dir()查看可用属性
idaapi.del_func(func_start) #输入地址,删除一个函数
idaapi.add_func(func_start) #输入地址,建立一个函数