给出的文件名为rabbithole
首先使用file命令查看一下
可以看到是64位的可执行文件
接下来我们切换到win,使用IDApro,以此文件为样例,学习IDAPython的用法。
不是所有时候我们都需要写一段代码来实现自动化的代码或者数据的查找,在有些情况下我们已经知道了目标代码或数据的位置,我们仅仅获取指定区域的代码,这时候可以使用idc.SelStart()和idc.SelEnd()
比如我们选中如下的范围
使用以下脚本获取所选区域地址
import idautils
start = idc.SelStart()
print hex(start)
end = idc.SelEnd()
print hex(end)
脚本中start为所选区域的起始地址,end被赋值为该区域结束地址的下一条地址。当然还有个更专业的函数idaapi.read_selection(),该函数返回一个3元组,元组的第一个参数为布尔值,标记所选区域是否可读,第二和第三个参数为所选区域的起始和结束地址。
上图是同一个区域使用idaapi.read_selection返回的结果
我们在使用IDA时常会添加注释,注释有助于理解代码的结构和功能。
比如一条简单的异或xor置零指令:xor eax eax,相当于就是给eax置0
我们以这个为例,实现一个简单的功能,就是自动给这种指令添加注释
添加的注释内容为eax = 0
import idautils
for func in idautils.Functions():
flags = idc.GetFunctionFlags(func)
if flags & FUNC_LIB or flags & FUNC_THUNK:
continue
dism_addr = list(idautils.FuncItems(func))
for ea in dism_addr:
if idc.GetMnem(ea) == “xor”:
if idc.GetOpnd(ea,0) == idc.GetOpnd(ea,1):
comment = “% s = 0” % (idc.GetOpnd(ea,0))
idc.MakeComm(ea,comment)
代码解释:首先通过idautils.Function()循环遍历所有函数,之后通过list(idautils.FuncItems(func))将每一个函数对应的所有指令放到一个list列表中汇总,通过idc.GetMnem(ea)获取list中每一条指令的操作码,并判断该操作码是否为“xor”,之后通过函数idc.GetOpnd(ea,n)获取该条指令的两个操作数,并判断这两个操作数是否相等,若相等则给该指令添加注释。
运行结果如下
IDAPython可以写注释,那么则呢么查看注释呢?通过GetCommentEx(ea,repeatable)函数可以获取到当前地址的注释内容,其中ea为指定的地址,repeatable是一个布尔值
import idautils
for func in idautils.Functions():
flags = idc.GetFunctionFlags(func)
if flags & FUNC_LIB or flags & FUNC_THUNK:
continue
dism_addr = list(idautils.FuncItems(func))
for ea in dism_addr:
if idc.GetMnem(ea) == “xor”:
if idc.GetOpnd(ea,0) == idc.GetOpnd(ea,1):
comment = “% s = 0” % (idc.GetOpnd(ea,0))
idc.MakeComm(ea,comment)
print idc.GetCommentEx(ea,False)
我们前面是在给指令写注释,那么怎么给函数写注释呢。我们通过idc.SetFunctionCmt(ea,cmt,bool)进行函数注释。Wa为函数体中任意一处指令的地址,cmt为需要注释的内容,bool为布尔值,false表示重复注释,true为普通注释。重复注释的意思就是生效之后,其他引用的地方也会自动生成注释。
以给check_value函数添加注释为例,定位到函数体重
代码如下
import idautils
ea = idc.ScreenEA()
print hex(ea),idc.GetDisasm(ea)
print idc.GetFunctionName(ea)
idc.SetFunctionCmt(ea,“function comment test”,1)
运行后可以看到check_value的注释已经生成了
因为使用的是重复注释,所以交叉引用时可以看到引用处函数也都进行了注释
同样的,我们使用idc.GetFunctionCmt来获取注释某一行指令所在函数对应的注释,代码如下
import idautils
ea = idc.ScreenEA()
print hex(ea),idc.GetDisasm(ea)
print idc.GetFunctionName(ea)
print idc.GetFunctionCmt(ea,1)
在代码中我们打印出当前指令对应的汇编指令形式及地址,函数名和对应的注释。