例如我们有一个 c 源程序
/*************************************************************************
> File Name: ddg.c
> Author:
> Mail:
> Created Time: 2017年08月24日 星期四 10时52分31秒
************************************************************************/
#include
#define Version_Num "1.122"
#define Version_num 122
const int v_num = 1222;
const char * ver_num = "1.1.1222";
char *x = "Hello world";
int main(){
int a = 112;
a += 12;
printf("Version is : %s, %d",x,a);
}
void print1 (){
printf("print1 %s",Version_Num);
}
void print2(){
printf("print2 %d",Version_num);
}
void print3(){
printf("print3 %d ",v_num);
}
void print4(){
printf("print4 %s",ver_num);
}
编译运行(本人使用了交叉编译,生成ARM平台下可执行文件)
然后使用所写脚本即可还原函数调用的参数,不过 脚本的输入是 printf的格式化字符串 例如:“print3 %d”
ida脚本如下:
#!/usr/bin/env python
# coding=utf-8
from 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 search
def get_content_register(self,ea,i):
#print hex(ea) , idc.GetDisasm(ea), i
if (GetOpType(ea,0) == 1 and GetOperandValue(ea,0) == i):# wanted register
if (ua_mnem (ea) == 'LDR'):
if (GetOpType(ea,1) == 2):#Optype is Memory Reference
return self.GetXref_String(ea,1)
elif (GetOpType(ea,1) == 4):#Base+index+Displacement
if(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 parameter
def BackForward(self,addr,n):
Reg_content = []
#addr = PrevHead(addr)
i = 0 # register number
for i in range(n):
Reg_content.append(self.get_content_register(addr,i))
return Reg_content
def Anayl_Func_Call(self, func_name, para_num):
if func_name == "":
return
#get start address
segkind = ['.text' , '.init' ,'.plt']
#startaddr = idc.SegByName('.rodata')
startaddr = MinEA()
#fun_addr = idc.LocByName(func_name)
# search the address of the pattern text
while True:
fun_addr = FindText(startaddr,SEARCH_DOWN, 0, 0, func_name)
if not (SegName(fun_addr)) in segkind:
break
startaddr = 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 = item
while ( 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] = para
return dic
def print_help():
info = 'use this as : idal64/idal -S"Anaylise_All.py \'print1 %s\'" '
print info
def main():
#test code
if (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 += 1
pos += 1
pos = 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:
continue
s += str(x[i])+' , '
sf.write(s + '\n')
sf.close()
'''
# get all names and it's addr
for x in Names():
print x
'''
idc.Exit(0)
if __name__ == '__main__':
main()
-S 表示运行ida python脚本
得到结果
In function : print4
print4 %s , 1.1.1222 ,