예제 #1
0
        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());
        }
예제 #2
0
        private bool IsAnalyzingNeeded(MethodCallEffect methodCall)
        {
            // probably we can cache 'empty' (with Input marks if needed) summary for non-analyzing cases
            // to improve performance (need to benchmark it)
            if (methodCall.Definition == null)
            {
                DebugLog($"{Indent()}{methodCall.Signature}: MethodDefinition == null");
                MarkOutputSlotsAsInput(methodCall);
                result.Stat.IgnoredNotImplementedMethodCalls++;
                return(false);
            }

            if (methodCall.CallKind == CallKind.Concrete && !methodCall.Definition.HasBody)
            {
                DebugLog($"{Indent()}{methodCall.Signature}: no body");
                MarkOutputSlotsAsInput(methodCall);
                if (methodCall.Definition.HasReturnType)
                {
                    var returnType = methodCall.Definition.ReturnType.TryGetTypeDef();
                    if (returnType != null)
                    {
                        // register types from external methods and delegates
                        RegisterType(returnType);
                    }
                }

                result.Stat.IgnoredNotImplementedMethodCalls++;
                return(false);
            }

            if (methodCall.CallKind == CallKind.Virtual)
            {
                int implMethodsCount;
                var registeredTypes = GetRegisteredTypes(methodCall.Definition.DeclaringType.ScopeType.ToString());
                if (registeredTypes.Count == 0)
                {
                    DebugLog($"{Indent()}{methodCall.Signature}: no created types");
                    //Console.WriteLine($"{methodCall.Signature}: no created types");
                    MarkOutputSlotsAsInput(methodCall);
                    result.Stat.IgnoredNotImplementedMethodCalls++;    // TODO: use another stat counter
                    return(false);

                    implMethodsCount = indexDb.GetImplementationsCount(methodCall.Signature); //, entryPointAssemblyName);
                }
                else
                {
                    implMethodsCount = indexDb.GetImplementationsCount(methodCall.Signature, registeredTypes);
                }

                if (!methodCall.Definition.HasBody && implMethodsCount == 0)
                {
                    DebugLog($"{Indent()}{methodCall.Signature}: no any implementation");
                    //Console.WriteLine($"{Indent()}{methodCall.Signature}: no any implementation");
                    MarkOutputSlotsAsInput(methodCall);
                    result.Stat.IgnoredNotImplementedMethodCalls++;
                    return(false);
                }

                if (implMethodsCount > virtualCallsLimit) //|| (registeredTypes.Count == 0 && implMethodsCount > 4))
                {
                    // TODO: need to propagate tainted value as well?
                    //Console.WriteLine($"{methodCall.Signature}: too much implementations ({implMethodsCount})");
                    MarkOutputSlotsAsInput(methodCall);
                    result.Stat.IgnoredVirtualMethodCallsByLimit++;
                    result.Stat.IgnoredVirtualMethodsByLimit.Add(methodCall.Signature.ToString());
                    return(false);
                }
            }

            if (indexDb.SkippedModules.Contains(methodCall.Definition.Module.FullName))
            {
                Console.WriteLine($"{methodCall.Signature}: in the skipped modules");
                MarkOutputSlotsAsInput(methodCall);
                result.Stat.IgnoredNotImplementedMethodCalls++;
                return(false);
            }

            return(true);
        }
예제 #3
0
        private void AddTargetMethodIfNeeded(MethodCallEffect methodCall, bool isAnalyzing)
        {
            if (methodCall.Parameters.Length == 0)
            {
                return;
            }

            ///////////////////////////////////////////////////////
            // TODO: ADD support for Delegate Invoke() call

/*
 *          if ((methodCall.IsVirtual && methodCall.Definition.IsVirtual) ||
 *              (methodCall.Definition == null || !methodCall.Definition.HasBody
 ||methodCall.Definition.Name == "SideEffect") &&
 *                   list.IsValid(methodCall.Signature))
 *          {
 *              for (int i = 0; i < methodCall.Parameters.Length; i++)
 *              {
 *                  var parameter = methodCall.Parameters[i];
 *                  parameter.AddTargetMethod(methodCall.Signature, result);
 *              }
 *          }
 *
 *          return;
 */
            ///////////////////////////////////////////////////////

            if (!isAnalyzing)
            {
                AddTargetMethodForAllParameters(methodCall);
            }
            else if (methodCall.Definition != null &&
                     methodCall.CallKind == CallKind.Virtual && methodCall.Definition.IsVirtual)
            {
                var implMethodsCount = indexDb.GetImplementationsCount(methodCall.Signature, entryPointAssemblyName);

                // add target methods only if we have several implementation
                if ((methodCall.Definition.HasBody && implMethodsCount > 0) ||
                    (!methodCall.Definition.HasBody && implMethodsCount > 1))
                {
                    methodCall.Parameters[0].AddTargetMethod(methodCall.Signature, CallStack, result);
                }
            }
            else if (methodCall.Definition == null || !methodCall.Definition.HasBody ||
                     methodCall.Definition.Name == "SideEffect")
            {
                AddTargetMethodForAllParameters(methodCall);
            }

            void AddTargetMethodForAllParameters(MethodCallEffect methodCallEffect)
            {
                if (list.IsValid(methodCallEffect.Signature))
                {
                    // TODO: need to exclude 'out' params, but leave 'ref'
                    for (int i = 0; i < methodCallEffect.Parameters.Length; i++)
                    {
                        var parameter = methodCallEffect.Parameters[i];
                        parameter.AddTargetMethod(methodCallEffect.Signature, CallStack, result);
                    }
                }
            }
        }