ResolveType() public method

public ResolveType ( int metadataToken ) : Type
metadataToken int
return Type
Beispiel #1
0
    public OpToken(Code aOpCode, int aPos, int aNextPos, Int32 aValue, Module aModule, Type[] aTypeGenericArgs, Type[] aMethodGenericArgs, ExceptionHandlingClause aCurrentExceptionHandler)
      : base(aOpCode, aPos, aNextPos, aCurrentExceptionHandler) {
      Value = aValue;
      if (ValueIsField)
      {
          ValueField = aModule.ResolveField(Value, aTypeGenericArgs, aMethodGenericArgs);
      }
      if (ValueIsType)
      {
          ValueType = aModule.ResolveType(Value, aTypeGenericArgs, aMethodGenericArgs);
      }

    }
 public static PropertyInfo GetPropertyInfo(
     Module module,
     int propertyMetadataToken,
     int parentTypeMetadataToken)
 {
     Type propertyParentType = module.ResolveType(parentTypeMetadataToken);
     var cache = cacheProperty.GetValue(propertyParentType, null);
     var constructorArguments = new object[]
     {
         propertyMetadataToken,
         propertyParentType,
         cache,
         false
     };
     var propertyInfo = (PropertyInfo)runtimePropertyInfoCtor.Invoke(constructorArguments);
     return propertyInfo;
 }
		public void Initialize() {
			RuntimeHelpers.RunModuleConstructor(reflectionModule.ModuleHandle);
			var reflectionProtectAssembly = GetProtectAssembly();
			if (reflectionProtectAssembly == null)
				throw new ApplicationException("Could not find 'Protect' assembly");
			reflectionProtectModule = reflectionProtectAssembly.ManifestModule;
			moduleProtect = ModuleDefMD.Load(reflectionProtectModule);
			protectMainType = FindMainType(moduleProtect);
			if (protectMainType == null)
				throw new ApplicationException("Could not find Protect.MainType");
			var invokerField = FindInvokerField(module);

			reflectionProtectMainType = reflectionProtectModule.ResolveType(0x02000000 + (int)protectMainType.Rid);
			invokerFieldInfo = reflectionModule.ResolveField(0x04000000 + (int)invokerField.Rid);

			decrypter = CreateDecrypter();
			if (decrypter == null)
				throw new ApplicationException("Probably a new version. Could not create a decrypter.");
		}
        /// <summary>
        /// Constructs the array of ILInstructions according to the IL byte code.
        /// </summary>
        /// <param name="module"></param>
        private void ConstructInstructions(Module module)
        {
            byte[] il = this.il;
            int position = 0;
            instructions = new List<ILInstruction>();
            while (position < il.Length)
            {
                ILInstruction instruction = new ILInstruction();

                // get the operation code of the current instruction
                OpCode code = OpCodes.Nop;
                ushort value = il[position++];
                if (value != 0xfe)
                {
                    code = Globals.singleByteOpCodes[(int)value];
                }
                else
                {
                    value = il[position++];
                    code = Globals.multiByteOpCodes[(int)value];
                    value = (ushort)(value | 0xfe00);
                }
                instruction.Code = code;
                instruction.Offset = position - 1;
                int metadataToken = 0;
                // get the operand of the current operation
                switch (code.OperandType)
                {
                    case OperandType.InlineBrTarget:
                        metadataToken = ReadInt32(il, ref position);
                        metadataToken += position;
                        instruction.Operand = metadataToken;
                        break;

                    // patched from comments on CP -hwd
                    case OperandType.InlineField:
                        metadataToken = ReadInt32(il, ref position);
                        if (mi is ConstructorInfo)
                        {
                            instruction.Operand = module.ResolveField(metadataToken,
                                mi.DeclaringType.GetGenericArguments(), null);
                        }
                        else
                        {
                            instruction.Operand = module.ResolveField(metadataToken,
                                mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments());
                        }
                        break;

                    // patched from comments on CP -hwd
                    case OperandType.InlineMethod:
                        metadataToken = ReadInt32(il, ref position);
                        try
                        {
                            if (mi is ConstructorInfo)
                            {
                                instruction.Operand = module.ResolveMethod(metadataToken,
                                    mi.DeclaringType.GetGenericArguments(), null);
                            }
                            else
                            {
                                instruction.Operand = module.ResolveMethod(metadataToken,
                                    mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments());
                            }
                        }
                        catch
                        {
                            if (mi is ConstructorInfo)
                            {
                                instruction.Operand = module.ResolveMember(metadataToken,
                                    mi.DeclaringType.GetGenericArguments(), null);
                            }
                            else
                            {
                                instruction.Operand = module.ResolveMember(metadataToken,
                                    mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments());
                            }
                        }
                        break;

                    case OperandType.InlineSig:
                        metadataToken = ReadInt32(il, ref position);
                        instruction.Operand = module.ResolveSignature(metadataToken);
                        break;

                    // patched from comments on CP -hwd
                    case OperandType.InlineTok:
                        metadataToken = ReadInt32(il, ref position);
                        //try
                        //{
                            if (mi is ConstructorInfo)
                            {
                                instruction.Operand = module.ResolveType(metadataToken,
                                    mi.DeclaringType.GetGenericArguments(), null);
                            }
                            else
                            {
                                instruction.Operand = module.ResolveType(metadataToken,
                                    mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments());
                            }
                        //}
                        //catch
                        //{
                        //    int i = 1;

                        //}
                        break;

                    // patched from comments on CP -hwd
                    case OperandType.InlineType:
                        metadataToken = ReadInt32(il, ref position);
                        if (this.mi is MethodInfo)
                        {
                            instruction.Operand = module.ResolveType(metadataToken,
                            this.mi.DeclaringType.GetGenericArguments(), this.mi.GetGenericArguments());
                        }
                        else if (mi is ConstructorInfo)
                        {
                            instruction.Operand = module.ResolveType(metadataToken,
                               this.mi.DeclaringType.GetGenericArguments(), null);
                        }
                        else
                        {
                            instruction.Operand = module.ResolveType(metadataToken);
                        }
                        break;

                    case OperandType.InlineI:
                        {
                            instruction.Operand = ReadInt32(il, ref position);
                            break;
                        }
                    case OperandType.InlineI8:
                        {
                            instruction.Operand = ReadInt64(il, ref position);
                            break;
                        }
                    case OperandType.InlineNone:
                        {
                            instruction.Operand = null;
                            break;
                        }
                    case OperandType.InlineR:
                        {
                            instruction.Operand = ReadDouble(il, ref position);
                            break;
                        }
                    case OperandType.InlineString:
                        {
                            metadataToken = ReadInt32(il, ref position);
                            instruction.Operand = module.ResolveString(metadataToken);
                            break;
                        }
                    case OperandType.InlineSwitch:
                        {
                            int count = ReadInt32(il, ref position);
                            int[] casesAddresses = new int[count];
                            for (int i = 0; i < count; i++)
                            {
                                casesAddresses[i] = ReadInt32(il, ref position);
                            }
                            int[] cases = new int[count];
                            for (int i = 0; i < count; i++)
                            {
                                cases[i] = position + casesAddresses[i];
                            }
                            break;
                        }
                    case OperandType.InlineVar:
                        {
                            instruction.Operand = ReadUInt16(il, ref position);
                            break;
                        }
                    case OperandType.ShortInlineBrTarget:
                        {
                            instruction.Operand = ReadSByte(il, ref position) + position;
                            break;
                        }
                    case OperandType.ShortInlineI:
                        {
                            instruction.Operand = ReadSByte(il, ref position);
                            break;
                        }
                    case OperandType.ShortInlineR:
                        {
                            instruction.Operand = ReadSingle(il, ref position);
                            break;
                        }
                    case OperandType.ShortInlineVar:
                        {
                            instruction.Operand = ReadByte(il, ref position);
                            break;
                        }
                    default:
                        {
                            throw new Exception("Unknown operand type.");
                        }
                }
                instructions.Add(instruction);
            }
        }
        /// <summary>
        /// Constructs the array of ILInstructions according to the IL byte code.
        /// </summary>
        /// <param name="module"></param>
        private void ConstructInstructions(Module module)
        {
            byte[] il = this.il;
            int position = 0;
            instructions = new List<ILInstruction>();
            while (position < il.Length)
            {
                ILInstruction instruction = new ILInstruction();

                // get the operation code of the current instruction
                OpCode code = OpCodes.Nop;
                ushort value = il[position++];
                if (value != 0xfe)
                {
                    code = Globals.singleByteOpCodes[(int)value];
                }
                else
                {
                    value = il[position++];
                    code = Globals.multiByteOpCodes[(int)value];
                    value = (ushort)(value | 0xfe00);
                }
                instruction.Code = code;
                instruction.Offset = position - 1;
                int metadataToken = 0;
                // get the operand of the current operation
                switch (code.OperandType)
                {
                    case OperandType.InlineBrTarget:
                        metadataToken = ReadInt32(il, ref position);
                        metadataToken += position;
                        instruction.Operand = metadataToken;
                        break;
                    case OperandType.InlineField:
                        metadataToken = ReadInt32(il, ref position);
                        instruction.Operand = module.ResolveField(metadataToken);
                        break;
                    case OperandType.InlineMethod:
                        metadataToken = ReadInt32(il, ref position);
                        try
                        {
                            instruction.Operand = module.ResolveMethod(metadataToken);
                        }
                        catch
                        {
                            try
                            {
                                instruction.Operand = module.ResolveMember(metadataToken);
                            }
                            catch (Exception)
                            {
                                //Try generic method
                                try
                                {
                                    instruction.Operand = module.ResolveMethod(metadataToken, mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments());
                                }
                                catch (Exception)
                                {

                                    //Try generic member
                                    try
                                    {
                                        instruction.Operand = module.ResolveMember(metadataToken, mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments());
                                    }
                                    catch (Exception)
                                    {
                                        throw;
                                    }
                                }

                            }
                        }
                        break;
                    case OperandType.InlineSig:
                        metadataToken = ReadInt32(il, ref position);
                        instruction.Operand = module.ResolveSignature(metadataToken);
                        break;
                    case OperandType.InlineTok:
                        metadataToken = ReadInt32(il, ref position);
                        try
                        {
                            instruction.Operand = module.ResolveType(metadataToken);
                        }
                        catch
                        {

                        }
                        // SSS : see what to do here
                        break;
                     case OperandType.InlineType:
                        metadataToken = ReadInt32(il, ref position);
                        // now we call the ResolveType always using the generic attributes type in order
                        // to support decompilation of generic methods and classes

                        // thanks to the guys from code project who commented on this missing feature
                        try
                        {
                            instruction.Operand = module.ResolveType(metadataToken);
                        }
                        catch (Exception)
                        {
                            instruction.Operand = module.ResolveType(metadataToken, this.mi.DeclaringType.GetGenericArguments(), this.mi.GetGenericArguments());
                        }
                        break;
                    case OperandType.InlineI:
                        {
                            instruction.Operand = ReadInt32(il, ref position);
                            break;
                        }
                    case OperandType.InlineI8:
                        {
                            instruction.Operand = ReadInt64(il, ref position);
                            break;
                        }
                    case OperandType.InlineNone:
                        {
                            instruction.Operand = null;
                            break;
                        }
                    case OperandType.InlineR:
                        {
                            instruction.Operand = ReadDouble(il, ref position);
                            break;
                        }
                    case OperandType.InlineString:
                        {
                            metadataToken = ReadInt32(il, ref position);
                            instruction.Operand = module.ResolveString(metadataToken);
                            break;
                        }
                    case OperandType.InlineSwitch:
                        {
                            int count = ReadInt32(il, ref position);
                            int[] casesAddresses = new int[count];
                            for (int i = 0; i < count; i++)
                            {
                                casesAddresses[i] = ReadInt32(il, ref position);
                            }
                            int[] cases = new int[count];
                            for (int i = 0; i < count; i++)
                            {
                                cases[i] = position + casesAddresses[i];
                            }
                            break;
                        }
                    case OperandType.InlineVar:
                        {
                            instruction.Operand = ReadUInt16(il, ref position);
                            break;
                        }
                    case OperandType.ShortInlineBrTarget:
                        {
                            instruction.Operand = ReadSByte(il, ref position) + position;
                            break;
                        }
                    case OperandType.ShortInlineI:
                        {
                            instruction.Operand = ReadSByte(il, ref position);
                            break;
                        }
                    case OperandType.ShortInlineR:
                        {
                            instruction.Operand = ReadSingle(il, ref position);
                            break;
                        }
                    case OperandType.ShortInlineVar:
                        {
                            instruction.Operand = ReadByte(il, ref position);
                            break;
                        }
                    default:
                        {
                            throw new Exception("Unknown operand type.");
                        }
                }
                instructions.Add(instruction);
            }
        }
        /// <summary>
        /// Recursive function that loads (SSA) assembly and all included assemblies
        /// (included assemblies are required because we need to check whether included files are up-to-date)
        /// </summary>
        /// <param name="ns">Namespace of the script to be loaded (namespace is encoded file name)</param>
        /// <param name="type">Type of the &lt;Script&gt; class</param>
        /// <param name="module">Module of the type - used for token resolving </param>
        /// <param name="checkStamp">Should we check timestamp?</param>
        /// <param name="includer">Namespace of the includer (can be null)</param>
        /// <param name="tempCache">Temporary cache - used only while loading</param>
        /// <returns>Success?</returns>
        private bool LoadIncludeesRecursive(string/*!*/ ns, Type type/*!*/, Module/*!*/ module,
            bool checkStamp, string includer, Dictionary<string, CacheEntry>/*!*/ tempCache)
        {
            //File already processed?
            if (tempCache.ContainsKey(ns))
                return true;

            tempCache[ns] = null;   // just recursion prevention

            // find [Script] attribute
            ScriptAttribute script_attr = ScriptAttribute.Reflect(type);
            if (script_attr == null) return false;

            // check source file timestamp
            if (checkStamp)
            {
                string path = ScriptModule.GetPathFromSubnamespace(ns).
                    ToFullPath(Configuration.Application.Compiler.SourceRoot).ToString();
                DateTime writeStamp = File.GetLastWriteTime(path);  // note: it does not fail if the file does not exists, in such case it returns 12:00 midnight, January 1, 1601 A.D.
                if (writeStamp > script_attr.SourceTimestamp) return false;
            }

            // find [ScriptIncludees] attribute
            ScriptIncludeesAttribute script_includees = ScriptIncludeesAttribute.Reflect(type);
            string[] inclusionNames;
            if (script_includees != null)
            {
                Type[] inclusionScripts;

                inclusionNames = new string[script_includees.Inclusions.Length];
                inclusionScripts = new Type[script_includees.Inclusions.Length];

                // resolve included Scripts tokens:
                for (int i = 0; i < inclusionNames.Length; i++)
                {
                    try
                    {
                        inclusionScripts[i] = module.ResolveType(script_includees.Inclusions[i]);
                        ScriptAttribute sa = ScriptAttribute.Reflect(inclusionScripts[i]);
                        if (sa == null) return false;
                        inclusionNames[i] = ScriptModule.GetSubnamespace(new RelativePath(sa.RelativePath), false);
                    }
                    catch (ArgumentException)
                    {
                        return false;
                    }
                }

                // Try to load all included scripts and check whether files weren't changed
                for (int i = 0; i < inclusionNames.Length; i++)
                {
                    if (!LoadIncludeesRecursive(inclusionNames[i], inclusionScripts[i], inclusionScripts[i].Module, true, ns, tempCache)) return false;
                }
            }
            else
            {
                inclusionNames = ArrayUtils.EmptyStrings;
            }

            // Load SSA assembly
            SingleScriptAssembly ssa = ScriptAssembly.LoadFromAssembly(applicationContext, type.Assembly) as SingleScriptAssembly;

            if (ssa != null)
            {
                // Save only to temp cache (other calls to LoadIncludeesRecursive may fail!)
                string[] includers = includer == null ? (ArrayUtils.EmptyStrings) : (new string[] { includer });
                CacheEntry entry = new CacheEntry(type, ssa, script_attr.SourceTimestamp, includers, inclusionNames, true);
                tempCache[ns] = entry;
            }
            else
            {
                // script in MSA was included from SSA, MSA scripts should not be in cache[]
                // leave null in tempCache[ns] (as recursion prevention), it will not process into cache[]
            }

            return true;
        }
