IDA Python
常用函数
获取界面中的地址
在IDA 7.5中. 我们获取地址的函数如下
当前地址获取使用 idc.here() 函数 或者 idc.get_screen_ea() 函数
最小地址可以使用: ida_ida.inf_get_min_ea()
最大地址可以使用: ida_ida.inf_get_max_ea()
当前选择地址的开始: idc.read_selection_start()
当前选择地址的结束:idc.read_selection_end()
如果判断地址是否存在可以使用: idaapi.BADADDR
print(hex(idc.here())) #获取当前地址
print(hex(idc.get_screen_ea())) #另一种获取当前地址的函数
print(hex(ida_ida.inf_get_min_ea())) #获取当前最小地址
print(hex(ida_ida.inf_get_max_ea())) #获取当前最大地址
print(hex(idc.read_selection_start()))#如果你选择了某块地址 那么使用此函数则返回你选择的这块地址的起始地址
print(hex(idc.read_selection_end())) #同上 返回结束地址.
if idaapi.BADADDR == idc.here():
print("BadAddress addr invalid")
else:
print("addr is ok")
获取汇编的指令操作
idaapi.get_imagebase() 获取基地址
import idc
import idaapi
import idautils
ea = idc.here();
print("当前模块基址为: {}".format(hex(idaapi.get_imagebase())))
print("当前的汇编语句为: {}".format(idc.GetDisasm(ea)))
print("当前的汇编指令为: {}".format(idc.print_insn_mnem(ea)))
print("当前的操作数为: {}".format(idc.print_operand(ea,0)))
print("当前的操作数值为: {}".format(idc.get_operand_value(ea,0)))
对段的操作
指令 | 作用 | 新函数 |
---|---|---|
idc.SegName(addr) | 获取段的名字 | idc.get_segm_name(addr) |
idc.SegStart(addr) | 获取段的开始地址 | idc.get_segm_start(addr) |
idc.SegEnd(addr) | 获取段的结束地址 | idc.get_segm_end(addr) |
idautil.Segments() | 返回一个列表记录所有段的地址 | |
idc.FirstSeg() | 获取第一个段 | idc.get_first_seg(addr) |
idc.NextSeg(addr) | 获取下一个段 参数是当前段的地址 返回的是下一个段的地址 | idc.get_next_seg(addr) |
import idc
import idaapi
import idautils
for seg in idautils.Segments():
segname = idc.get_segm_name(seg)
segstart = idc.get_segm_start(seg)
segend = idc.get_segm_end(seg)
print("段名 = {} 起始地址= {} 结束地址 = {} ".format(segname,hex(segstart),hex(segend)));
IDA中的函数操作
老函数 | 作用 | 新函数 |
---|---|---|
Functions(startaddr,endaddr) | 获取指定地址之间的所有函数 | 无 |
idc.GetFunctionName(addr) | 获取指定地址的函数名 | idc.get_func_name(addr) |
idc.GetFunctionCmt | 获取函数的注释 | get_func_cmt(ea, repeatable) 1是地址 2是0或1 1是获取重复注释 0是获取常规注释 |
idc.SetFunctionCmt | 设置函数注释 | set_func_cmt(ea, cmt, repeatable) |
idc.ChooseFunction(title) | 弹出框框要求用户进行选择 参数则是信息 | idc.choose_func(title) |
idc.GetFuncOffset(addr) | 返回: addr 距离函数的偏移形式 | idc.get_func_off_str(addr) |
idc.FindFuncEnd(addr) | 寻找函数结尾,如果函数存在则返回结尾地址,否则返回BADADDR | idc.find_func_end(addr) |
idc.SetFunctionEnd(addr,newendaddr) | 设置函数结尾 | ida_funcs.set_func_end |
ida_funcs.func_setstart(addr,newstartaddr) | 设置函数开头 | ida_funcs.set_func_start(addr, newstart) |
idc.MakeFunction | 创建函数 | ida_funcs.add_func(ea) |
idc.DelFunction | 删除函数 | ida_funcs.del_func(ea) |
idc.MakeName(addr, name) 与之同名了还有Ex函数 | 设置地址处的名字 | idc.set_name(ea, name, SN_CHECK) Ex函数也使用set_name |
idc.PrevFunction | 获取首个函数 | idc.get_prev_func |
idc.NextFunction | 获取下一个函数 | idc.get_next_func |
import idc
import idaapi
import idautils
for seg in idautils.Segments():
segname = idc.get_segm_name(seg)
segstart = idc.get_segm_start(seg)
segend = idc.get_segm_end(seg)
print("段名 = {} 起始地址= {} 结束地址 = {} ".format(segname,hex(segstart),hex(segend)));
if (segname == '.text'):
for funcaddr in Functions(segstart,segend):
funname = idc.get_func_name(funcaddr)
funend = idc.find_func_end(funcaddr)
funnext = idc.get_next_func(funcaddr)
funnextname = idc.get_func_name(funnext)
print("当前函数名 = {} 当前结束地址 = {} 下一个函数地址 = {} 下一个函数名= {} ".format(funname,hex(funend),hex(funnext),funnextname))
ea = idc.get_screen_ea()
funnextoffset = idc.get_func_off_str(ea)
print("当前选择地址距离当前函数的偏移为: {} ".format(funnextoffset))
实战
获取所有函数的起始地址偏移
批量化
单个脚本执行
C:\\Study\\BinaryAnalyse>C://Pwn/IDA/ida64.exe -LC:/mylog.log -c -A -S"C://Study/BinaryAnalyse/analyse.py" C://Study/BinaryAnalyse/datas/crackme0x03.exe
PS:Windows注意-S后的脚本名称需要添加双引号
- c 表示对要分析的二进制文件生成一个新的IDB文件。 -A表示以autonomous模式运行,如果不加这个选项,则会弹出图形界面。 -S 制定要执行的 plugin script。
批量执行
//analyse.py
import idc
import idautils
import idaapi
from collections import defaultdict
def analysis():
pass
# 这里是分析的代码
def main():
"""
控制器
"""
idc.auto_wait() # 等IDA分析完后才执行
analysis()
idc.qexit(0) # 关闭IDA
if __name__ == "__main__":
main()
批量
//run.py
# -*- coding:utf-8 -*-
# =======Import =======
import os
import subprocess
#C:\\Study\\BinaryAnalyse\\datas
#C:\\Pwn\\IDA Pro 7.6
dir_path = "C://Study/BinaryAnalyse/datas/" # 原始数据的文件夹
ida64_path = "C://Pwn/IDA/ida64.exe" # ida64的路径
ana_file = "C://Study/BinaryAnalyse/analyse.py" # 分析文件的路径
def run():
for root, dirs, files in os.walk(dir_path):
for file_name in files:
file_path = os.path.join(root, file_name)
cmd = "{0} -LC:/mylog.log -c -A -S\\"{1}\\" {2}".format(ida64_path, ana_file, file_path)
print(cmd)
p = subprocess.Popen(cmd)
p.wait()
if __name__ == "__main__":
run()
参考链接
IDAPython入门教程 基于IDA7.5_Python3 第一讲 简介与地址获取
Porting from IDAPython 6.x-7.3, to 7.4
IDAPython documentation
https://www.anquanke.com/post/id/197784#h3-5
IDApython插件编写及脚本批量分析教程_y4ung-CSDN博客_ida python脚本
https://www.keepnight.com/usr/uploads/2020/09/1365696735.pdf
Gencoding/raw-feature-extractor at master · qian-feng/Gencoding