Operands(操作数)
- 获取操作数的助记符我们可以调用 idc.GetOpnd(ea,long n)。 第一个参数是地址,第二个 long n
是操作数索引。第一个操作数是 0 和第二个是 1。 - idc.GetOpType(ea,n)得到的操作数的类型。ea 是地址,n 是索引
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。
Instructions(指令)
- idautils.Functions()将返回一个已知函数列表。这个列表将包含起始地址的每一个函数。idautils.Functions()可传递的参数范围内搜索。如果我们想要搜索可以通过开始地址和结束地址 idautils.Funtions(start_addr, end_addr) 。
- idc.GetFunctionName(func_ea),返回函数名称
- idc.GetMnem(ea):获取指令名称
- 邻近指令:
获得下一条指令地址: idc.NextHead(ea)
获得前一条指令地址idc.PrevHead(ea)。
这些功能将得到下一个指令的开始而不是下一个地址
- 邻近地址
得到下一个地址我们使用idc.NextAddr(ea)
得到前一个地址我们使用 idc.PrevAddr(ea)
Xrefs(交叉引用)
- 通过调用idautils.CodeRefsTo(ea, flow)。它能通过遍历将返回一个迭代器。ea是我们想要得到 的交叉引用的地址。参数流是一个 bool类型。它被用来指定是否要遵照正常的代码流。然后显示每一个交叉引用的地址。
获得内存值
- 整形:idc.Byte(ea)/idc.Word(ea)/idc.Dword(ea)/idc.Qword(ea)
- 浮点数:idc.GetFloat(ea)/idc.GetDouble(ea)
Patch
- 按字节patch:idc.PatchByte(ea, value)
示例
addr = 0x401500
for i in range(0xBA):
PatchByte(addr+i, Byte(addr+i)^0x41)
-
按字:idc.PatchWord(ea, value)
-
按双字:idc.PatchDword(ea, value)
命令行
有时我们需要使用IDA对大量二进制文件进行分析,这个时候我们就需要使用IDA的命令行模式来进行批量操作
命令行指令
基础命令如下:
ida(ida64) input-file (Start graphical interface)
idat input-file (Start text interface)
我们还需要添加一下参数,常用参数如下:
-h帮助界面
-L表示输出的日志路径
-c表示对二进制文件进行反汇编(删除旧的数据库)
-A表示自动模式,IDA不会提示一些信息,会自动处理
-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()
因为我们要批量分析,就需要重复执行指令,写一个调用脚本来自动执行:
# -*- 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,猜测可能路径没有配置对,后面换了一个安装版的就解决了