Beispiel #7
0
        void CopyOpcode(byte[] Bytes, ref int i, ILGenerator Gen, Module Origin, List<int> ExceptionTrinkets, Dictionary<int, Label[]> LabelOrigins)
        {
            OpCode Code = GetOpcode(Bytes, ref i);

            // These are emitted by exception handling copier if an exception
            // block is imminent. If not, copy them as usual.
            if(Code == OpCodes.Leave && ExceptionTrinkets.Contains(i + 5))
            {
                i += 4;
                return;
            }
            else if(Code == OpCodes.Leave_S && ExceptionTrinkets.Contains(i + 2))
            {
                // This is a rather tricky one. See the comment preceding the call to MineLabels above.
                i++;
                return;
            }
            else if(Code == OpCodes.Endfinally && ExceptionTrinkets.Contains(i+1)) return;

            switch(Code.OperandType)
            {
                // If no argument, then re-emit the opcode
                case OperandType.InlineNone:
                {
                    Gen.Emit(Code);
                    break;
                }

                // If argument is a method, re-emit the method reference
                case OperandType.InlineMethod:
                {
                    int Token = BitHelper.ReadInteger(Bytes, ref i);
                    MethodBase Base = Origin.ResolveMethod(Token);

                    if(Base is MethodInfo)
                        Gen.Emit(Code, GrabMethod(Base as MethodInfo));
                    else if(Base is ConstructorInfo)
                        Gen.Emit(Code, GrabConstructor(Base as ConstructorInfo));
                    else throw new InvalidOperationException("Inline method is neither method nor constructor.");

                    break;
                }

                // Argument is a field reference
                case OperandType.InlineField:
                {
                    int Token = BitHelper.ReadInteger(Bytes, ref i);
                    FieldInfo Field = Origin.ResolveField(Token);
                    Gen.Emit(Code, GrabField(Field));
                    break;
                }

                // Argument is a type reference
                case OperandType.InlineType:
                {
                    int Token = BitHelper.ReadInteger(Bytes, ref i);
                    Type Ref = Origin.ResolveType(Token);
                    Gen.Emit(Code, GrabType(Ref));
                    break;
                }

                // Argument is an inline string
                case OperandType.InlineString:
                {
                    int Token = BitHelper.ReadInteger(Bytes, ref i);
                    string Copy = Origin.ResolveString(Token);
                    Gen.Emit(Code, Copy);
                    break;
                }

                // Argument is a metadata token
                case OperandType.InlineTok:
                {
                    int Token = BitHelper.ReadInteger(Bytes, ref i);
                    MemberInfo Info = Origin.ResolveMember(Token);

                    if(Info.MemberType == MemberTypes.Field)
                    {
                        if(Code != OpCodes.Ldtoken || !TryReplaceBackingField(Bytes, i, Gen, Origin))
                            Gen.Emit(Code, GrabField(Info as FieldInfo));
                    }
                    else if(Info.MemberType == MemberTypes.Method)
                        Gen.Emit(Code, GrabMethod(Info as MethodInfo));
                    else if(Info.MemberType == MemberTypes.TypeInfo || Info.MemberType == MemberTypes.NestedType)
                        Gen.Emit(Code, GrabType(Info as Type));
                    else throw new InvalidOperationException("Inline token is neither field, nor method, nor type");

                    break;
                }

                // Argument is a switch map
                case OperandType.InlineSwitch:
                {
                    if(!LabelOrigins.ContainsKey(i))
                        throw new Exception("No switchmap found for RVA "+i.ToString("X"));

                    Label[] Labels = LabelOrigins[i];
                    i += 4 + Labels.Length*4;
                    Gen.Emit(Code, Labels);

                    break;
                }

                // Argument is a single-byte branch target
                case OperandType.ShortInlineBrTarget:
                {
                    if(!LabelOrigins.ContainsKey(i))
                        throw new Exception("No label origin found for RVA "+i.ToString("X"));

                    Gen.Emit(Code, LabelOrigins[i][0]);
                    i++;

                    break;
                }

                // Argument is a byte
                case OperandType.ShortInlineI:
                case OperandType.ShortInlineVar:
                {
                    Gen.Emit(Code, Bytes[++i]);
                    break;
                }

                // Argument is a short
                case OperandType.InlineVar:
                {
                    Gen.Emit(Code, BitHelper.ReadShort(Bytes, ref i));
                    break;
                }

                case OperandType.InlineBrTarget:
                {
                    if(!LabelOrigins.ContainsKey(i))
                        throw new Exception("No label origin found for RVA "+i.ToString("X"));

                    Gen.Emit(Code, LabelOrigins[i][0]);
                    i += 4;

                    break;
                }

                // Argument is a 32-bit integer
                case OperandType.InlineI:
                case OperandType.ShortInlineR: // This is actually a 32-bit float, but we don't care
                {
                    Gen.Emit(Code, BitHelper.ReadInteger(Bytes, ref i));
                    break;
                }

                // Argument is a 64-bit integer
                case OperandType.InlineI8:
                {
                    Gen.Emit(Code, BitHelper.ReadLong(Bytes, ref i));
                    break;
                }

                // Argument is a 64-bit float
                case OperandType.InlineR:
                {
                    Gen.Emit(Code, BitHelper.ReadDouble(Bytes, ref i));
                    break;
                }

                // If ever we run across OpCodes.Calli this'll probably happen
                default:
                    throw new InvalidOperationException("The method copier ran across an unknown opcode.");
            }
        }
        private void Write(BinaryWriter bw, Module module, MethodBody mb)
        {
            var locals = mb.LocalVariables;
            bw.Write(locals.Count);
            for (int i=0;i< locals.Count;i++)
            {
                bw.Write(locals[i].LocalType.FullName);
                bw.Write(locals[i].IsPinned);
            }

            var il = mb.GetILAsByteArray();
            for(int i = 0; i < il.Length;)
            {
                EArgumentType argType = EArgumentType.None;
                var opcode = (EOpCode)il[i];
                bw.Write(il[i]);
                i++;

                if(opcode == EOpCode.Extended)
                {
                    bw.Write(il[i]);
                    argType = ((EExtendedOpCode)il[i]).ArgFor();
                    i++;
                }
                else
                    argType = opcode.ArgFor();

                switch (argType)
                {
                    case EArgumentType.Field:
                        var fi = module.ResolveField(BitConverter.ToInt32(il, i));
                        i += 4;
                        bw.Write(Names.Field(fi));
                        break;
                    case EArgumentType.Float32:
                        bw.Write(BitConverter.ToSingle(il, i));
                        i += 4;
                        break;
                    case EArgumentType.Float64:
                        bw.Write(BitConverter.ToDouble(il, i));
                        i += 8;
                        break;
                    case EArgumentType.Token:
                    case EArgumentType.Int32:
                        bw.Write(BitConverter.ToInt32(il, i));
                        i += 4;
                        break;
                    case EArgumentType.Int64:
                        bw.Write(BitConverter.ToInt64(il, i));
                        i += 8;
                        break;
                    case EArgumentType.Int8:
                        bw.Write((sbyte)il[i]);
                        i++;
                        break;
                    case EArgumentType.ListOfInt:
                        uint count = BitConverter.ToUInt32(il, i);
                        bw.Write(count);
                        i += 4;
                        while(count > 0)
                        {
                            bw.Write(BitConverter.ToInt32(il, i));
                            i += 4;
                        }
                        break;
                    case EArgumentType.Method:
                        var mi = module.ResolveMethod(BitConverter.ToInt32(il, i));
                        i += 4;
                        bw.Write(Names.Method(mi));
                        break;
                    case EArgumentType.String:
                        var str = module.ResolveString(BitConverter.ToInt32(il, i));
                        i += 4;
                        bw.Write(str);
                        break;
                    case EArgumentType.Type:
                        var t = module.ResolveType(BitConverter.ToInt32(il, i));
                        i += 4;
                        bw.Write(t.FullName);
                        break;
                    case EArgumentType.Uint16:
                        bw.Write(BitConverter.ToUInt16(il, i));
                        i += 2;
                        break;
                    case EArgumentType.Uint32:
                        bw.Write(BitConverter.ToUInt32(il, i));
                        i += 4;
                        break;
                    case EArgumentType.Uint8:
                        bw.Write(il[i]);
                        i++;
                        break;
                }
            }

            bw.Write((byte)EOpCode.Terminator);
            /*

            var handlers = mb.ExceptionHandlingClauses;
            m_bw.Write(handlers.Count);
            foreach(var h in handlers)
            {
                m_bw.Write(h.TryOffset);
                m_bw.Write(h.TryLength);
                m_bw.Write(h.FilterOffset);
                m_bw.Write(h.HandlerOffset);
                m_bw.Write(h.HandlerLength);
                m_bw.Write((uint)h.Flags);

                //m_bw.Write(h.)
            }*/
        }
Beispiel #9
0
 internal static unsafe bool FilterCustomAttributeRecord(CustomAttributeRecord caRecord, MetadataImport scope, ref Assembly lastAptcaOkAssembly, Module decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, bool mustBeInheritable, object[] attributes, IList derivedAttributes, out RuntimeType attributeType, out RuntimeMethodHandle ctor, out bool ctorHasParameters, out bool isVarArg)
 {
     ctor = new RuntimeMethodHandle();
     attributeType = null;
     ctorHasParameters = false;
     isVarArg = false;
     IntPtr ptr1 = (IntPtr) (((void*) caRecord.blob.Signature) + caRecord.blob.Length);
     attributeType = decoratedModule.ResolveType(scope.GetParentToken((int) caRecord.tkCtor), null, null) as RuntimeType;
     if (!attributeFilterType.IsAssignableFrom(attributeType))
     {
         return false;
     }
     if (!AttributeUsageCheck(attributeType, mustBeInheritable, attributes, derivedAttributes))
     {
         return false;
     }
     if ((attributeType.Assembly != lastAptcaOkAssembly) && !attributeType.Assembly.AptcaCheck(decoratedModule.Assembly))
     {
         return false;
     }
     lastAptcaOkAssembly = decoratedModule.Assembly;
     ConstArray methodSignature = scope.GetMethodSignature(caRecord.tkCtor);
     isVarArg = (methodSignature[0] & 5) != 0;
     ctorHasParameters = methodSignature[1] != 0;
     if (ctorHasParameters)
     {
         ctor = decoratedModule.ModuleHandle.ResolveMethodHandle((int) caRecord.tkCtor);
     }
     else
     {
         ctor = attributeType.GetTypeHandleInternal().GetDefaultConstructor();
         if (ctor.IsNullHandle() && !attributeType.IsValueType)
         {
             throw new MissingMethodException(".ctor");
         }
     }
     if (ctor.IsNullHandle())
     {
         if (!attributeType.IsVisible && !attributeType.TypeHandle.IsVisibleFromModule(decoratedModule.ModuleHandle))
         {
             return false;
         }
         return true;
     }
     if (ctor.IsVisibleFromModule(decoratedModule))
     {
         return true;
     }
     MetadataToken token = new MetadataToken();
     if (decoratedToken.IsParamDef)
     {
         token = new MetadataToken(scope.GetParentToken((int) decoratedToken));
         token = new MetadataToken(scope.GetParentToken((int) token));
     }
     else if ((decoratedToken.IsMethodDef || decoratedToken.IsProperty) || (decoratedToken.IsEvent || decoratedToken.IsFieldDef))
     {
         token = new MetadataToken(scope.GetParentToken((int) decoratedToken));
     }
     else if (decoratedToken.IsTypeDef)
     {
         token = decoratedToken;
     }
     return (token.IsTypeDef && ctor.IsVisibleFromType(decoratedModule.ModuleHandle.ResolveTypeHandle((int) token)));
 }
