概述
Operands(操作数)
- 获取操作数的助记符
idc.GetOpnd(ea,long n) IDA 7.0
idc.print_operand(ea, n) IDA 7.4
第一个参数是地址,第二个 long n
是操作数索引。第一个操作数是 0 和第二个是 1。
2.得到的操作数的类型。ea 是地址,n 是索引
idc.GetOpType(ea,n) IDA 7.0
idc.get_operand_type(ea, n) IDA 7.4
返回值:
idc.o_void
如果一个指令没有任何操作数它将返回 0。
idc.o_reg
如果一个操作数是一个普遍的寄存器将返回此类型。这个值在内部表示为 1。
idc.o_mem
如果一个操作数是直接内存引用它将返回这个类型。这个值在内部表示为 2。这种类型
是有用的在 DATA 段查找引用。
idc.o_phrase
这个操作数被返回则这个操作数包含一个基本的寄存器或一个索引寄存器。这个值在内
部表示为 3。
idc.o_displ
这个操作数被返回则操作数包含寄存器和一个位移值,这个为位移值是一个整数,例如
0x18。这是常见的当一条指令访问值在一个结构中。在内部,它表示为 4 的值。
idc.o_imm
操作数是这样一个为整数的 0xc 的值的类型。它在内部表示为 5。
idc.o_far
这个操作数不是很常,见当逆向 x86 或 x86_64
时。它是用来寻找操作数的访问立即数远 地址的。它在内部表示为 6。
idc.o_near
这个操作数不是很常见,当逆向 x86 或 x86_64
时。它是用来寻找操作数的访问立即数近 地址的。它在内部表示为 7。
- 可以获取操作数真正的地址
idc.GetOperandValue(ea, n) IDA 7.0
idc.get_operand_value(ea, n) IDA 7.4
例如这样一条指令
movzx eax, _ans[eax]
_ans是位于data或者bss段上的一个变量,用这个命令这可以得到在data或者bss段上的地址
Instructions(指令)
- idautils.Functions()将返回一个已知函数列表。这个列表将包含起始地址的每一个函数。idautils.Functions()可传递的参数范围内搜索。如果我们想要搜索可以通过开始地址和结束地址 idautils.Funtions(start_addr, end_addr) 。
- 返回函数名称
idc.GetFunctionName(func_ea) IDA 7.0
ida_funcs.get_func_name(functionAddr) IDA 7.4
- 获取反汇编指令
idc.GetDisasm(ea)
- 获取指令名称
idc.GetMnem(ea) IDA 7.0
idc.print_insn_mnem(ea) IDA 7.4
- 邻近指令:
获得下一条指令地址:
IDA 7.0:idc.NextHead(ea)
IDA 7.4:idc.next_head(ea)
获得前一条指令地址:
IDA 7.0:idc.PrevHead(ea)。
IDA 7.4:idc.prev_head(ea)
这些功能将得到下一个指令的开始而不是下一个地址
- 邻近地址
得到下一个地址:
idc.NextAddr(ea) IDA 7.0
idc.next_addr(ea) IDA 7.4
得到前一个地址:
idc.PrevAddr(ea) IDA 7.0
idc.prev_addr(ea) IDA 7.4
- 根据函数名获取地址
idc.LocByName(func) IDA 7.0
ida_name.get_name_ea(idaapi.BADADDR, func) IDA 7.4
- 获取函数属性
idc.GetFunctionAttr(ea, attr) IDA 7.0
idc.get_func_attr(ea, attr) IDA 7.4
attr - one of: FUNCATTR_START, FUNCATTR_END, FUNCATTR_OWNER, FUNCATTR_REFQT
Xrefs(交叉引用)
- 通过调用idautils.CodeRefsTo(ea, flow)。它能通过遍历将返回一个迭代器。ea是我们想要得到 的交叉引用的地址。参数流是一个 bool类型。它被用来指定是否要遵照正常的代码流。然后显示每一个交叉引用的地址。
获得内存值
- 整形:
idc.Byte(ea)/idc.Word(ea)/idc.Dword(ea)/idc.Qword(ea) IDA 7.0
ida_bytes.get_byte(ea)/ida_bytes.get_word(ea)/ida_bytes.get_dword(ea)/ida_bytes.get_qword(ea) IDA 7.4
- 浮点数:
idc.GetFloat(ea)/idc.GetDouble(ea)
程序信息
- 获取节的名字
idc.SegName(ea) IDA 7.0
idc.get_segm_name(ea) IDA 7.4
- 获取节的开始与结束地址
开始:
idc.SegStart(ea) IDA 7.0
idc.get_segm_start(ea) IDA 7.4
结束:
idc.SegEnd(ea) IDA 7.0
idc.get_segm_end(ea) IDA7.4
- 获取程序基地址
idaapi.get_imagebase() IDA7.0
不过IDA 7.4的没有在手册中找到
- 重定位程序
idc.RebaseProgram(delta, flags) IDA7.0
ida_segment.rebase_program(delta, flags) IDA7.4
delta:目标偏移减去当前的base
flags - Move segment flags it is recommended to use MSF_FIXONCE so that the loader takes care of global variables it stored in the database (C++: int), 这个我也不知道, 填了个0
Patch
- 按字节patch:idc.PatchByte(ea, value) IDA 7.0 / ida_bytes.patch_byte(ea, x) IDA 7.4
示例
addr = 0x401500
for i in range(0xBA):
PatchByte(addr+i, Byte(addr+i)^0x41)
-
按字:idc.PatchWord(ea, value) IDA 7.0 / ida_bytes.patch_word(ea, x) IDA 7.4
-
按双字:idc.PatchDword(ea, value) IDA 7.0 / ida_bytes.patch_dword(ea, x) IDA 7.4
-
按四字:ida_bytes.patch_qword(ea, x) IDA 7.4
命令行
有时我们需要使用IDA对大量二进制文件进行分析,这个时候我们就需要使用IDA的命令行模式来进行批量操作
命令行指令
基础命令如下:
ida(ida64) input-file (Start graphical interface)
idat input-file (Start text interface)
我们还需要添加一下参数,常用参数如下:
-h帮助界面
-L表示输出的日志路径
-c表示对二进制文件进行反汇编(删除旧的数据库)
-A表示自动模式,IDA不会提示一些信息,会自动处理,与-S合用
-S后面的路径是分析脚本的路径
注意!!其中,-L和-S与后面的路径之间是没有空格的。
所有参数请见官网:IDA Help: Command line switches
分析脚本
def analysis():
# 这里是分析的代码
pass
def main():
"""
控制器
"""
idc.Wait() # 等IDA分析完后才执行
analysis()
idc.Exit(0) # 关闭IDA
if __name__ == "__main__":
main()
注意要点:
分析过程结束必须手动添加退出代码,否则ida界面被打开
idc.Wait() IDA 7.0 或者 idaapi.qexit(0) IDA 7.4或者sys.exit(-1)
在customize分析过程之前,加上snippet:
re = idaapi.auto_wait() IDA 7.4或者 idc.Wait() IDA 7.0
必须加上这个,否则idaapi.decompile等基础功能异常
因为我们要批量分析,就需要重复执行指令,写一个调用脚本来自动执行:
# -*- coding:utf-8 -*-
# =======Import =======
import os
import subprocess
dir_path = "D://transfer/" # 原始数据的文件夹
ida64_path = "D://ProgramFiles/IDA/ida64.exe" # ida64的路径
ana_file = "D://listFunc/analysis.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} -LD:/mylog.log -c -A -S{1} {2}".format(ida64_path, ana_file, file_path)
p = subprocess.Popen(cmd)
p.wait()
if __name__ == "__main__":
run()
遇到的问题
- unknown file extension
可能是因为ida python的解释器没有正常执行,这里因为我用的是免安装版的IDA,猜测可能路径没有配置对,后面换了一个安装版的就解决了
参考资料
- IDApython插件编写及脚本批量分析教程
- ida 官方文档
- idapython manual documentary
- Porting from IDAPython 6.x-7.3, to 7.4
最后
以上就是疯狂招牌为你收集整理的IDA python 备忘Operands(操作数)Instructions(指令)Xrefs(交叉引用)获得内存值Patch命令行参考资料的全部内容,希望文章能够帮你解决IDA python 备忘Operands(操作数)Instructions(指令)Xrefs(交叉引用)获得内存值Patch命令行参考资料所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复