Exemplo n.º 1
0
        public override void LeaveMethod()
        {
            if (!bStartMonitoring)
            {
                return;
            }

            if (this.methodStack.Count == 0)
            {
                return;
            }

            var poppedMethod = this.methodStack.Pop();

            this.currOffset = this.offsetStack.Pop();

            var previousLoadedFields = this.lastLoadedFieldsStack.Pop();

            //If the last method call is a getter, add the field just loaded by that getter method
            //Or any other remaining loaded fields
            if (poppedMethod.ShortName.StartsWith("get_"))
            {
                Field usedField;
                int   foffset;
                if (DeclEntityCollector.TryGetFieldOfGetter(poppedMethod, out usedField, out foffset))
                {
                    previousLoadedFields.AddRange(usedField);
                }
            }
            this.lastLoadedFields.Clear();
            this.lastLoadedFields.AddRange(previousLoadedFields);

            //Updating the defined and used field list
            if (this.methodStoreStack.Count > 0)
            {
                ses.AppendMethodStore(currSEMethodStore);
                var poppedStore = this.methodStoreStack.Pop();
                if (!poppedMethod.ShortName.StartsWith("get_"))
                {
                    //Do not propogate for getter methods
                    PropagateModificationsToCaller(poppedStore, currSEMethodStore, poppedMethod);
                }
                poppedStore.AppendMethodStore(currSEMethodStore, this.currOffset);
                currSEMethodStore = poppedStore;
            }

            if (poppedMethod.ShortName.Equals("Main") || poppedMethod.ShortName.Equals("DUCoverTerminate"))
            {
                ses.DumpToDatabase();
                bStartMonitoring = false;
            }
        }
Exemplo n.º 2
0
        public override EnterMethodFlags EnterMethod(Method method)
        {
            //Console.WriteLine(method.FullName);

            if (this.methodStack.Count == 0 && !bStartMonitoring)
            {
                var assemblyShortname = method.Definition.Module.Assembly.ShortName;
                if (assemblyShortname == this.currentAssemblyLoc)
                {
                    //Whereever the main method, it is the assembly under analysis,
                    //since our tool assumes that there is only one assembly
                    var assembly = method.Definition.Module.Assembly;
                    ses.CurrAssembly = assembly;
                    bStartMonitoring = true;
                }
            }

            if (bStartMonitoring)
            {
                this.methodStack.Push(method);

                if (currSEMethodStore != null)
                {
                    this.methodStoreStack.Push(currSEMethodStore);
                }
                currSEMethodStore = new SEMethodStore(method.FullName);
                currSEMethodStore.OptionalMethod = method;

                var tempLastLoadedFields = new SafeList <Field>();
                tempLastLoadedFields.AddRange(lastLoadedFields);
                this.lastLoadedFieldsStack.Push(tempLastLoadedFields);
                this.lastLoadedFields.Clear();

                this.offsetStack.Push(this.currOffset);
            }

            return(base.EnterMethod(method)); // 'true' indicates that we want callbacks for the argument values
        }
Exemplo n.º 3
0
        /// <summary>
        /// Propagates the changes made by a called method to its caller, based on the lastLoadedFields
        /// For example, if the called method modifies any fields, then the related parent fields in the caller method
        /// are marked as updated
        /// </summary>
        /// <param name="callerMStore"></param>
        /// <param name="calledMethodStore"></param>
        private void PropagateModificationsToCaller(SEMethodStore callerMStore, SEMethodStore calledMethodStore, Method calledMethod)
        {
            if (this.lastLoadedFields.Count == 0)
            {
                return;
            }

            //Idenitfy relevant fields from the last loadedFields
            SafeList <Field> fieldsProcessed = new SafeList <Field>();
            Field            receiverField   = null;

            //Check whether the current method call is actually on the field previously loaded
            TypeEx methodDeclType;

            if (!calledMethod.TryGetDeclaringType(out methodDeclType))
            {
                logger.Error("Failed to get the declaring type of the method: " + calledMethod.FullName);
                return;
            }

            if (methodDeclType.FullName == "System.String" || methodDeclType.FullName == "System.string")
            {
                return; //Do not process string types.
            }

            //Check whether the declaring type is in the fields list
            foreach (var field in this.lastLoadedFields)
            {
                var fieldType = field.Type;
                if (fieldType == methodDeclType || fieldType.IsAssignableTo(methodDeclType) || methodDeclType.IsAssignableTo(fieldType))
                {
                    fieldsProcessed.Add(field);
                    receiverField = field;
                    break;
                }
            }

            if (receiverField == null)
            {
                //Failed to identify the reciver field of this method
                return;
            }

            //Identify arguments of the current method call
            foreach (var argtype in calledMethod.ParameterTypes)
            {
                foreach (var field in this.lastLoadedFields)
                {
                    if (field == receiverField)
                    {
                        continue;
                    }

                    var fieldType = field.Type;
                    if (fieldType == argtype || fieldType.IsAssignableTo(argtype) || argtype.IsAssignableTo(fieldType))
                    {
                        fieldsProcessed.Add(field);
                        break;
                    }
                }
            }

            if (calledMethodStore.DefinedFieldSet.Count == 0)
            {
                //If the called method does not define any field, all current fields are just loaded fields
                foreach (var field in fieldsProcessed)
                {
                    callerMStore.AddToUsedList(field, this.currOffset);
                    this.lastLoadedFields.Remove(field);
                }
            }
            else
            {
                //process each defined field
                foreach (var deffield in calledMethodStore.DefinedFieldSet.Values)
                {
                    TypeEx deffieldType;
                    if (deffield.OptionalField.TryGetDeclaringType(out deffieldType))
                    {
                        //Identify the related field in the lastLoadedFields
                        Field processedField = null;
                        foreach (var field in fieldsProcessed)
                        {
                            var fieldType = field.Type;
                            if (fieldType == deffieldType || fieldType.IsAssignableTo(deffieldType) || deffieldType.IsAssignableTo(fieldType))
                            {
                                processedField = field;
                                callerMStore.AddToDefinedList(field, this.currOffset);
                                break;
                            }
                        }

                        if (processedField != null)
                        {
                            fieldsProcessed.Remove(processedField);
                            this.lastLoadedFields.Remove(processedField);
                        }
                    }
                }

                //Consider the remaining fields at usedfields and remove them from lastLoadedFields
                foreach (var field in fieldsProcessed)
                {
                    callerMStore.AddToUsedList(field, this.currOffset);
                    this.lastLoadedFields.Remove(field);
                }
            }
        }