diff --git a/Confuser.Core/DnlibUtils.cs b/Confuser.Core/DnlibUtils.cs
index f3d3c5c12..8241615b7 100644
--- a/Confuser.Core/DnlibUtils.cs
+++ b/Confuser.Core/DnlibUtils.cs
@@ -6,453 +6,516 @@
using dnlib.DotNet.Emit;
using dnlib.IO;
-namespace Confuser.Core {
- ///
- /// Provides a set of utility methods about dnlib
- ///
- public static class DnlibUtils {
- ///
- /// Finds all definitions of interest in a module.
- ///
- /// The module.
- /// A collection of all required definitions
- public static IEnumerable FindDefinitions(this ModuleDef module) {
- yield return module;
- foreach (TypeDef type in module.GetTypes()) {
- yield return type;
-
- foreach (MethodDef method in type.Methods)
- yield return method;
-
- foreach (FieldDef field in type.Fields)
- yield return field;
-
- foreach (PropertyDef prop in type.Properties)
- yield return prop;
-
- foreach (EventDef evt in type.Events)
- yield return evt;
- }
- }
-
- ///
- /// Finds all definitions of interest in a type.
- ///
- /// The type.
- /// A collection of all required definitions
- public static IEnumerable FindDefinitions(this TypeDef typeDef) {
- yield return typeDef;
-
- foreach (TypeDef nestedType in typeDef.NestedTypes)
- yield return nestedType;
-
- foreach (MethodDef method in typeDef.Methods)
- yield return method;
-
- foreach (FieldDef field in typeDef.Fields)
- yield return field;
-
- foreach (PropertyDef prop in typeDef.Properties)
- yield return prop;
-
- foreach (EventDef evt in typeDef.Events)
- yield return evt;
- }
-
- ///
- /// Determines whether the specified type is visible outside the containing assembly.
- ///
- /// The type.
- /// Visibility of executable modules.
- /// true if the specified type is visible outside the containing assembly; otherwise, false.
- public static bool IsVisibleOutside(this TypeDef typeDef, bool exeNonPublic = true) {
- // Assume executable modules' type is not visible
- if (exeNonPublic && (typeDef.Module.Kind == ModuleKind.Windows || typeDef.Module.Kind == ModuleKind.Console))
- return false;
-
- do {
- if (typeDef.DeclaringType == null)
- return typeDef.IsPublic;
- if (!typeDef.IsNestedPublic && !typeDef.IsNestedFamily && !typeDef.IsNestedFamilyOrAssembly)
- return false;
- typeDef = typeDef.DeclaringType;
- } while (typeDef != null);
-
- throw new UnreachableException();
- }
-
- ///
- /// Determines whether the object has the specified custom attribute.
- ///
- /// The object.
- /// The full name of the type of custom attribute.
- /// true if the specified object has custom attribute; otherwise, false.
- public static bool HasAttribute(this IHasCustomAttribute obj, string fullName) {
- return obj.CustomAttributes.Any(attr => attr.TypeFullName == fullName);
- }
-
- ///
- /// Determines whether the specified type is COM import.
- ///
- /// The type.
- /// true if specified type is COM import; otherwise, false.
- public static bool IsComImport(this TypeDef type) {
- return type.IsImport ||
- type.HasAttribute("System.Runtime.InteropServices.ComImportAttribute") ||
- type.HasAttribute("System.Runtime.InteropServices.TypeLibTypeAttribute");
- }
-
- ///
- /// Determines whether the specified type is compiler generated.
- ///
- /// The type.
- /// true if specified type is compiler generated; otherwise, false.
- public static bool IsCompilerGenerated(this TypeDef type) {
- return type.HasAttribute("System.Runtime.CompilerServices.CompilerGeneratedAttribute");
- }
-
- ///
- /// Determines whether the specified type is a delegate.
- ///
- /// The type.
- /// true if the specified type is a delegate; otherwise, false.
- public static bool IsDelegate(this TypeDef type) {
- if (type.BaseType == null)
- return false;
-
- string fullName = type.BaseType.FullName;
- return fullName == "System.Delegate" || fullName == "System.MulticastDelegate";
- }
-
- ///
- /// Determines whether the specified type is inherited from a base type in corlib.
- ///
- /// The type.
- /// The full name of base type.
- /// true if the specified type is inherited from a base type; otherwise, false.
- public static bool InheritsFromCorlib(this TypeDef type, string baseType) {
- if (type.BaseType == null)
- return false;
-
- TypeDef bas = type;
- do {
- bas = bas.BaseType.ResolveTypeDefThrow();
- if (bas.ReflectionFullName == baseType)
- return true;
- } while (bas.BaseType != null && bas.BaseType.DefinitionAssembly.IsCorLib());
- return false;
- }
-
- ///
- /// Determines whether the specified type is inherited from a base type.
- ///
- /// The type.
- /// The full name of base type.
- /// true if the specified type is inherited from a base type; otherwise, false.
- public static bool InheritsFrom(this TypeDef type, string baseType) {
- if (type.BaseType == null)
- return false;
-
- TypeDef bas = type;
- do {
- bas = bas.BaseType.ResolveTypeDefThrow();
- if (bas.ReflectionFullName == baseType)
- return true;
- } while (bas.BaseType != null);
- return false;
- }
-
- ///
- /// Determines whether the specified type implements the specified interface.
- ///
- /// The type.
- /// The full name of the type of interface.
- /// true if the specified type implements the interface; otherwise, false.
- public static bool Implements(this TypeDef type, string fullName) {
- do {
- foreach (InterfaceImpl iface in type.Interfaces) {
- if (iface.Interface.ReflectionFullName == fullName)
- return true;
- }
-
- if (type.BaseType == null)
- return false;
-
- type = type.BaseType.ResolveTypeDefThrow();
- } while (type != null);
- throw new UnreachableException();
- }
-
- ///
- /// Resolves the method.
- ///
- /// The method to resolve.
- /// A instance.
- /// The method couldn't be resolved.
- public static MethodDef ResolveThrow(this IMethod method) {
- var def = method as MethodDef;
- if (def != null)
- return def;
-
- var spec = method as MethodSpec;
- if (spec != null)
- return spec.Method.ResolveThrow();
-
- return ((MemberRef)method).ResolveMethodThrow();
- }
-
- ///
- /// Resolves the field.
- ///
- /// The field to resolve.
- /// A instance.
- /// The method couldn't be resolved.
- public static FieldDef ResolveThrow(this IField field) {
- var def = field as FieldDef;
- if (def != null)
- return def;
-
- return ((MemberRef)field).ResolveFieldThrow();
- }
-
- ///
- /// Find the basic type reference.
- ///
- /// The type signature to get the basic type.
- /// A instance, or null if the typeSig cannot be resolved to basic type.
- public static ITypeDefOrRef ToBasicTypeDefOrRef(this TypeSig typeSig) {
- while (typeSig.Next != null)
- typeSig = typeSig.Next;
-
- if (typeSig is GenericInstSig)
- return ((GenericInstSig)typeSig).GenericType.TypeDefOrRef;
- if (typeSig is TypeDefOrRefSig)
- return ((TypeDefOrRefSig)typeSig).TypeDefOrRef;
- return null;
- }
-
- ///
- /// Find the type references within the specified type signature.
- ///
- /// The type signature to find the type references.
- /// A list of instance.
- public static IList FindTypeRefs(this TypeSig typeSig) {
- var ret = new List();
- FindTypeRefsInternal(typeSig, ret);
- return ret;
- }
-
- static void FindTypeRefsInternal(TypeSig typeSig, IList ret) {
- while (typeSig.Next != null) {
- if (typeSig is ModifierSig)
- ret.Add(((ModifierSig)typeSig).Modifier);
- typeSig = typeSig.Next;
- }
-
- if (typeSig is GenericInstSig) {
- var genInst = (GenericInstSig)typeSig;
- ret.Add(genInst.GenericType.TypeDefOrRef);
- foreach (TypeSig genArg in genInst.GenericArguments)
- FindTypeRefsInternal(genArg, ret);
- }
- else if (typeSig is TypeDefOrRefSig) {
- var type = ((TypeDefOrRefSig)typeSig).TypeDefOrRef;
- while (type != null) {
- ret.Add(type);
- type = type.DeclaringType;
- }
- }
- }
-
- ///
- /// Determines whether the specified property is public.
- ///
- /// The property.
- /// true if the specified property is public; otherwise, false.
- public static bool IsPublic(this PropertyDef property) {
- if (property.GetMethod != null && property.GetMethod.IsPublic)
- return true;
-
- if (property.SetMethod != null && property.SetMethod.IsPublic)
- return true;
-
- return property.OtherMethods.Any(method => method.IsPublic);
- }
-
- ///
- /// Determines whether the specified property is static.
- ///
- /// The property.
- /// true if the specified property is static; otherwise, false.
- public static bool IsStatic(this PropertyDef property) {
- if (property.GetMethod != null && property.GetMethod.IsStatic)
- return true;
-
- if (property.SetMethod != null && property.SetMethod.IsStatic)
- return true;
-
- return property.OtherMethods.Any(method => method.IsStatic);
- }
-
- ///
- /// Determines whether the specified event is public.
- ///
- /// The event.
- /// true if the specified event is public; otherwise, false.
- public static bool IsPublic(this EventDef evt) {
- if (evt.AddMethod != null && evt.AddMethod.IsPublic)
- return true;
-
- if (evt.RemoveMethod != null && evt.RemoveMethod.IsPublic)
- return true;
-
- if (evt.InvokeMethod != null && evt.InvokeMethod.IsPublic)
- return true;
-
- return evt.OtherMethods.Any(method => method.IsPublic);
- }
-
- ///
- /// Determines whether the specified event is static.
- ///
- /// The event.
- /// true if the specified event is static; otherwise, false.
- public static bool IsStatic(this EventDef evt) {
- if (evt.AddMethod != null && evt.AddMethod.IsStatic)
- return true;
-
- if (evt.RemoveMethod != null && evt.RemoveMethod.IsStatic)
- return true;
-
- if (evt.InvokeMethod != null && evt.InvokeMethod.IsStatic)
- return true;
-
- return evt.OtherMethods.Any(method => method.IsStatic);
- }
-
- ///
- /// Replaces the specified instruction reference with another instruction.
- ///
- /// The method body.
- /// The instruction to replace.
- /// The new instruction.
- public static void ReplaceReference(this CilBody body, Instruction target, Instruction newInstr) {
- foreach (ExceptionHandler eh in body.ExceptionHandlers) {
- if (eh.TryStart == target)
- eh.TryStart = newInstr;
- if (eh.TryEnd == target)
- eh.TryEnd = newInstr;
- if (eh.HandlerStart == target)
- eh.HandlerStart = newInstr;
- if (eh.HandlerEnd == target)
- eh.HandlerEnd = newInstr;
- }
- foreach (Instruction instr in body.Instructions) {
- if (instr.Operand == target)
- instr.Operand = newInstr;
- else if (instr.Operand is Instruction[]) {
- var targets = (Instruction[])instr.Operand;
- for (int i = 0; i < targets.Length; i++)
- if (targets[i] == target)
- targets[i] = newInstr;
- }
- }
- }
-
- ///
- /// Determines whether the specified method is array accessors.
- ///
- /// The method.
- /// true if the specified method is array accessors; otherwise, false.
- public static bool IsArrayAccessors(this IMethod method) {
- var declType = method.DeclaringType.ToTypeSig();
- if (declType is GenericInstSig)
- declType = ((GenericInstSig)declType).GenericType;
-
- if (declType.IsArray) {
- return method.Name == "Get" || method.Name == "Set" || method.Name == "Address";
- }
- return false;
- }
- }
-
-
- ///
- /// wrapper of .
- ///
- public class ImageStream : Stream {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The base stream.
- public ImageStream(IImageStream baseStream) {
- BaseStream = baseStream;
- }
-
- ///
- /// Gets the base stream of this instance.
- ///
- /// The base stream.
- public IImageStream BaseStream { get; private set; }
-
- ///
- public override bool CanRead {
- get { return true; }
- }
-
- ///
- public override bool CanSeek {
- get { return true; }
- }
-
- ///
- public override bool CanWrite {
- get { return false; }
- }
-
- ///
- public override long Length {
- get { return BaseStream.Length; }
- }
-
- ///
- public override long Position {
- get { return BaseStream.Position; }
- set { BaseStream.Position = value; }
- }
-
- ///
- public override void Flush() { }
-
- ///
- public override int Read(byte[] buffer, int offset, int count) {
- return BaseStream.Read(buffer, offset, count);
- }
-
- ///
- public override long Seek(long offset, SeekOrigin origin) {
- switch (origin) {
- case SeekOrigin.Begin:
- BaseStream.Position = offset;
- break;
- case SeekOrigin.Current:
- BaseStream.Position += offset;
- break;
- case SeekOrigin.End:
- BaseStream.Position = BaseStream.Length + offset;
- break;
- }
- return BaseStream.Position;
- }
-
- ///
- public override void SetLength(long value) {
- throw new NotSupportedException();
- }
-
- ///
- public override void Write(byte[] buffer, int offset, int count) {
- throw new NotSupportedException();
- }
- }
+namespace Confuser.Core
+{
+ ///
+ /// Provides a set of utility methods about dnlib
+ ///
+ public static class DnlibUtils
+ {
+ ///
+ /// Finds all definitions of interest in a module.
+ ///
+ /// The module.
+ /// A collection of all required definitions
+ public static IEnumerable FindDefinitions(this ModuleDef module)
+ {
+ yield return module;
+ foreach (TypeDef type in module.GetTypes())
+ {
+ yield return type;
+
+ foreach (MethodDef method in type.Methods)
+ yield return method;
+
+ foreach (FieldDef field in type.Fields)
+ yield return field;
+
+ foreach (PropertyDef prop in type.Properties)
+ yield return prop;
+
+ foreach (EventDef evt in type.Events)
+ yield return evt;
+ }
+ }
+
+ ///
+ /// Finds all definitions of interest in a type.
+ ///
+ /// The type.
+ /// A collection of all required definitions
+ public static IEnumerable FindDefinitions(this TypeDef typeDef)
+ {
+ yield return typeDef;
+
+ foreach (TypeDef nestedType in typeDef.NestedTypes)
+ yield return nestedType;
+
+ foreach (MethodDef method in typeDef.Methods)
+ yield return method;
+
+ foreach (FieldDef field in typeDef.Fields)
+ yield return field;
+
+ foreach (PropertyDef prop in typeDef.Properties)
+ yield return prop;
+
+ foreach (EventDef evt in typeDef.Events)
+ yield return evt;
+ }
+
+ ///
+ /// Determines whether the specified type is visible outside the containing assembly.
+ ///
+ /// The type.
+ /// Visibility of executable modules.
+ /// true if the specified type is visible outside the containing assembly; otherwise, false.
+ public static bool IsVisibleOutside(this TypeDef typeDef, bool exeNonPublic = true)
+ {
+ // Assume executable modules' type is not visible
+ if (exeNonPublic && (typeDef.Module.Kind == ModuleKind.Windows || typeDef.Module.Kind == ModuleKind.Console))
+ return false;
+
+ do
+ {
+ if (typeDef.DeclaringType == null)
+ return typeDef.IsPublic;
+ if (!typeDef.IsNestedPublic && !typeDef.IsNestedFamily && !typeDef.IsNestedFamilyOrAssembly)
+ return false;
+ typeDef = typeDef.DeclaringType;
+ } while (typeDef != null);
+
+ throw new UnreachableException();
+ }
+
+ ///
+ /// Determines whether the object has the specified custom attribute.
+ ///
+ /// The object.
+ /// The full name of the type of custom attribute.
+ /// true if the specified object has custom attribute; otherwise, false.
+ public static bool HasAttribute(this IHasCustomAttribute obj, string fullName)
+ {
+ return obj.CustomAttributes.Any(attr => attr.TypeFullName == fullName);
+ }
+
+ ///
+ /// Determines whether the specified type is COM import.
+ ///
+ /// The type.
+ /// true if specified type is COM import; otherwise, false.
+ public static bool IsComImport(this TypeDef type)
+ {
+ return type.IsImport ||
+ type.HasAttribute("System.Runtime.InteropServices.ComImportAttribute") ||
+ type.HasAttribute("System.Runtime.InteropServices.TypeLibTypeAttribute");
+ }
+
+ ///
+ /// Determines whether the specified type is compiler generated.
+ ///
+ /// The type.
+ /// true if specified type is compiler generated; otherwise, false.
+ public static bool IsCompilerGenerated(this TypeDef type)
+ {
+ return type.HasAttribute("System.Runtime.CompilerServices.CompilerGeneratedAttribute");
+ }
+
+ ///
+ /// Determines whether the specified type is a delegate.
+ ///
+ /// The type.
+ /// true if the specified type is a delegate; otherwise, false.
+ public static bool IsDelegate(this TypeDef type)
+ {
+ if (type.BaseType == null)
+ return false;
+
+ string fullName = type.BaseType.FullName;
+ return fullName == "System.Delegate" || fullName == "System.MulticastDelegate";
+ }
+
+ ///
+ /// Determines whether the specified type is inherited from a base type in corlib.
+ ///
+ /// The type.
+ /// The full name of base type.
+ /// true if the specified type is inherited from a base type; otherwise, false.
+ public static bool InheritsFromCorlib(this TypeDef type, string baseType)
+ {
+ if (type.BaseType == null)
+ return false;
+
+ TypeDef bas = type;
+ do
+ {
+ bas = bas.BaseType.ResolveTypeDefThrow();
+ if (bas.ReflectionFullName == baseType)
+ return true;
+ } while (bas.BaseType != null && bas.BaseType.DefinitionAssembly.IsCorLib());
+ return false;
+ }
+
+ ///
+ /// Determines whether the specified type is inherited from a base type.
+ ///
+ /// The type.
+ /// The full name of base type.
+ /// true if the specified type is inherited from a base type; otherwise, false.
+ public static bool InheritsFrom(this TypeDef type, string baseType)
+ {
+ if (type.BaseType == null)
+ return false;
+
+ TypeDef bas = type;
+ do
+ {
+ bas = bas.BaseType.ResolveTypeDefThrow();
+ if (bas.ReflectionFullName == baseType)
+ return true;
+ } while (bas.BaseType != null);
+ return false;
+ }
+
+ ///
+ /// Determines whether the specified type implements the specified interface.
+ ///
+ /// The type.
+ /// The full name of the type of interface.
+ /// true if the specified type implements the interface; otherwise, false.
+ public static bool Implements(this TypeDef type, string fullName)
+ {
+ do
+ {
+ foreach (InterfaceImpl iface in type.Interfaces)
+ {
+ if (iface.Interface.ReflectionFullName == fullName)
+ return true;
+ }
+
+ if (type.BaseType == null)
+ return false;
+
+ type = type.BaseType.ResolveTypeDefThrow();
+ } while (type != null);
+ throw new UnreachableException();
+ }
+
+ ///
+ /// Resolves the method.
+ ///
+ /// The method to resolve.
+ /// A instance.
+ /// The method couldn't be resolved.
+ public static MethodDef ResolveThrow(this IMethod method)
+ {
+ var def = method as MethodDef;
+ if (def != null)
+ return def;
+
+ var spec = method as MethodSpec;
+ if (spec != null)
+ return spec.Method.ResolveThrow();
+
+ return ((MemberRef)method).ResolveMethodThrow();
+ }
+
+ ///
+ /// Resolves the field.
+ ///
+ /// The field to resolve.
+ /// A instance.
+ /// The method couldn't be resolved.
+ public static FieldDef ResolveThrow(this IField field)
+ {
+ var def = field as FieldDef;
+ if (def != null)
+ return def;
+
+ return ((MemberRef)field).ResolveFieldThrow();
+ }
+
+ ///
+ /// Find the basic type reference.
+ ///
+ /// The type signature to get the basic type.
+ /// A instance, or null if the typeSig cannot be resolved to basic type.
+ public static ITypeDefOrRef ToBasicTypeDefOrRef(this TypeSig typeSig)
+ {
+ while (typeSig.Next != null)
+ typeSig = typeSig.Next;
+
+ if (typeSig is GenericInstSig)
+ return ((GenericInstSig)typeSig).GenericType.TypeDefOrRef;
+ if (typeSig is TypeDefOrRefSig)
+ return ((TypeDefOrRefSig)typeSig).TypeDefOrRef;
+ return null;
+ }
+
+ ///
+ /// Find the type references within the specified type signature.
+ ///
+ /// The type signature to find the type references.
+ /// A list of instance.
+ public static IList FindTypeRefs(this TypeSig typeSig)
+ {
+ var ret = new List();
+ FindTypeRefsInternal(typeSig, ret);
+ return ret;
+ }
+
+ static void FindTypeRefsInternal(TypeSig typeSig, IList ret)
+ {
+ while (typeSig.Next != null)
+ {
+ if (typeSig is ModifierSig)
+ ret.Add(((ModifierSig)typeSig).Modifier);
+ typeSig = typeSig.Next;
+ }
+
+ if (typeSig is GenericInstSig)
+ {
+ var genInst = (GenericInstSig)typeSig;
+ ret.Add(genInst.GenericType.TypeDefOrRef);
+ foreach (TypeSig genArg in genInst.GenericArguments)
+ FindTypeRefsInternal(genArg, ret);
+ }
+ else if (typeSig is TypeDefOrRefSig)
+ {
+ var type = ((TypeDefOrRefSig)typeSig).TypeDefOrRef;
+ while (type != null)
+ {
+ ret.Add(type);
+ type = type.DeclaringType;
+ }
+ }
+ }
+
+ ///
+ /// Determines whether the specified property is public.
+ ///
+ /// The property.
+ /// true if the specified property is public; otherwise, false.
+ public static bool IsPublic(this PropertyDef property)
+ {
+ return property.AllMethods().Any(method => method.IsPublic);
+ }
+
+ ///
+ /// Determines whether the specified property is static.
+ ///
+ /// The property.
+ /// true if the specified property is static; otherwise, false.
+ public static bool IsStatic(this PropertyDef property)
+ {
+ return property.AllMethods().Any(method => method.IsStatic);
+ }
+
+ ///
+ /// Determines whether the specified event is public.
+ ///
+ /// The event.
+ /// true if the specified event is public; otherwise, false.
+ public static bool IsPublic(this EventDef evt)
+ {
+ return evt.AllMethods().Any(method => method.IsPublic);
+ }
+
+ ///
+ /// Determines whether the specified event is static.
+ ///
+ /// The event.
+ /// true if the specified event is static; otherwise, false.
+ public static bool IsStatic(this EventDef evt)
+ {
+ return evt.AllMethods().Any(method => method.IsStatic);
+ }
+
+ ///
+ /// Determines whether the specified method is an explictly implemented interface member.
+ ///
+ /// The method.
+ /// true if the specified method is an explictly implemented interface member; otherwise, false.
+ public static bool IsExplicitlyImplementedInterfaceMember(this MethodDef method)
+ {
+ return method.IsFinal && method.IsPrivate;
+ }
+
+ ///
+ /// Determines whether the specified property is an explictly implemented interface member.
+ ///
+ /// The method.
+ /// true if the specified property is an explictly implemented interface member; otherwise, false.
+ public static bool IsExplicitlyImplementedInterfaceMember(this PropertyDef property)
+ {
+ return property.AllMethods().Any(IsExplicitlyImplementedInterfaceMember);
+ }
+
+ ///
+ /// Determines whether the specified event is an explictly implemented interface member.
+ ///
+ /// The event.
+ /// true if the specified eve is an explictly implemented interface member; otherwise, false.
+ public static bool IsExplicitlyImplementedInterfaceMember(this EventDef evt)
+ {
+ return evt.AllMethods().Any(IsExplicitlyImplementedInterfaceMember);
+ }
+
+ private static IEnumerable AllMethods(this EventDef evt)
+ {
+ return new[] { evt.AddMethod, evt.RemoveMethod, evt.InvokeMethod }
+ .Concat(evt.OtherMethods)
+ .Where(m => m != null);
+ }
+
+ private static IEnumerable AllMethods(this PropertyDef property)
+ {
+ return new[] { property.GetMethod, property.SetMethod }
+ .Concat(property.OtherMethods)
+ .Where(m => m != null);
+ }
+
+ ///
+ /// Replaces the specified instruction reference with another instruction.
+ ///
+ /// The method body.
+ /// The instruction to replace.
+ /// The new instruction.
+ public static void ReplaceReference(this CilBody body, Instruction target, Instruction newInstr)
+ {
+ foreach (ExceptionHandler eh in body.ExceptionHandlers)
+ {
+ if (eh.TryStart == target)
+ eh.TryStart = newInstr;
+ if (eh.TryEnd == target)
+ eh.TryEnd = newInstr;
+ if (eh.HandlerStart == target)
+ eh.HandlerStart = newInstr;
+ if (eh.HandlerEnd == target)
+ eh.HandlerEnd = newInstr;
+ }
+ foreach (Instruction instr in body.Instructions)
+ {
+ if (instr.Operand == target)
+ instr.Operand = newInstr;
+ else if (instr.Operand is Instruction[])
+ {
+ var targets = (Instruction[])instr.Operand;
+ for (int i = 0; i < targets.Length; i++)
+ if (targets[i] == target)
+ targets[i] = newInstr;
+ }
+ }
+ }
+
+ ///
+ /// Determines whether the specified method is array accessors.
+ ///
+ /// The method.
+ /// true if the specified method is array accessors; otherwise, false.
+ public static bool IsArrayAccessors(this IMethod method)
+ {
+ var declType = method.DeclaringType.ToTypeSig();
+ if (declType is GenericInstSig)
+ declType = ((GenericInstSig)declType).GenericType;
+
+ if (declType.IsArray)
+ {
+ return method.Name == "Get" || method.Name == "Set" || method.Name == "Address";
+ }
+ return false;
+ }
+ }
+
+
+ ///
+ /// wrapper of .
+ ///
+ public class ImageStream : Stream
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The base stream.
+ public ImageStream(IImageStream baseStream)
+ {
+ BaseStream = baseStream;
+ }
+
+ ///
+ /// Gets the base stream of this instance.
+ ///
+ /// The base stream.
+ public IImageStream BaseStream { get; private set; }
+
+ ///
+ public override bool CanRead
+ {
+ get { return true; }
+ }
+
+ ///
+ public override bool CanSeek
+ {
+ get { return true; }
+ }
+
+ ///
+ public override bool CanWrite
+ {
+ get { return false; }
+ }
+
+ ///
+ public override long Length
+ {
+ get { return BaseStream.Length; }
+ }
+
+ ///
+ public override long Position
+ {
+ get { return BaseStream.Position; }
+ set { BaseStream.Position = value; }
+ }
+
+ ///
+ public override void Flush() { }
+
+ ///
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ return BaseStream.Read(buffer, offset, count);
+ }
+
+ ///
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ switch (origin)
+ {
+ case SeekOrigin.Begin:
+ BaseStream.Position = offset;
+ break;
+ case SeekOrigin.Current:
+ BaseStream.Position += offset;
+ break;
+ case SeekOrigin.End:
+ BaseStream.Position = BaseStream.Length + offset;
+ break;
+ }
+ return BaseStream.Position;
+ }
+
+ ///
+ public override void SetLength(long value)
+ {
+ throw new NotSupportedException();
+ }
+
+ ///
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ throw new NotSupportedException();
+ }
+ }
}
\ No newline at end of file