Beispiel #10
0
        private static int _ReadOperand(MethodBase This, OpCode code, int position, byte[] il, Module module, ILInstruction instruction)
        {
            int metadataToken;

            switch (code.OperandType)
            {
            case OperandType.InlineBrTarget: {
                metadataToken       = ReadInt32(il, ref position);
                metadataToken      += position;
                instruction.Operand = metadataToken;
                break;
            }

            case OperandType.InlineField: {
                metadataToken       = ReadInt32(il, ref position);
                instruction.Operand = module.ResolveField(metadataToken);
                break;
            }

            case OperandType.InlineMethod: {
                metadataToken = ReadInt32(il, ref position);
                try {
                    instruction.Operand = module.ResolveMethod(metadataToken);
                } catch {
                    instruction.Operand = module.ResolveMember(metadataToken);
                }
                break;
            }

            case OperandType.InlineSig: {
                metadataToken       = ReadInt32(il, ref position);
                instruction.Operand = module.ResolveSignature(metadataToken);
                break;
            }

            case OperandType.InlineTok: {
                metadataToken = ReadInt32(il, ref position);
                try {
                    instruction.Operand = module.ResolveType(metadataToken);
                } catch { }
                // SSS : see what to do here
                break;
            }

            case OperandType.InlineType: {
                metadataToken = ReadInt32(il, ref position);
                // now we call the ResolveType always using the generic attributes type in order
                // to support decompilation of generic methods and classes

                // thanks to the guys from code project who commented on this missing feature

                instruction.Operand = module.ResolveType(metadataToken, This.DeclaringType.GetGenericArguments(), This.GetGenericArguments());
                break;
            }

            case OperandType.InlineI: {
                instruction.Operand = ReadInt32(il, ref position);
                break;
            }

            case OperandType.InlineI8: {
                instruction.Operand = ReadInt64(il, ref position);
                break;
            }

            case OperandType.InlineNone: {
                instruction.Operand = null;
                break;
            }

            case OperandType.InlineR: {
                instruction.Operand = ReadDouble(il, ref position);
                break;
            }

            case OperandType.InlineString: {
                metadataToken       = ReadInt32(il, ref position);
                instruction.Operand = module.ResolveString(metadataToken);
                break;
            }

            case OperandType.InlineSwitch: {
                var count          = ReadInt32(il, ref position);
                var casesAddresses = new int[count];
                for (var i = 0; i < count; i++)
                {
                    casesAddresses[i] = ReadInt32(il, ref position);
                }

                var cases = new int[count];
                for (var i = 0; i < count; i++)
                {
                    cases[i] = position + casesAddresses[i];
                }

                break;
            }

            case OperandType.InlineVar: {
                instruction.Operand = ReadUInt16(il, ref position);
                break;
            }

            case OperandType.ShortInlineBrTarget: {
                instruction.Operand = ReadSByte(il, ref position) + position;
                break;
            }

            case OperandType.ShortInlineI: {
                if (instruction.Code == OpCodes.Ldc_I4_S)
                {
                    instruction.Operand = ReadSByte(il, ref position);
                }
                else
                {
                    instruction.Operand = ReadByte(il, ref position);
                }
                break;
            }

            case OperandType.ShortInlineR: {
                instruction.Operand = ReadSingle(il, ref position);
                break;
            }

            case OperandType.ShortInlineVar: {
                instruction.Operand = ReadByte(il, ref position);
                break;
            }

            default: {
                throw new Exception("Unknown operand type.");
            }
            }
            return(position);
        }
        internal unsafe static bool FilterCustomAttributeRecord(
            CustomAttributeRecord caRecord, MetadataImport scope, ref Assembly lastAptcaOkAssembly, 
            Module decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, bool mustBeInheritable,
            object[] attributes, IList derivedAttributes,
            out RuntimeType attributeType, out RuntimeMethodHandle ctor, out bool ctorHasParameters, out bool isVarArg)
        {
            ctor = new RuntimeMethodHandle();
            attributeType = null;
            ctorHasParameters = false;
            isVarArg = false;
            
            IntPtr blobStart = caRecord.blob.Signature;
            IntPtr blobEnd = (IntPtr)((byte*)blobStart + caRecord.blob.Length);

            // Resolve attribute type from ctor parent token found in decorated decoratedModule scope
            attributeType = decoratedModule.ResolveType(scope.GetParentToken(caRecord.tkCtor), null, null) as RuntimeType;

            // Test attribute type against user provided attribute type filter
            if (!(attributeFilterType.IsAssignableFrom(attributeType)))
                return false;

            if (!AttributeUsageCheck(attributeType, mustBeInheritable, attributes, derivedAttributes))
                return false;

            // APTCA checks
            if (attributeType.Assembly != lastAptcaOkAssembly && 
                !attributeType.Assembly.AptcaCheck(decoratedModule.Assembly))
                return false;

            // Cache last successful APTCA check (optimization)
            lastAptcaOkAssembly = decoratedModule.Assembly;

            // Resolve the attribute ctor
            ConstArray ctorSig = scope.GetMethodSignature(caRecord.tkCtor);
            isVarArg = (ctorSig[0] & 0x05) != 0;
            ctorHasParameters = ctorSig[1] != 0;

            if (ctorHasParameters)
            {
                // Resolve method ctor token found in decorated decoratedModule scope
                ctor = decoratedModule.ModuleHandle.ResolveMethodHandle(caRecord.tkCtor);
            }
            else
            {
                // Resolve method ctor token from decorated decoratedModule scope
                ctor = attributeType.GetTypeHandleInternal().GetDefaultConstructor();

                if (ctor.IsNullHandle() && !attributeType.IsValueType)
                    throw new MissingMethodException(".ctor");
            }

            // Visibility checks
            if (ctor.IsNullHandle())
            {
                if (!attributeType.IsVisible && !attributeType.TypeHandle.IsVisibleFromModule(decoratedModule.ModuleHandle))
                    return false;            
                
                return true;
            }
            
            if (ctor.IsVisibleFromModule(decoratedModule))
                return true;
            
            MetadataToken tkParent = new MetadataToken();
                
            if (decoratedToken.IsParamDef)
            {
                tkParent = new MetadataToken(scope.GetParentToken(decoratedToken));
                tkParent = new MetadataToken(scope.GetParentToken(tkParent));
            }               
            else if (decoratedToken.IsMethodDef || decoratedToken.IsProperty || decoratedToken.IsEvent || decoratedToken.IsFieldDef) 
            {
                tkParent = new MetadataToken(scope.GetParentToken(decoratedToken));
            }
            else if (decoratedToken.IsTypeDef)
            {
                tkParent = decoratedToken;
            }
            
            if (tkParent.IsTypeDef)
                return ctor.IsVisibleFromType(decoratedModule.ModuleHandle.ResolveTypeHandle(tkParent));
            
            return false;
        }
        private void ConstructInstructions(Module module)
        {
            byte[] localIlbytes = this.il;
            int position = 0;
            while (position < localIlbytes.Length)
            {
                var instruction = new ILInstruction();

                // get the operation code of the current instruction
                OpCode code;
                ushort value = localIlbytes[position++];
                if (GlobalIntermediateLanguageConstants.SingleByteOpCodes.Count == 0)
                {
                    throw new InvalidOperationException(
                        "Attempt to use Method Body Reader before Global Intermediate Language Constants has been initialised. Global Intermediate Language Constants. Load Op Codes must be called once.");
                }

                if (value != 0xfe)
                {
                    code = GlobalIntermediateLanguageConstants.SingleByteOpCodes[value];
                }
                else
                {
                    value = localIlbytes[position++];
                    code = GlobalIntermediateLanguageConstants.MultiByteOpCodes[value];
                }

                instruction.Code = code;
                instruction.Offset = position - 1;
                int metadataToken;

                // get the operand of the current operation
                switch (code.OperandType)
                {
                    case OperandType.InlineBrTarget:
                        metadataToken = ReadInt32(ref position);
                        metadataToken += position;
                        instruction.Operand = metadataToken;
                        break;
                    case OperandType.InlineField:

                        // TODO All these try catch blocks need to go
                        try
                        {
                            metadataToken = ReadInt32(ref position);
                            instruction.Operand = module.ResolveField(metadataToken);
                        }
                        catch
                        {
                            instruction.Operand = new object();
                        }

                        break;
                    case OperandType.InlineMethod:
                        metadataToken = ReadInt32(ref position);
                        try
                        {
                            instruction.Operand = module.ResolveMethod(metadataToken);
                        }
                        catch
                        {
                            instruction.Operand = new object();
                        }

                        break;
                    case OperandType.InlineSig:
                        metadataToken = ReadInt32(ref position);
                        instruction.Operand = module.ResolveSignature(metadataToken);
                        break;
                    case OperandType.InlineTok:
                        metadataToken = ReadInt32(ref position);
                        try
                        {
                            instruction.Operand = module.ResolveType(metadataToken);
                        }
                        catch
                        {
                        }

                        // TODO : see what to do here
                        break;
                    case OperandType.InlineType:
                        metadataToken = ReadInt32(ref position);

                        // now we call the ResolveType always using the generic attributes type in order
                        // to support decompilation of generic methods and classes
                        // thanks to the guys from code project who commented on this missing feature
                        Type[] declaringTypeGenericArgs = this.mi.DeclaringType.GetGenericArguments();
                        Type[] genericArgs = null;
                        if (this.mi.IsGenericMethod)
                        {
                            genericArgs = this.mi.GetGenericArguments();
                        }

                        instruction.Operand = module.ResolveType(metadataToken, declaringTypeGenericArgs, genericArgs);
                        break;
                    case OperandType.InlineI:
                        {
                            instruction.Operand = ReadInt32(ref position);
                            break;
                        }

                    case OperandType.InlineI8:
                        {
                            instruction.Operand = ReadInt64(ref position);
                            break;
                        }

                    case OperandType.InlineNone:
                        {
                            instruction.Operand = null;
                            break;
                        }

                    case OperandType.InlineR:
                        {
                            instruction.Operand = ReadDouble(ref position);
                            break;
                        }

                    case OperandType.InlineString:
                        {
                            metadataToken = ReadInt32(ref position);
                            instruction.Operand = module.ResolveString(metadataToken);
                            break;
                        }

                    case OperandType.InlineSwitch:
                        {
                            int count = ReadInt32(ref position);
                            var casesAddresses = new int[count];
                            for (int i = 0; i < count; i++)
                            {
                                casesAddresses[i] = ReadInt32(ref position);
                            }

                            var cases = new int[count];
                            for (int i = 0; i < count; i++)
                            {
                                cases[i] = position + casesAddresses[i];
                            }

                            break;
                        }

                    case OperandType.InlineVar:
                        {
                            instruction.Operand = ReadUInt16(ref position);
                            break;
                        }

                    case OperandType.ShortInlineBrTarget:
                        {
                            instruction.Operand = ReadSByte(ref position) + position;
                            break;
                        }

                    case OperandType.ShortInlineI:
                        {
                            instruction.Operand = ReadSByte(ref position);
                            break;
                        }

                    case OperandType.ShortInlineR:
                        {
                            instruction.Operand = ReadSingle(ref position);
                            break;
                        }

                    case OperandType.ShortInlineVar:
                        {
                            instruction.Operand = ReadByte(ref position);
                            break;
                        }

                    default:
                        {
                            throw new NotSupportedException("Unknown operand type.");
                        }
                }

                this.instructions.Add(instruction);
            }
        }
