利用ida python 实现复原函数调用的参数 (仅对数据被简单硬编码有效)
生活随笔
收集整理的這篇文章主要介紹了
利用ida python 实现复原函数调用的参数 (仅对数据被简单硬编码有效)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
例如我們有一個 c 源程序
編譯運行(本人使用了交叉編譯,生成ARM平臺下可執行文件)
然后使用所寫腳本即可還原函數調用的參數,不過 腳本的輸入是 ?printf的格式化字符串 例如:“print3 %d”
ida腳本如下:
#!/usr/bin/env python # coding=utf-8from idc import * from idaapi import * import idautils class AnayBinFil(object):def __init__(self):list = []# 得到某一條匯編指令所指向的內存的內容 def GetXref_String(self,ea,n):if (GetOpType(ea,n) == 2):ea = GetOperandValue(ea,n)if (not SegName(ea) == '.rodata'):addrx = idautils.DataRefsFrom(ea)for item in addrx:return self.GetXref_String(item,n)return idc.Dword(ea)return GetString(ea)#get the register's content whose number is i from ea forward searchdef get_content_register(self,ea,i):#print hex(ea) , idc.GetDisasm(ea), iif (GetOpType(ea,0) == 1 and GetOperandValue(ea,0) == i):# wanted registerif (ua_mnem (ea) == 'LDR'):if (GetOpType(ea,1) == 2):#Optype is Memory Referencereturn self.GetXref_String(ea,1)elif (GetOpType(ea,1) == 4):#Base+index+Displacementif(GetOperandValue(ea,1) == 0): # like : LDR R3,[R3]return self.get_content_register(PrevHead(ea),i)else:return else :print 'unkown Optype:' ,hex(ea),idc.GetDisasm(ea)elif (ua_mnem(ea) == 'MOV'):if (GetOpType(ea,1) == 5):return GetOperandValue(ea,1)elif (GetOpType(ea,1) == 1):return self.get_content_register(PrevHead(ea),GetOperandValue(ea,1))else:print 'unkown OpType:',hex(ea),idc.GetDisasm(ea)else:return self.get_content_register(PrevHead(ea),i)#from a call instruction BackForward search parameterdef BackForward(self,addr,n):Reg_content = []#addr = PrevHead(addr)i = 0 # register numberfor i in range(n):Reg_content.append(self.get_content_register(addr,i))return Reg_contentdef Anayl_Func_Call(self, func_name, para_num):if func_name == "":return#get start addresssegkind = ['.text' , '.init' ,'.plt'] #startaddr = idc.SegByName('.rodata')startaddr = MinEA() #fun_addr = idc.LocByName(func_name)# search the address of the pattern textwhile True:fun_addr = FindText(startaddr,SEARCH_DOWN, 0, 0, func_name)if not (SegName(fun_addr)) in segkind:breakstartaddr = NextHead(fun_addr)print 'find pattern string addr',hex(fun_addr)#byte_str = [hex(y) for y in bytearray(func_name)]#print byte_str#print hex(fun_addr),idc.GetDisasm(fun_addr)call_addrs = idautils.DataRefsTo(fun_addr)dic = {}for item in call_addrs:if (not isCode(GetFlags(item))):continue#print hex(item),idc.GetDisasm(item)CALL_ADDR = itemwhile ( not ua_mnem(CALL_ADDR) == 'BL' ):CALL_ADDR = NextHead(CALL_ADDR)CALL_ADDR = PrevHead(CALL_ADDR) #print 'from addr %s analyses' % (str(hex(CALL_ADDR)))para = self.BackForward(CALL_ADDR,para_num)xref_funname = GetFunctionName(CALL_ADDR)dic[xref_funname] = parareturn dicdef print_help():info = 'use this as : idal64/idal -S"Anaylise_All.py \'print1 %s\'" 'print infodef main():#test codeif (len (idc.ARGV) < 2):print_help()ana_fun_name = '%s version %s protocol version %d%s'else:ana_fun_name = idc.ARGV[1]#要分析的函數名para_num = 0 #參數數量pos = ana_fun_name.find('%')while (not pos == -1):para_num += 1pos += 1pos = ana_fun_name.find('%',pos)ana = AnayBinFil()dic = ana.Anayl_Func_Call(ana_fun_name,para_num+1)print '在函數中','其調用參數為'for item in dic:print item , dic[item]sf = open("out.dat",'w')if not sf:sf.write ('parameter:'+str(idc.ARGV[0])+str(idc.ARGV[1])+'\n')idc.Exit(0)for item in dic:sf.write('In function : '+item+'\n')x = (dic[item])s = ' 'for i in range(len(x)):if x[i] is None:continues += str(x[i])+' , 'sf.write(s + '\n')sf.close()'''# get all names and it's addrfor x in Names():print x''' idc.Exit(0)if __name__ == '__main__':main()
-S 表示運行ida python腳本
得到結果
In function : print4
? ? print4 %s , 1.1.1222 ,?
總結
以上是生活随笔為你收集整理的利用ida python 实现复原函数调用的参数 (仅对数据被简单硬编码有效)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 非阻塞,send后马上close消息能成
- 下一篇: 使用LoadRunner对Web Ser