private void Handle(MethodCallEffect methodCall, ExecutionContext executionContext) { executionContext.MethodCallCount++; result.Stat.MethodCallCount++; if (methodCall.Signature == taintedCall) { if (!inputTaintedMode || methodCall.Parameters.Any(slot => slot.IsInput())) { // mark returned values as tainted // TODO: ref counter for tainted obj Debug.Assert(methodCall.OutputSlots.Count == 1, "for current tainted call this value always 1. Need to test other cases."); for (var i = 0; i < methodCall.OutputSlots.Count; i++) { var(id, backwardCallStack) = result.AddTaintedMethodCall(methodCall.Signature, CallStack); methodCall.OutputSlots[i].MarkTaint(id, backwardCallStack); } } else if (inputTaintedMode) { for (int i = 0; i < methodCall.Parameters.Length; i++) { var parameter = methodCall.Parameters[i]; parameter.AddSinkMethod(executionContext.Signature, CallStack, methodCall.OutputSlots); } } result.Stat.IgnoredTargetMethodCalls++; return; } var isAnalyzing = IsAnalyzingNeeded(methodCall); AddTargetMethodIfNeeded(methodCall, isAnalyzing); if (!isAnalyzing) { return; } var summary = GetOrCreateSummary(methodCall); executionContext.Apply(summary, methodCall.Parameters, result, ReturnValueApplyingMode.Replace, Indent()); }
private void BuildExecutionContext(ExecutionContext executionContext, MethodCall method) { var methodDef = method.Definition; var interpreter = new Interpreter(executionContext, methodDef); //var interpreter = new TraceInterpreter(method); foreach (var effect in interpreter.EnumerateEffects()) { switch (effect) { case CtorCallEffect ctorCall: if (ctorCall.Definition != null) { // can be null for array creating instructions, e.g., JavaScriptSerializer // System.Web.Configuration.HealthMonitoringSectionHelper::.ctor() // IL_00A5: newobj System.Void System.Collections.ArrayList[0...,0...]::.ctor(System.Int32,System.Int32) Debug.Assert(!ctorCall.Definition.DeclaringType.IsAbstract); Debug.Assert(!ctorCall.Definition.DeclaringType.IsInterface); RegisterType(ctorCall.Definition.DeclaringType); } Handle(ctorCall, executionContext); break; case MethodCallEffect methodCall: // if (method.Definition.Name == "ParseDictionary") // { // int tt = 777; // } if (methodCall.CallKind == CallKind.Virtual) { //RegisterVirtualCall(methodCall.Signature, method.Signature); } Handle(methodCall, executionContext); break; } } }
private protected override Summary Analyze(MethodCall methodCall) { Debug.Assert(methodCall.CallKind == CallKind.Concrete || methodCall.Parameters != null); if (methodCall.CallKind == CallKind.Concrete) { Debug.Assert(methodCall.Definition.HasBody); result.Stat.AnalyzedConcreteMethodCount++; result.Stat.AnalyzedDifferentConcreteMethods.Add(methodCall.Signature.ToString()); result.Stat.InstructionCount += (ulong)methodCall.Definition.Body.Instructions.Count; var context = new ExecutionContext( CallStack, methodCall.Signature, methodCall.Definition, enableStaticFields, firstExecutionContextCreating); if (firstExecutionContextCreating) { firstExecutionContextCreating = false; } result.Stat.StartMethodAnalyzing(methodCall.Signature.ToString()); BuildExecutionContext(context, methodCall); result.Stat.StopMethodAnalyzing(methodCall.Signature.ToString()); return(context.ToSummary()); } else { // emulate virtual call // TODO: optimize virtual call w/o implMethods? result.Stat.AnalyzedVirtualMethodCount++; result.Stat.AnalyzedDifferentVirtualMethods.Add(methodCall.Signature.ToString()); var context = new ExecutionContext( CallStack, methodCall.Signature, methodCall.Definition, enableStaticFields, firstExecutionContextCreating); if (firstExecutionContextCreating) { firstExecutionContextCreating = false; } if (methodCall.Definition.HasReturnType) { context.Frame.Push( new SymbolicSlot( new SymbolicReference( new MethodReturnSource(methodCall.Definition)))); } var mode = ReturnValueApplyingMode.Replace; // execute this one and all overriden methods that have body if (methodCall.Definition.HasBody) { var summary = GetOrCreateSummary(new MethodCall( methodCall.Signature, methodCall.Definition, null, CallKind.Concrete)); result.Stat.EmulatedMethodCallCount++; context.Apply(summary, context.Arguments.Slots, result, mode, Indent()); mode = ReturnValueApplyingMode.Merge; } var types = GetRegisteredTypes(methodCall.Definition.DeclaringType.ScopeType.ToString()); var implementations = types.Count == 0 ? indexDb.GetImplementations(methodCall.Signature, entryPointAssemblyName) : indexDb.GetImplementations(methodCall.Signature, types); foreach (var methodDef in implementations) { var summary = GetOrCreateSummary(new MethodCall( methodDef.CreateMethodUniqueSignature(), methodDef, null, CallKind.Concrete)); result.Stat.EmulatedMethodCallCount++; context.Apply(summary, context.Arguments.Slots, result, mode, Indent()); mode = ReturnValueApplyingMode.Merge; } if (mode == ReturnValueApplyingMode.Replace) { Debug.Fail("We must call Analyze() only if we have at least one implementation!"); return(Summary.Empty); } // emulate ret opcode if (methodCall.Definition.HasReturnType) { var value = context.Frame.Pop(); if (!Interpreter.IsSimple(methodCall.Definition.ReturnType) && !value.IsConstAfterSimplification()) { context.AddReturnValue(value); } } return(context.ToSummary()); } }