Example #1
0
        public bool PerformComparison(MethodDef method, bool preserveOrder = true, bool allowOtherInstruction = false)
        {
            int groupIndex = 0;

            for (var i = 0; i < method.GetInstructions().Count; ++i)
            {
                var instruction = method.Body.Instructions[i];
                if (InstructionGroups.Count <= groupIndex && !allowOtherInstruction)
                {
                    return(false);
                }
                else if (InstructionGroups.Count <= groupIndex)
                {
                    break;
                }

                bool hasLimit = InstructionGroups[groupIndex].HowMany.HasValue;
                int  limit    = InstructionGroups[groupIndex].HowMany.GetValueOrDefault();

                //At this moment this algorithm doesn't manage:
                // unrecognized -> optional -> non optional
                //But only:
                // optional -> unrecognized -> non optional
                //(Not planning to add this use case, though)
                bool isRecognized = InstructionGroups[groupIndex].RecognizedInstructions.Contains(instruction.OpCode);

                while (!isRecognized && ((InstructionGroups[groupIndex].IsOptional) ||
                                         (hasLimit && InstructionGroups[groupIndex].FoundInstructions.Count == limit) ||
                                         (!hasLimit && InstructionGroups[groupIndex].FoundInstructions.Count > 0)))
                {
                    //If you're here:
                    // Either you're skipping a not found, optional instruction,
                    // or you're skipping a group of instruction you've already matched in a
                    // previous iteration.
                    groupIndex++;
                    isRecognized = InstructionGroups[groupIndex].RecognizedInstructions.Contains(instruction.OpCode);
                }

                //If you're here:
                // Not optional, found
                // Not optional, not found
                // Optional, found
                if (isRecognized)
                {
                    InstructionGroups[groupIndex].FoundInstructions.Add(i);
                }
                else if (allowOtherInstruction)
                {
                    continue;
                }
                else if (!InstructionGroups[groupIndex].IsOptional)
                {
                    return(false);
                }
            }

            foreach (var group in instructionGroups)
            {
                if (!group.HowMany.HasValue)
                {
                    if (!group.IsOptional && group.FoundInstructions.Count == 0)
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!group.IsOptional && group.FoundInstructions.Count != group.HowMany.Value)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }