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 <Script> 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; }
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.) }*/ }
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))); }
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); } }
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; }
public override Type ResolveType(int Metadatatoken) { return(_Module.ResolveType(Metadatatoken)); }
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))); }
// 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)); }