public AnalyzedFieldAccessTreeNode(FieldDef analyzedField, bool showWrites) {
			if (analyzedField == null)
				throw new ArgumentNullException("analyzedField");

			this.analyzedField = analyzedField;
			this.showWrites = showWrites;
		}
Exemplo n.º 2
0
		public AnalyzedFieldTreeNode(FieldDef analyzedField)
		{
			if (analyzedField == null)
				throw new ArgumentNullException("analyzedField");
			this.analyzedField = analyzedField;
			this.LazyLoading = true;
		}
Exemplo n.º 3
0
		public FieldAccessNode(FieldDef analyzedField, bool showWrites) {
			if (analyzedField == null)
				throw new ArgumentNullException(nameof(analyzedField));

			this.analyzedField = analyzedField;
			this.showWrites = showWrites;
		}
Exemplo n.º 4
0
		static MemberIcon GetMemberIcon(FieldDef field)
		{
			var access = GetMemberAccess(field);

			if (field.DeclaringType.IsEnum && !field.IsSpecialName) {
				switch (access) {
				case MemberAccess.Public: return MemberIcon.EnumValue;
				case MemberAccess.Private: return MemberIcon.EnumValuePrivate;
				case MemberAccess.Protected: return MemberIcon.EnumValueProtected;
				case MemberAccess.Internal: return MemberIcon.EnumValueInternal;
				case MemberAccess.CompilerControlled: return MemberIcon.EnumValueCompilerControlled;
				case MemberAccess.ProtectedInternal: return MemberIcon.EnumValueProtectedInternal;
				default:
					Debug.Fail("Invalid MemberAccess");
					goto case MemberAccess.Public;
				}
			}

			if (field.IsLiteral || (field.IsInitOnly && IsDecimalConstant(field))) {
				switch (access) {
				case MemberAccess.Public: return MemberIcon.Literal;
				case MemberAccess.Private: return MemberIcon.LiteralPrivate;
				case MemberAccess.Protected: return MemberIcon.LiteralProtected;
				case MemberAccess.Internal: return MemberIcon.LiteralInternal;
				case MemberAccess.CompilerControlled: return MemberIcon.LiteralCompilerControlled;
				case MemberAccess.ProtectedInternal: return MemberIcon.LiteralProtectedInternal;
				default:
					Debug.Fail("Invalid MemberAccess");
					goto case MemberAccess.Public;
				}
			}
			else if (field.IsInitOnly) {
				switch (access) {
				case MemberAccess.Public: return MemberIcon.FieldReadOnly;
				case MemberAccess.Private: return MemberIcon.FieldReadOnlyPrivate;
				case MemberAccess.Protected: return MemberIcon.FieldReadOnlyProtected;
				case MemberAccess.Internal: return MemberIcon.FieldReadOnlyInternal;
				case MemberAccess.CompilerControlled: return MemberIcon.FieldReadOnlyCompilerControlled;
				case MemberAccess.ProtectedInternal: return MemberIcon.FieldReadOnlyProtectedInternal;
				default:
					Debug.Fail("Invalid MemberAccess");
					goto case MemberAccess.Public;
				}
			}
			else {
				switch (access) {
				case MemberAccess.Public: return MemberIcon.Field;
				case MemberAccess.Private: return MemberIcon.FieldPrivate;
				case MemberAccess.Protected: return MemberIcon.FieldProtected;
				case MemberAccess.Internal: return MemberIcon.FieldInternal;
				case MemberAccess.CompilerControlled: return MemberIcon.FieldCompilerControlled;
				case MemberAccess.ProtectedInternal: return MemberIcon.FieldProtectedInternal;
				default:
					Debug.Fail("Invalid MemberAccess");
					goto case MemberAccess.Public;
				}
			}
		}
Exemplo n.º 5
0
		public static ITextOutput Write(ITextOutput output, FieldDef field, Language language) {
			output.Write(UIUtils.CleanUpIdentifier(field.Name), TextTokenHelper.GetTextTokenType(field));
			output.WriteSpace();
			output.Write(':', TextTokenType.Operator);
			output.WriteSpace();
			language.TypeToString(output, field.FieldType.ToTypeDefOrRef(), false, field);
			field.MDToken.WriteSuffixString(output);
			return output;
		}
        public AnalyzedEventFiredByTreeNode(EventDef analyzedEvent)
        {
            if (analyzedEvent == null)
                throw new ArgumentNullException("analyzedEvent");

            this.analyzedEvent = analyzedEvent;

            this.eventBackingField = GetBackingField(analyzedEvent);
            this.eventFiringMethod = analyzedEvent.EventType.ResolveTypeDef().Methods.First(md => md.Name == "Invoke");
        }
Exemplo n.º 7
0
		public EventFiredByNode(EventDef analyzedEvent) {
			if (analyzedEvent == null)
				throw new ArgumentNullException(nameof(analyzedEvent));

			this.analyzedEvent = analyzedEvent;

			eventBackingField = GetBackingField(analyzedEvent);
			var eventType = analyzedEvent.EventType.ResolveTypeDef();
			if (eventType != null)
				eventFiringMethod = eventType.Methods.First(md => md.Name == "Invoke");
		}
Exemplo n.º 8
0
		public FieldDefOptions(FieldDef field) {
			this.Attributes = field.Attributes;
			this.Name = field.Name;
			this.FieldSig = field.FieldSig;
			this.FieldOffset = field.FieldOffset;
			this.MarshalType = field.MarshalType;
			this.RVA = field.RVA;
			this.InitialValue = field.InitialValue;
			this.ImplMap = field.ImplMap;
			this.Constant = field.Constant;
			this.CustomAttributes.AddRange(field.CustomAttributes);
		}
Exemplo n.º 9
0
		public FieldDefOptions(FieldDef field) {
			Attributes = field.Attributes;
			Name = field.Name;
			FieldSig = field.FieldSig;
			FieldOffset = field.FieldOffset;
			MarshalType = field.MarshalType;
			RVA = field.RVA;
			InitialValue = field.InitialValue;
			ImplMap = field.ImplMap;
			Constant = field.Constant;
			CustomAttributes.AddRange(field.CustomAttributes);
		}
Exemplo n.º 10
0
		public FieldDef CopyTo(FieldDef field) {
			field.Attributes = this.Attributes;
			field.Name = this.Name ?? UTF8String.Empty;
			field.FieldSig = this.FieldSig;
			field.FieldOffset = this.FieldOffset;
			field.MarshalType = this.MarshalType;
			field.RVA = this.RVA;
			field.InitialValue = this.InitialValue;
			field.ImplMap = this.ImplMap;
			field.Constant = this.Constant;
			field.CustomAttributes.Clear();
			field.CustomAttributes.AddRange(CustomAttributes);
			return field;
		}
Exemplo n.º 11
0
		protected override void GetCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
			var name = field.Name.String;
			callOpcode = OpCodes.Call;
			if (name.EndsWith("%", StringComparison.Ordinal)) {
				callOpcode = OpCodes.Callvirt;
				name = name.TrimEnd(new char[] { '%' });
			}
			byte[] value = Convert.FromBase64String(name);
			int methodIndex = BitConverter.ToInt32(value, 0);	// 0-based memberRef index
			var mr = module.ResolveMemberRef((uint)methodIndex + 1);
			if (mr == null || !mr.IsMethodRef)
				throw new ApplicationException(string.Format("Invalid MemberRef index: {0}", methodIndex));
			calledMethod = mr;
		}
Exemplo n.º 12
0
        public static void Execute(ModuleDefMD module)
        {
            cctor = module.GlobalType.FindStaticConstructor();
            Dictionary<FieldDef, Tuple<byte[], int>> fields = new Dictionary<FieldDef,Tuple<byte[], int>>();
            List<byte> data = new List<byte>();
            int count = 0;
            foreach (var method in  module.GetTypes().SelectMany(type => type.Methods))
            {
                if (method.HasBody)
                {
                    List<Instruction> stringInstr = method.Body.Instructions.Where(instr => instr.OpCode == OpCodes.Ldstr).ToList();
                    for (int i = 0; i < stringInstr.Count; i++)
                    {
                        byte[] stringByte = Encoding.UTF8.GetBytes(stringInstr[i].Operand as string);
                        data.AddRange(stringByte);
                        FieldDef field = CreateField(module);
                        fields.Add(field, Tuple.Create(stringByte, count));
                        method.DeclaringType.Fields.Add(field);
                        stringInstr[i].OpCode = OpCodes.Ldsfld;
                        stringInstr[i].Operand = field;
                        count++;
                    }
                }
            }
            staticFields = fields;
            data = Encrypt(data.ToArray()).ToList();
            var dataType = new TypeDefUser("", "", module.CorLibTypes.GetTypeRef("System", "ValueType"));
            RenameTask.Rename(dataType);
            dataType.Layout = TypeAttributes.ExplicitLayout;
            dataType.Visibility = TypeAttributes.NestedPrivate;
            dataType.IsSealed = true;
            dataType.ClassLayout = new ClassLayoutUser(1, (uint)data.Count);
            module.GlobalType.NestedTypes.Add(dataType);

            var dataField = new FieldDefUser("", new FieldSig(dataType.ToTypeSig()))
            {
                IsStatic = true,
                HasFieldRVA = true,
                InitialValue = data.ToArray(),
                Access = FieldAttributes.CompilerControlled
            };
            module.GlobalType.Fields.Add(dataField);
            GlobalDataField = dataField;
            RenameTask.Rename(dataField);
            NETUtils.listener.OnWriterEvent += OnWriterEvent;
        }
Exemplo n.º 13
0
		protected override void GetCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
			var ctx = (Context)context;

			switch (ctx.proxyCreatorType) {
			case ProxyCreatorType.CallOrCallvirt:
				callOpcode = field.IsFamilyOrAssembly ? OpCodes.Callvirt : OpCodes.Call;
				break;
			case ProxyCreatorType.CallCtor:
				callOpcode = OpCodes.Call;
				break;
			case ProxyCreatorType.Newobj:
				callOpcode = OpCodes.Newobj;
				break;
			default:
				throw new ApplicationException(string.Format("Invalid proxy creator type: {0}", ctx.proxyCreatorType));
			}

			calledMethod = module.ResolveToken(ctx.methodToken) as IMethod;
		}
		void Find() {
			foreach (var type in module.Types) {
				if (type.HasEvents || type.HasProperties)
					continue;
				if (type.Methods.Count != 1)
					continue;
				if (type.Fields.Count != 1)
					continue;
				var method = type.Methods[0];
				if (method.Name != ".ctor")
					continue;
				var field = type.Fields[0];
				var fieldType = DotNetUtils.GetType(module, field.FieldSig.GetFieldType());
				if (fieldType == null)
					continue;
				if (!fieldType.IsEnum)
					continue;
				enumField = field;
				return;
			}
		}
Exemplo n.º 15
0
		protected override void GetCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
			callOpcode = OpCodes.Call;
			string name = field.Name.String;

			uint memberRefRid = 0;
			for (int i = name.Length - 1; i >= 0; i--) {
				char c = name[i];
				if (c == '~') {
					callOpcode = OpCodes.Callvirt;
					break;
				}

				int val;
				if (specialCharsDict.TryGetValue(c, out val))
					memberRefRid = memberRefRid * (uint)specialChars.Length + (uint)val;
			}
			memberRefRid++;

			calledMethod = module.ResolveMemberRef(memberRefRid);
			if (calledMethod == null)
				Logger.w("Ignoring invalid method RID: {0:X8}, field: {1:X8}", memberRefRid, field.MDToken.ToInt32());
		}
		protected override bool CheckDecrypterType(TypeDef type) {
			var fields = type.Fields;
			if (fields.Count != 2)
				return false;

			if (fields[0].FieldType.FullName != "System.Byte[]")
				return false;

			var dict = fields[1].FieldType.ToGenericInstSig();
			if (dict == null || dict.GenericArguments.Count != 2)
				return false;
			if (dict.GenericType.GetFullName() != "System.Collections.Generic.Dictionary`2")
				return false;

			if (dict.GenericArguments[0].FullName != "System.Int32")
				return false;

			var garg = dict.GenericArguments[1];
			if (garg.FullName != "System.String") {
				if (!garg.IsValueType)
					return false;
				var gargType = DotNetUtils.GetType(module, garg);
				if (gargType == null || !gargType.IsClass)
					return false;
				if (gargType.Fields.Count != 1)
					return false;
				var field = gargType.Fields[0];
				if (field.FieldType.FullName != "System.String")
					return false;
				delegateReturnType = gargType;
				stringStructField = field;
			}
			else {
				delegateReturnType = garg;
				stringStructField = null;
			}

			return true;
		}
Exemplo n.º 17
0
        void Analyze(NameService service, ConfuserContext context, ProtectionParameters parameters, FieldDef field)
        {
            if (field.DeclaringType.IsVisibleOutside() &&
                (field.IsFamily || field.IsFamilyOrAssembly || field.IsPublic) &&
                !IsVisibleOutside(context, parameters, field))
                service.SetCanRename(field, false);

            else if (field.IsRuntimeSpecialName)
                service.SetCanRename(field, false);

            else if (parameters.GetParameter(context, field, "forceRen", false))
                return;

            else if (field.DeclaringType.IsSerializable && !field.IsNotSerialized)
                service.SetCanRename(field, false);

            else if (field.IsLiteral && field.DeclaringType.IsEnum)
                service.SetCanRename(field, false);
        }
			protected IntPtr GetDelegateAddress(FieldDef delegateField) {
				FieldInfo delegateFieldInfo = dmd.reflectionProtectModule.ResolveField(0x04000000 + (int)delegateField.Rid);
				object mainTypeInst = ((Delegate)dmd.invokerFieldInfo.GetValue(null)).Target;
				return GetNativeAddressOfDelegate((Delegate)delegateFieldInfo.GetValue(mainTypeInst));
			}
Exemplo n.º 19
0
		public void Find() {
			var cctor = DotNetUtils.GetModuleTypeCctor(module);
			if (cctor == null)
				return;
			simpleDeobfuscator.Deobfuscate(cctor, SimpleDeobfuscatorFlags.Force | SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs);

			if ((dictField = ConstantsDecrypterUtils.FindDictField(cctor, cctor.DeclaringType)) == null)
				return;

			if ((dataField = ConstantsDecrypterUtils.FindDataField_v18_r75367(cctor, cctor.DeclaringType)) == null &&
				(dataField = ConstantsDecrypterUtils.FindDataField_v19_r77172(cctor, cctor.DeclaringType)) == null)
				return;

			nativeMethod = FindNativeMethod(cctor, cctor.DeclaringType);

			var method = GetDecryptMethod();
			if (method == null)
				return;
			simpleDeobfuscator.Deobfuscate(method, SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs);
			var info = new DecrypterInfo(this, method, ConfuserVersion.Unknown);
			if (FindKeys_v18_r75367(info))
				InitVersion(cctor, ConfuserVersion.v18_r75367_normal, ConfuserVersion.v18_r75367_dynamic, ConfuserVersion.v18_r75367_native);
			else if (FindKeys_v18_r75369(info)) {
				lzmaType = ConfuserUtils.FindLzmaType(cctor);
				if (lzmaType == null)
					InitVersion(cctor, ConfuserVersion.v18_r75369_normal, ConfuserVersion.v18_r75369_dynamic, ConfuserVersion.v18_r75369_native);
				else if (!DotNetUtils.CallsMethod(method, "System.Void System.Threading.Monitor::Exit(System.Object)"))
					InitVersion(cctor, ConfuserVersion.v19_r77172_normal, ConfuserVersion.v19_r77172_dynamic, ConfuserVersion.v19_r77172_native);
				else if (DotNetUtils.CallsMethod(method, "System.Void System.Diagnostics.StackFrame::.ctor(System.Int32)"))
					InitVersion(cctor, ConfuserVersion.v19_r78363_normal, ConfuserVersion.v19_r78363_dynamic, ConfuserVersion.v19_r78363_native);
				else {
					int index1 = ConfuserUtils.FindCallMethod(cctor.Body.Instructions, 0, Code.Callvirt, "System.Reflection.Module System.Reflection.MemberInfo::get_Module()");
					int index2 = ConfuserUtils.FindCallMethod(cctor.Body.Instructions, 0, Code.Callvirt, "System.Int32 System.Reflection.MemberInfo::get_MetadataToken()");
					if (index1 < 0 || index2 < 0) {
					}
					if (index2 - index1 == 3)
						InitVersion(cctor, ConfuserVersion.v19_r78056_normal, ConfuserVersion.v19_r78056_dynamic, ConfuserVersion.v19_r78056_native);
					else if (index2 - index1 == -4)
						InitVersion(cctor, ConfuserVersion.v19_r79630_normal, ConfuserVersion.v19_r79630_dynamic, ConfuserVersion.v19_r79630_native);
				}
			}
			else
				return;

			installMethod = cctor;
		}
Exemplo n.º 20
0
		public override void DecompileField(FieldDef field, ITextOutput output, DecompilationOptions options)
		{
			output.WriteReference(IdentifierEscaper.Escape(field.FieldType.GetFullName()), field.FieldType.ToTypeDefOrRef(), TextTokenHelper.GetTextTokenType(field.FieldType));
			output.WriteSpace();
			output.WriteDefinition(IdentifierEscaper.Escape(field.Name), field, TextTokenHelper.GetTextTokenType(field), false);
			var c = field.Constant;
			if (c != null) {
				output.WriteSpace();
				output.Write('=', TextTokenType.Operator);
				output.WriteSpace();
				if (c.Value == null)
					output.Write("null", TextTokenType.Keyword);
				else {
					switch (c.Type) {
					case ElementType.Boolean:
						if (c.Value is bool)
							output.Write((bool)c.Value ? "true" : "false", TextTokenType.Keyword);
						else
							goto default;
						break;

					case ElementType.Char:
						output.Write(string.Format("'{0}'", c.Value), TextTokenType.Char);
						break;

					case ElementType.I1:
					case ElementType.U1:
					case ElementType.I2:
					case ElementType.U2:
					case ElementType.I4:
					case ElementType.U4:
					case ElementType.I8:
					case ElementType.U8:
					case ElementType.R4:
					case ElementType.R8:
					case ElementType.I:
					case ElementType.U:
						output.Write(string.Format("{0}", c.Value), TextTokenType.Number);
						break;

					case ElementType.String:
						output.Write(string.Format("{0}", c.Value), TextTokenType.String);
						break;

					default:
						output.Write(string.Format("{0}", c.Value), TextTokenType.Text);
						break;
					}
				}
			}
		}
Exemplo n.º 21
0
 public override TreeViewNodeFilterResult GetFilterResult(FieldDef field)
 {
     bool isMatch = (flags & VisibleMembersFlags.FieldDef) != 0;
     if (!isMatch)
         return new TreeViewNodeFilterResult(FilterResult.Hidden, isMatch);
     return new TreeViewNodeFilterResult(FilterResult.Match, isMatch);
 }
Exemplo n.º 22
0
 public override void DecompileField(FieldDef field, ITextOutput output, DecompilationOptions options)
 {
     var dis = CreateReflectionDisassembler(output, options, field);
     dis.DisassembleField(field);
 }
Exemplo n.º 23
0
		bool? CanAccess(FieldDef fd, GenericInstSig git) {
			if (fd == null)
				return null;
			var access = GetTypeAccess(fd.DeclaringType, git);
			if (access == null)
				return null;
			var acc = access.Value;
			if ((acc & CheckTypeAccess.Normal) == 0)
				return false;
			if ((acc & CheckTypeAccess.FullMemberAccess) != 0)
				return true;

			return IsVisible(fd, git);
		}
Exemplo n.º 24
0
		bool IsVisible(FieldDef fd, GenericInstSig git) {
			if (fd == null)
				return false;
			var fdDeclaringType = fd.DeclaringType;
			if (fdDeclaringType == null)
				return false;
			if (userType == fdDeclaringType)
				return true;

			switch (fd.Access) {
			case FieldAttributes.PrivateScope:
				// Private scope aka compiler controlled fields/methods can only be accessed
				// by a Field/Method token. This means they must be in the same module.
				return userType.Module == fdDeclaringType.Module;

			case FieldAttributes.Private:
				return false;

			case FieldAttributes.FamANDAssem:
				return IsSameAssemblyOrFriendAssembly(fdDeclaringType.Module) &&
					CheckFamily(fdDeclaringType, git);

			case FieldAttributes.Assembly:
				return IsSameAssemblyOrFriendAssembly(fdDeclaringType.Module);

			case FieldAttributes.Family:
				return CheckFamily(fdDeclaringType, git);

			case FieldAttributes.FamORAssem:
				return IsSameAssemblyOrFriendAssembly(fdDeclaringType.Module) ||
					CheckFamily(fdDeclaringType, git);

			case FieldAttributes.Public:
				return true;

			default:
				return false;
			}
		}
		static FieldDef FindDelegateFieldV2_0_9_0(TypeDef mainType, FieldDef decryptCallbackField) {
			if (decryptCallbackField == null)
				return null;
			var type = decryptCallbackField.FieldSig.GetFieldType().ToTypeDefOrRef() as TypeDef;
			if (type == null)
				return null;
			return FindDelegateField(mainType, "System.Boolean", string.Format("(System.Int32,System.Int32,System.Int32,System.Int32,System.Diagnostics.StackTrace,{0})", type.FullName));
		}