Beispiel #13
0
 public string ToString( Module module )
 {
     OpCode opCode = OpCode;
     string operandStr = "";
     int operandStart = _startIndex + opCode.Size;
     switch (opCode.OperandType)
     {
         case OperandType.InlineBrTarget:
             break;
         case OperandType.InlineField:
             operandStr = module.ResolveField(_il.GetInt32(operandStart)).Name;
             break;
         case OperandType.InlineI:
             operandStr = _il.GetInt32(operandStart).ToString();
             break;
         case OperandType.InlineI8:
             operandStr = _il.GetInt64(operandStart).ToString();
             break;
         case OperandType.InlineMethod:
             operandStr = module.ResolveMethod(_il.GetInt32(operandStart)).Name;
             break;
         case OperandType.InlineNone:
             break;
         case OperandType.InlineR:
             operandStr = _il.GetDouble(operandStart).ToString();
             break;
         case OperandType.InlineSig:
             operandStr = string.Join("",
                                      module.ResolveSignature(_il.GetInt32(operandStart))
                                            .Select(b => b.ToString("X2")));
             break;
         case OperandType.InlineString:
             operandStr = "\"" + module.ResolveString(_il.GetInt32(operandStart)) + "\"";
             break;
         case OperandType.InlineSwitch:
             break;
         case OperandType.InlineTok:
             operandStr = module.ResolveType(_il.GetInt32(operandStart)).Name;
             break;
         case OperandType.InlineType:
             operandStr = module.ResolveType(_il.GetInt32(operandStart)).Name;
             break;
         case OperandType.InlineVar:
             operandStr = _il.GetInt16(operandStart).ToString();
             break;
         case OperandType.ShortInlineBrTarget:
             break;
         case OperandType.ShortInlineI:
             operandStr = ((int) _il[operandStart]).ToString();
             break;
         case OperandType.ShortInlineR:
             operandStr = _il.GetSingle(operandStart).ToString();
             break;
         case OperandType.ShortInlineVar:
             operandStr = ((int) _il[operandStart]).ToString();
             break;
     }
     return opCode.Name + " " + operandStr;
 }
