def getJobs(i,varstr,codestr): lib_definition=fread_handler.gen_match_str(varstr) m=re.search(lib_definition,codestr) jobs=[] if m: startpos=m.span()[1] endpos,reachend=ArgHandler.nextarg(codestr,startpos) if reachend: print "Fatal Error the fread third argument is missing.",1/0 size=codestr[startpos:endpos] varstrs=Filter.expression2vars(size) for v in varstrs: jobs.append(TaintJob(i,TaintVar(v,[]))) startpos=endpos+1 endpos,reachend=ArgHandler.nextarg(codestr,startpos) if reachend: print "Fatal Error the fread fourth argument is missing.",1/0 count=codestr[startpos:endpos] varstrs=Filter.expression2vars(count) for v in varstrs: jobs.append(TaintJob(i,TaintVar(v,[]))) startpos=endpos+1 endpos,reachend=ArgHandler.nextarg(codestr,startpos) if not reachend: print "Fatal Error the fread have 4 argument, at least five argument detected here!",1/0 fp=codestr[startpos:endpos] varstrs=Filter.expression2vars(fp) for v in varstrs: jobs.append(TaintJob(i,TaintVar(v,[]))) print "The fread is handled!" return jobs
def generate_vars(self): if self.m_fopen: start_pos = self.m_fopen.span()[1] end_pos, reachend = ArgHandler.nextarg(self.right, start_pos) if reachend: print "Fatal Error fopen() has only one argument!" 1 / 0 if re.search("\[|\+|\-(?!>)", self.right): print "Fatal Error cannot handle expression filename now!" 1 / 0 v = self.right[start_pos:end_pos].strip() return set([TaintVar(v, ["*"])])
def isUniqueNonLibCall(callstr): callstr=' '.join(callstr.split()).rstrip(';') if callstr=='':return False if callstr[0]=="(":#callstr: (struct areltdata *) _bfd_read_ar_hdr (abfd) callstr=Syntax.remove_left_type_coversion(callstr) if re.search(r"[_A-Za-z0-9]",callstr[0]) is None: return False m=re.search(Syntax.identifier+r"\s*\(",callstr) if m is None : return False if Syntax.isLibFuncName(m.group().rstrip('(')): return False start=m.span()[1] end,islast=ArgHandler.nextarg(callstr,start) while islast==False: print start,end,callstr start=end+1 end,islast=ArgHandler.nextarg(callstr,start) if end is not None and end==len(callstr)-1: return True return False
def count_va_arg_order_num(self): count=0 argptr_name=[] for i in self.indexes: if i>self.i: continue print i,"#",self.l[i] m_argptr=re.search(r'(?<![A-Za-z_0-9])va_arg\s*\(',self.l[i].codestr) if m_argptr: start_pos=m_argptr.span()[1] end_pos,reachend=ArgHandler.nextarg(self.l[i].codestr, start_pos) if reachend: print "Fatal Error! var_arg() paramlist contains only one arg!",1/0 name=self.l[i].codestr[start_pos:end_pos].strip() argptr_name.append(name) count+=1 i-=1 if len(set(argptr_name))!=1: print "Fatal Error! The first variable of var_arg() is not same!",1/0 self.argptr_name=argptr_name[0] return count
def taintUp(self,jobs): if len(jobs) ==0 :return [] P=[] paramJobs,newJobs=self.taintOneStepUp(jobs) P.extend(paramJobs) while len(newJobs)>0: paramJobs,newJobs=self.taintOneStepUp(newJobs) P.extend(paramJobs) if P==[]: return [] else: traceIndex=P[0].trace_index if traceIndex==0:return [] funcInfo=self.l[traceIndex] print "FunctionCallInfo:",funcInfo positions=self.findPositions(P,funcInfo) print "The inter point and the old line:",self.l[traceIndex] upperIndex=traceIndex-1#try to find last call site funcname=self.l[traceIndex].get_func_name().split("::")[-1].strip() if re.search(Syntax.lt+funcname+r"\s*\(",self.l[upperIndex].codestr): rightstr,upperIndex=self.normal_right_str(upperIndex, funcInfo) elif self.isMacroCall(upperIndex): rightstr=self.macro_call_right_str(upperIndex) else: print "Malformed call site! Cannot find the arglist of the call site!" print 1/0 args = ArgHandler.arglist(rightstr) cjobs=set() for pos,param in positions: print "args:",args print "pos,param:",pos,param arg=args[pos].strip() self.TG.linkInterEdges(traceIndex,upperIndex,param,arg,pos) print "arg expression:",arg identifiers=Filter.expression2vars(arg) print "variables in arg expression",identifiers #handle the 'header->index+offset' and '&op' pattern #NOTE: We let the TaintVar to help us handle variables with '&' or '->'. #It will automatically performs dereference and reference action. #FIXME: patterns like '&argv[i]' '*p' has not been handled soundly now. accessp=[e for e in param.p] if len(identifiers)==0: print "ARG:",arg print "Arg of callsite doesn't contains variable! Maybe all is constant." elif len(identifiers)==1: print 'Unique variable argument:',identifiers[0] job=TaintJob(upperIndex,TaintVar(identifiers[0],accessp)) cjobs.add(job) else: find_base_pointer=False for identifier in identifiers: if not find_base_pointer: m=re.search(identifier+r'\s*[\+\-]',arg) if m and m.span()[0]==0: job=TaintJob(upperIndex,TaintVar(identifier,accessp)) find_base_pointer=True else: m=re.search(identifier+r'\s*\[',arg) if m: job=TaintJob(upperIndex,TaintVar(identifier,['*'])) else: job=TaintJob(upperIndex,TaintVar(identifier,[])) else: m=re.search(identifier+r'\s*\[',arg) if m: job=TaintJob(upperIndex,TaintVar(identifier,['*'])) else: job=TaintJob(upperIndex,TaintVar(identifier,[])) cjobs.add(job) return cjobs