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) #输入地址,建立一个函数