Beispiel #14
0
 public override Type ResolveType(int Metadatatoken)
 {
     return(_Module.ResolveType(Metadatatoken));
 }
Beispiel #15
0
        internal static unsafe bool FilterCustomAttributeRecord(CustomAttributeRecord caRecord, MetadataImport scope, ref Assembly lastAptcaOkAssembly, Module decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, bool mustBeInheritable, object[] attributes, IList derivedAttributes, out RuntimeType attributeType, out RuntimeMethodHandle ctor, out bool ctorHasParameters, out bool isVarArg)
        {
            ctor              = new RuntimeMethodHandle();
            attributeType     = null;
            ctorHasParameters = false;
            isVarArg          = false;
            IntPtr ptr1 = (IntPtr)(((void *)caRecord.blob.Signature) + caRecord.blob.Length);

            attributeType = decoratedModule.ResolveType(scope.GetParentToken((int)caRecord.tkCtor), null, null) as RuntimeType;
            if (!attributeFilterType.IsAssignableFrom(attributeType))
            {
                return(false);
            }
            if (!AttributeUsageCheck(attributeType, mustBeInheritable, attributes, derivedAttributes))
            {
                return(false);
            }
            if ((attributeType.Assembly != lastAptcaOkAssembly) && !attributeType.Assembly.AptcaCheck(decoratedModule.Assembly))
            {
                return(false);
            }
            lastAptcaOkAssembly = decoratedModule.Assembly;
            ConstArray methodSignature = scope.GetMethodSignature(caRecord.tkCtor);

            isVarArg          = (methodSignature[0] & 5) != 0;
            ctorHasParameters = methodSignature[1] != 0;
            if (ctorHasParameters)
            {
                ctor = decoratedModule.ModuleHandle.ResolveMethodHandle((int)caRecord.tkCtor);
            }
            else
            {
                ctor = attributeType.GetTypeHandleInternal().GetDefaultConstructor();
                if (ctor.IsNullHandle() && !attributeType.IsValueType)
                {
                    throw new MissingMethodException(".ctor");
                }
            }
            if (ctor.IsNullHandle())
            {
                if (!attributeType.IsVisible && !attributeType.TypeHandle.IsVisibleFromModule(decoratedModule.ModuleHandle))
                {
                    return(false);
                }
                return(true);
            }
            if (ctor.IsVisibleFromModule(decoratedModule))
            {
                return(true);
            }
            MetadataToken token = new MetadataToken();

            if (decoratedToken.IsParamDef)
            {
                token = new MetadataToken(scope.GetParentToken((int)decoratedToken));
                token = new MetadataToken(scope.GetParentToken((int)token));
            }
            else if ((decoratedToken.IsMethodDef || decoratedToken.IsProperty) || (decoratedToken.IsEvent || decoratedToken.IsFieldDef))
            {
                token = new MetadataToken(scope.GetParentToken((int)decoratedToken));
            }
            else if (decoratedToken.IsTypeDef)
            {
                token = decoratedToken;
            }
            return(token.IsTypeDef && ctor.IsVisibleFromType(decoratedModule.ModuleHandle.ResolveTypeHandle((int)token)));
        }
Beispiel #16
0
//		private IMethodReference FindMethodRef(uint metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
//		{
//			return AssemblyManager.FindMethod(_netModule.ResolveMethod((int)metadataToken, genericTypeArguments, genericMethodArguments));
//		}

        private ITypeReference FindTypeRef(uint metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments, Type[] genericArguments)
        {
            return(AssemblyManager.FindType(_netModule.ResolveType((int)metadataToken, genericTypeArguments, genericMethodArguments), genericArguments));
        }