IDAPRO的python插件-IDAPython

来源:互联网 发布:西门子840d循环编程 编辑:程序博客网 时间:2024/05/19 14:54
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] view plaincopy
  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.                 cross_refs = CodeRefsTo(addr, 0)  
  8.                 f1.write("################\n")  
  9.                 for ref in cross_refs:  
  10.                         f1.write(str(hex(ref)) + '\n')  
  11.   
  12.   
  13. f1.close()  

二、函数调用的统计
每当检索到函数调入的时候,就下一个断点。需要继承DBG_Hooks,实现其中的函数。
[python] view plaincopy
  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.         AddBpt(f)        #set breakpoint  
  19.         SetBptAttr(f, BPTATTR_FLAGS,0x0)  
  20.   
  21.   
  22. num_breakpoints = GetBptQty()        #return number of breakpoint  
  23. print "Set %d breakpoints." %num_breakpoints  

脚本运行完后,自动对每个函数调用设置了断点,并且断点属性是不用停下来,继续执行。然后执行调试的时候,响应的处理动作就会被执行。


三、函数栈大小
栈对于程序的运行有着重要的作用,对我们分析程序来讲更为重要。通过下面中的几个函数,我们可以得到程序在函数调用时的栈内信息,这对于我们分析函数和其参数意义重大。下面脚本是在统计每个函数调用时栈内参数的大小。
[python] view plaincopy
  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.         stack_frame = GetFrame(f)        #get frame of stack  
  8.         frame_size = GetStrucSize(stack_frame)        #compute size of stackframe  
  9.   
  10.   
  11.         frame_counter = 0  
  12.         prev_count = -1  
  13.         distance = 0  
  14.   
  15.   
  16.         while frame_counter < frame_size:  
  17.                 stack_var = GetMemberName(stack_frame, frame_counter)        #get one from stack  
  18.                 if stack_var != "":  
  19.                         if prev_count != -1:  
  20.                                 distance = frame_counter - prev_distance  
  21.                                 prev_distance = frame_counter        #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.                                 frame_counter = frame_counter + GetMemberSize(stack_frame, frame_counter)        #compute offset  
  31.                         except:  
  32.                                 frame_counter += 1  
  33.                 else:  
  34.                         frame_counter += 1  
原创粉丝点击