Exemplo n.º 26
0
		/// <summary>
		/// Checks whether it can access a <see cref="FieldDef"/>
		/// </summary>
		/// <param name="fd">The field</param>
		/// <returns><c>true</c> if it has access to it, <c>false</c> if not, and <c>null</c>
		/// if we can't determine it (eg. we couldn't resolve a type or input was <c>null</c>)</returns>
		public bool? CanAccess(FieldDef fd) {
			return CanAccess(fd, null);
		}
			public DecrypterV2_0_9_0(DynamicMethodsDecrypter dmd, FieldDef delegateField)
				: base(dmd) {
				IntPtr addr = GetDelegateAddress(delegateField);
				decryptMethod = (DecryptMethod)Marshal.GetDelegateForFunctionPointer(addr, typeof(DecryptMethod));
				PatchRuntime(addr);
			}
Exemplo n.º 28
0
 /// <summary>
 /// Checks whether it can access a <see cref="FieldDef"/>
 /// </summary>
 /// <param name="fd">The field</param>
 /// <returns><c>true</c> if it has access to it, <c>false</c> if not, and <c>null</c>
 /// if we can't determine it (eg. we couldn't resolve a type or input was <c>null</c>)</returns>
 public bool?CanAccess(FieldDef fd)
 {
     return(CanAccess(fd, null));
 }
Exemplo n.º 29
0
        public TreeNode NewField(FieldDef field)
        {
            string type = field.FieldType.GetExtendedName();

            TreeNode node = NewNode(String.Format("{0}: {1}", field.Name, type));
            node.Tag = field;
            node.ImageIndex = node.SelectedImageIndex = 17;

            return node;
        }
Exemplo n.º 30
0
		int? FindOffsetValue(MethodDef method, FieldDef offsetField, FieldDefAndDeclaringTypeDict<IField> fields) {
			var instructions = method.Body.Instructions;
			for (int i = 0; i <= instructions.Count - 2; i++) {
				var ldstr = instructions[i];
				if (ldstr.OpCode.Code != Code.Ldstr)
					continue;
				var stringVal = ldstr.Operand as string;
				if (stringVal == null)
					continue;

				var stsfld = instructions[i + 1];
				if (stsfld.OpCode.Code != Code.Stsfld)
					continue;
				var field = stsfld.Operand as IField;
				if (field == null || fields.Find(field) != offsetField)
					continue;

				int value;
				if (!int.TryParse(stringVal, System.Globalization.NumberStyles.Integer, null, out value))
					continue;

				return value;
			}

			return null;
		}
Exemplo n.º 31
0
		Info GetDecrypterInfo(MethodDef method, FieldDef delegateField) {
			try {
				int index = 0;
				var instrs = method.Body.Instructions;
				if (instrs[index].OpCode.Code != Code.Ldsfld)
					return null;
				var field = instrs[index++].Operand as FieldDef;
				if (field != delegateField)
					return null;

				if (!instrs[index].IsLdcI4())
					return null;
				int offset = instrs[index++].GetLdcI4Value();

				if (instrs[index].OpCode.Code != Code.Call && instrs[index].OpCode.Code != Code.Callvirt)
					return null;
				var calledMethod = instrs[index++].Operand as IMethod;
				if (calledMethod.Name != "Invoke")
					return null;

				if (instrs[index].OpCode.Code == Code.Unbox_Any)
					index++;

				if (instrs[index++].OpCode.Code != Code.Ret)
					return null;

				return new Info(method, offset);
			}
			catch (ArgumentOutOfRangeException) {
				return null;
			}
		}