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 vars_in_pointer_offset_style(expstr): m=re.search(r'\+|(\-(?!>))',expstr) if m: first_op=m.span()[0]#first + or - operation for case: 'psf->header+psf->headerindex' former_vars=Filter.expression2vars(expstr[:first_op]) follow_vars=Filter.expression2vars(expstr[first_op+1:]) return former_vars,follow_vars else: former_vars=[''.join(expstr.split())] return former_vars,None
def generate_candidate_vars(self): if self.m_cond_exp: #FIX ME: #CAN HANDLE: int i,m=t->len>10?10:t->len; #CANNOT HANDLE: m=q+((t->len>10?10:t->len)?a:b); array=self.right.split('?')[1].split(':') choice1=Filter.expression2vars(array[0]) choice2=Filter.expression2vars(array[1]) symbols=choice1+choice2 return symbols
def getJobs(index,varstr,codestr): syscall_definition=memcpy_handler.gen_match_str(varstr) m=re.search(syscall_definition,codestr) start_pos=m.span()[1] end_pos,islast=ArgHandler.nextarg(codestr,start_pos) if end_pos is None: print "Error! memcpy second arg wrong!" x=1/0 elif islast: print "Error! memcpy third arg missing!" x=1/0 former_vars,follow_vars=ArgHandler.vars_in_pointer_offset_style(codestr[start_pos:end_pos]) jobs=[] jobs.append(TaintJob(index,TaintVar(former_vars[0],['*']))) if follow_vars: for v in follow_vars: jobs.append(TaintJob(index,TaintVar(v,[]))) start_pos=end_pos+1 end_pos,islast=ArgHandler.nextarg(codestr,start_pos) if end_pos is None or not islast: print "Error! memcpy third arg wrong!" x=1/0 vs=Filter.expression2vars(codestr[start_pos:end_pos]) for v in vs: jobs.append(TaintJob(index,TaintVar(v,[]))) return jobs
def handleReturnAssgin(self,job_trace_index,i,accesspattern,var): if i+2+1<len(self.l) and isinstance(self.l[i+1],FunctionCallInfo) and isinstance(self.l[i+2],LineOfCode): if self.l[i+1].get_func_name().split("::")[-1].strip() in self.l[i].codestr or self.isMacroCall(i): indexes=self.slice_same_func_lines(i+2, job_trace_index) count=0 print "accesspattern:",accesspattern for idx in indexes[::-1]: print "Line Under Check:", aIndex, "#",self.l[aIndex] if 'return ' in self.l[idx].codestr: self.TG.linkExpandEdges(job_trace_index,idx,"return dependency:"+var.simple_access_str()) #self.TG.linkTraverseEdges(i,idx,"ref:"+var.simple_access_str()) start=re.search(r'return\s*',self.l[idx].codestr).span()[1] rightpart=self.l[idx].codestr[start:].strip().rstrip(';').strip() if Syntax.isUniqueNonLibCall(rightpart): jobs=self.handleReturnAssgin(job_trace_index,idx,accesspattern,var) return self.taintUp(jobs) else: variable_pat=re.compile('^'+Syntax.variable+'$') m=variable_pat.match(rightpart) if m: rfl,p=accesspattern return self.taintUp([TaintJob(idx,TaintVar(rightpart,p,rfl))]) else: taint_v_strs = Filter.expression2vars(rightpart) jobs=map(lambda x : TaintJob(idx,x),[TaintVar(tv,[]) for tv in taint_v_strs]) return self.taintUp(jobs) count+=1 if count == 3:break return [] print "Fatal Error! the malformed call detail lines after return value assignment!" print 1/0
def getJobs(index,varstr,codestr): syscall_definition=sscanf_handler.gen_match_str(varstr) m0=re.search(syscall_definition,codestr) sscanf_str=m0.group() start_pos=re.search("sscanf\s*\(",sscanf_str).span()[1] end_pos,islast=ArgHandler.nextarg(sscanf_str,start_pos) if end_pos is None: print "Error! sscanf second arg wrong!" x=1/0 elif islast: print "Error! sscanf format string arg missing!" x=1/0 former_vars,follow_vars=ArgHandler.vars_in_pointer_offset_style(sscanf_str[start_pos:end_pos]) jobs=[] jobs.append(TaintJob(index,TaintVar(former_vars[0],['*']))) if follow_vars: for v in follow_vars: jobs.append(TaintJob(index,TaintVar(v,[]))) start_pos=end_pos+1 end_pos,islast=ArgHandler.nextarg(sscanf_str,start_pos) if end_pos is None or islast: print "Error! format string wrong or third arg missing !" x=1/0 vs=Filter.expression2vars(sscanf_str[start_pos:end_pos]) for v in vs: jobs.append(TaintJob(index,TaintVar(v,[]))) return jobs
def getJobs(self, var, index,sliced_indexes): line =self.l[index] codestr=line.codestr str_pat=var.accessStr()+r"\s*(\[[^\[\]]+\])*\s*[\+\-\*/%&\|]?\s*=(?!=)" print "CHECKING CODE:",codestr m=re.search(str_pat,codestr) if m: span=m.span() left=m.group() i=0 while re.search(r"[A-Za-z0-9_\.\*\->\s]",left[i]): i+=1 name="".join(left[:i].split()) rfl,pp=var.matchAccessPattern(name) right=codestr[span[1]:] right=right.split(';')[0].strip() #strip out ";" va_arg_handler=Va_argHandler(right,pp, rfl, index, sliced_indexes, self.l, self.TG) fopen_handler=FopenHandler(right) type_conv=TypeConvertHandler(right,pp,rfl) cond_exp=ConditionalExpressionHandler(right,pp,rfl) if Syntax.isVariable(right): if pp is None: print "Fatal Error!!!",1/0 return None else: print pp return [TaintJob(index,TaintVar(right, pp, rfl))] elif va_arg_handler.match(): return va_arg_handler.generate_jobs() elif fopen_handler.match(): taintvars= fopen_handler.generate_vars() jobs=map(lambda x : TaintJob(index, x), taintvars) return jobs elif cond_exp.match(): symbols=cond_exp.generate_candidate_vars() elif type_conv.match(): symbols=type_conv.generate_candidate_vars() else: symbols=Filter.expression2vars(right) print symbols varstrs=Filter.filterOutFuncNames(symbols,line.codestr) print "Right variables in assignment:",varstrs taintvars=set(map(lambda x : TaintVar(x, []), varstrs)) jobs=map(lambda x : TaintJob(index, x), taintvars) return jobs
def vars_in_for_init_part(v_access,init_str): init_str=' '.join(init_str.split()) inits=init_str.split(',') for init in inits: match_init= re.search(v_access+Syntax.assign,init) if match_init: left_var=match_init.group().rstrip("=") rightstr=init[match_init.span()[1]:] right_var_strs_in_init=Filter.expression2vars(rightstr) return left_var,right_var_strs_in_init return None
def vars_in_for_change_part(v_access,change_str): change_str=''.join(change_str.split()) changes=change_str.split(',') for change in changes: #inc find_inc=Syntax.isIncDef(v_access,change) if find_inc: return [] #assignment #=================================================================== # find_assign=re.search(v_access+Syntax.assign, change) # if find_assign: # rightvars=Filter.expression2vars(change[find_assign.span()[1]:]) # return rightvars #=================================================================== #op_assignment find_op_assign=re.search(Syntax.op_assignment_pattern(v_access), change) if find_op_assign: rightvars=Filter.expression2vars(change[find_op_assign.span()[1]:]) return rightvars return None
def getJobs(index,varstr,codestr): syscall_definition=memset_handler.gen_match_str(varstr) m=re.search(syscall_definition,codestr) start_pos=m.span()[1] end_pos,islast=ArgHandler.nextarg(codestr,start_pos) if end_pos is None: print "Error! memset second arg wrong!" x=1/0 elif islast: print "Error! memset third arg missing!" x=1/0 start_pos=end_pos+1 end_pos,islast=ArgHandler.nextarg(codestr,start_pos) if end_pos is None or not islast : print "Error! memset third arg wrong!" x=1/0 third_param=codestr[start_pos:end_pos] vs=Filter.expression2vars(third_param) jobs=[] for v in vs: jobs.append(TaintJob(index,TaintVar(v,[]))) print "handle memset! new job var:",v,[] return jobs
def generate_for_jobs(num,codestr,v): v_access=v.accessStr() init,cond,change=Syntax.split_for(codestr) #right vars in init part right_vars_in_change=Syntax.vars_in_for_change_part(v_access,change) #bound vars in cond part bound_var_strs=[] if right_vars_in_change is not None: bound_var_strs=Filter.expression2vars(cond) bound_var_strs=[bv for bv in bound_var_strs if re.search(bv+r"\s*"+Syntax.assign,init) is None]; #right vars in change part init_vars=Syntax.vars_in_for_init_part(v_access,init) right_var_strs_in_init=[] if init_vars is not None: left_var,right_var_strs_in_init=init_vars if right_vars_in_change is not None and left_var in bound_var_strs: bound_var_strs.remove(left_var) taint_vars=map(lambda x: TaintVar(x,[]),right_var_strs_in_init+bound_var_strs)#+right_vars_in_change) Now we discard right increvalue because it's usually a fix value. if init_vars is None and right_vars_in_change is not None: taint_vars.append(v) for t_v in taint_vars: print 'Taint Vars found in FOR STATEMENT:',t_v jobs=map(lambda x:TaintJob(num,x),set(taint_vars)) return list(set(jobs))
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