IDAPython是IDA的一款插件。将python和ida结合起来,利用python语言就可以更加自动化的分析程序。
IDA5版本里没有带这个插件,需要自己装,并且目前不支持python2.6+。所以还是用IDA6吧,内置自带IDAPython。
这个插件内部的脚本放在ida主目录的python目录里,里面有4个py,idaapi.py,idautils.py,idc.py,init.py,下面将会遇到的函数也都出自这里。
使用这个插件的方式有三种:
1.打开IDA后,在界面最下面(状态栏上面)的那行,可以输入命令脚本,但仅限一行。
2.菜单栏File-python command里可以输入命令脚本。
3.菜单来File-Script file里可以导入命令脚本文件。
很明显,想要达到“分析”的效果,必须使用第三种方法(快捷键Alt+F7)。熟练使用下面讲的一些函数后,根据我们特定的需求写出python脚本来,就可以达到快速的分析。在脚本处理是地址一般默认也是用十进制表示,出于习惯可以自行转换为十六进制。
首先,它可以使用所有的IDC函数。其次,它有一些特有的函数,并且python语言的特定都可以使用。手工分析总会在Pure Code,Externs,Pure Data各个段中庞大的数据弄的脑袋短路IDAPython帮我们把我们经常要做的比较繁琐的事情模块化为函数,主要是下面4种:
1.段的地址操作
2.函数的处理
3.交叉引用的检索
4.调试器Hook(需要选一个调试器)
透过下面的三个例子,我们来初步认识一下idapython的这四种函数的使用。
一、特定敏感系统函数调用的提取
下面的代码选了"strcpy","sprintf","strncpy"三个库函数作为监控对象,检索程序对它的调用。这里用到了CodeRefsTo(),用来查询哪个地方调用了这个地址。
[python]
1. from idaapi import *
2. f1 = file('danger_call.txt','w')
3. danger_funcs = ["strcpy","sprintf","strncpy"]
4. for func in danger_funcs:
5. addr = LocByName(func)
6. if addr != BADADDR:
7. 0)
8. "################\n")
9. for ref in cross_refs:
10. '\n')
11.
12.
13. f1.close()
二、函数调用的统计
每当检索到函数调入的时候,就下一个断点。需要继承DBG_Hooks,实现其中的函数。
[python]
1. from idaapi import *
2. class FuncCov(DBG_Hooks):
3. # breakpoint handler
4. def dbg_bpt(self,tid,ea):
5. print hex(ea)
6. return
7. #def dbg_library_load(self, pid, tid, ea, name, base, size):
8. print name
9. return
10.
11. debugger = FuncCov()
12. debugger.hook() #set hook
13.
14.
15. current_addr = ScreenEA()
16. for f in Functions(SegStart(current_addr), SegEnd(current_addr)):
17. #print f
18. #set breakpoint
19. 0x0)
20.
21.
22. num_breakpoints = GetBptQty() #return number of breakpoint
23. print "Set %d breakpoints." %num_breakpoints
脚本运行完后,自动对每个函数调用设置了断点,并且断点属性是不用停下来,继续执行。然后执行调试的时候,响应的处理动作就会被执行。
三、函数栈大小
栈对于程序的运行有着重要的作用,对我们分析程序来讲更为重要。通过下面中的几个函数,我们可以得到程序在函数调用时的栈内信息,这对于我们分析函数和其参数意义重大。下面脚本是在统计每个函数调用时栈内参数的大小。
[python]
1. from idaapi import *
2. var_size_threshold = 16
3. current_addr = ScreenEA()
4.
5.
6. for f in Functions(SegStart(current_addr), SegEnd(current_addr)):
7. #get frame of stack
8. #compute size of stackframe
9.
10.
11. 0
12. 1
13. 0
14.
15.
16. while frame_counter < frame_size:
17. #get one from stack
18. if stack_var != "":
19. if prev_count != -1:
20. distance = frame_counter - prev_distance
21. #record last location
22.
23. if distance >= var_size_threshold:
24. print "[*] Function: %s - > Stack Variable: %s (%d bytes)" % ( GetFunctionName(f), prev_member, distance )
25. else:
26. prev_count = frame_counter
27. prev_distance = frame_counter
28. prev_member = stack_var
29. try:
30. #compute offset
31. except:
32. 1
33. else:
34. 1