/// <summary>
        /// Print out information about whether or not a devirtualization attempt was
        /// successful, and if not why not.
        /// </summary>
        /// <param name="options">MonoOptions set from passed command-line arguments</param>
        /// <param name="module">EazModule</param>
        /// <param name="attempt">Data about the devirtualization attempt</param>
        static void PrintAttemptSuccess(MonoOptions options, EazModule module,
                                        DevirtualizeAttempt attempt)
        {
            var reader = attempt.Reader;

            if (attempt.Successful)
            {
                Console.WriteLine("--> Devirtualizable");
            }
            else if (attempt.WasInstructionUnknown)
            {
                var matches = module.VirtualInstructions
                              .Where((instr) => { return(instr.VirtualCode == reader.LastVirtualOpCode); })
                              .ToArray();

                if (matches.Length > 0)
                {
                    VirtualOpCode v = matches[0];
                    Console.WriteLine("--> Not yet devirtualizable (contains unknown virtual instruction)");
                    Console.WriteLine("-----> Virtual OpCode = {0} @ [{1}] (0x{2:X8})",
                                      reader.LastVirtualOpCode, reader.CurrentInstructionOffset, reader.CurrentVirtualOffset);
                    Console.WriteLine("-----> Delegate method: {0} (MDToken = 0x{1:X8})",
                                      v.DelegateMethod.FullName, v.DelegateMethod.MDToken.Raw);
                }
                else
                {
                    Console.WriteLine("--> Not yet devirtualizable (contains unexpected virtual instruction @ [{0}] (0x{1:X8}))",
                                      reader.CurrentInstructionOffset, reader.CurrentVirtualOffset);
                }
            }
            else
            {
                Console.WriteLine("--> Not yet devirtualizable (threw exception)");
            }
        }
		/// <summary>
		/// Print out information about whether or not a devirtualization attempt was
		/// successful, and if not why not.
		/// </summary>
		/// <param name="options">MonoOptions set from passed command-line arguments</param>
		/// <param name="module">EazModule</param>
		/// <param name="attempt">Data about the devirtualization attempt</param>
		static void PrintAttemptSuccess(MonoOptions options, EazModule module,
			DevirtualizeAttempt attempt)
		{
			var reader = attempt.Reader;

			if (attempt.Successful)
				Console.WriteLine("--> Devirtualizable");
			else if (attempt.WasInstructionUnknown)
			{
				var matches = module.VirtualInstructions
							.Where((instr) => { return instr.VirtualCode == reader.LastVirtualOpCode; })
							.ToArray();

				if (matches.Length > 0)
				{
					VirtualOpCode v = matches[0];
					Console.WriteLine("--> Not yet devirtualizable (contains unknown virtual instruction)");
					Console.WriteLine("-----> Virtual OpCode = {0} @ [{1}] (0x{2:X8})",
						reader.LastVirtualOpCode, reader.CurrentInstructionOffset, reader.CurrentVirtualOffset);
					Console.WriteLine("-----> Delegate method: {0} (MDToken = 0x{1:X8})",
						v.DelegateMethod.FullName, v.DelegateMethod.MDToken.Raw);
				}
				else
				{
					Console.WriteLine("--> Not yet devirtualizable (contains unexpected virtual instruction @ [{0}] (0x{1:X8}))",
						reader.CurrentInstructionOffset, reader.CurrentVirtualOffset);
				}
			}
			else
				Console.WriteLine("--> Not yet devirtualizable (threw exception)");
		}
Exemple #3
0
 public Devirtualizer(EazModule module, DevirtualizeOptions options, IList <Type> fixers, ILogger logger)
 {
     this.Parent   = module;
     this.Options  = options;
     this.Injector = new AttributeInjector(module);
     this.Fixers   = (fixers != null ? fixers : new List <Type>());
     this.Logger   = (logger != null ? logger : DummyLogger.NoThrowInstance);
 }
		public Devirtualizer(EazModule module, DevirtualizeOptions options, IList<Type> fixers, ILogger logger)
		{
			this.Parent = module;
			this.Options = options;
			this.Injector = new AttributeInjector(module);
			this.Fixers = (fixers != null ? fixers : new List<Type>());
			this.Logger = (logger != null ? logger : DummyLogger.NoThrowInstance);
		}
		public VirtualMachineType(EazModule module, ILogger logger)
		{
			if (module == null)
				throw new ArgumentNullException();

			this.Parent = module;
			this.Logger = (logger != null ? logger : DummyLogger.NoThrowInstance);

			this.Initialize();
		}
        public VirtualMachineType(EazModule module, ILogger logger)
        {
            if (module == null)
            {
                throw new ArgumentNullException();
            }

            this.Parent = module;
            this.Logger = (logger != null ? logger : DummyLogger.NoThrowInstance);

            this.Initialize();
        }
Exemple #7
0
        static Boolean TryLoadModule(String path, ILogger logger, out EazModule module)
        {
            try
            {
                ModuleDefMD      moduleDef   = ModuleDefMD.Load(path);
                AssemblyResolver asmResolver = new AssemblyResolver();
                ModuleContext    modCtx      = new ModuleContext(asmResolver);
                // All resolved assemblies will also get this same modCtx
                asmResolver.DefaultModuleContext = modCtx;
                moduleDef.Context = modCtx;

                foreach (TypeDef typeDef in moduleDef.Types)
                {
                    if (!typeDef.HasMethods)
                    {
                        continue;
                    }
                    foreach (MethodDef method in typeDef.Methods)
                    {
                        if (!method.HasBody || !method.Body.HasInstructions)
                        {
                            continue;
                        }
                        BlockDeobfuscator(method);
                    }
                }

                module = new EazModule(moduleDef, logger);
            }
            catch (IOException e)
            {
                // Console.WriteLine(e.Message);
                Console.Write(e);
                module = null;
                return(false);
            }

            return(true);
        }
Exemple #8
0
        static Boolean TryLoadModule(String path, ILogger logger, out EazModule module)
        {
            try
            {
                ModuleDefMD      moduleDef   = ModuleDefMD.Load(path);
                AssemblyResolver asmResolver = new AssemblyResolver();
                ModuleContext    modCtx      = new ModuleContext(asmResolver);
                // All resolved assemblies will also get this same modCtx
                asmResolver.DefaultModuleContext = modCtx;
                moduleDef.Context = modCtx;

                module = new EazModule(moduleDef, logger);
            }
            catch (IOException e)
            {
                // Console.WriteLine(e.Message);
                Console.Write(e);
                module = null;
                return(false);
            }

            return(true);
        }
		public Devirtualizer(EazModule module)
			: this(module, DevirtualizeOptions.Nothing)
		{
		}
Exemple #10
0
 static Boolean TryLoadModule(String path, out EazModule module)
 {
     return(TryLoadModule(path, null, out module));
 }
		public VirtualMachineType(EazModule module)
			: this(module, null)
		{
		}
Exemple #12
0
        /// <summary>
        /// Find all virtual instructions given the main virtualization type.
        /// </summary>
        /// <param name="module">Module</param>
        /// <param name="virtualizationType">Main virtualization type (class)</param>
        /// <returns>All found virtualization instructions</returns>
        public static IList<VirtualOpCode> FindAllInstructions(EazModule module, TypeDef virtualizationType)
        {
            if (module == null || virtualizationType == null)
                throw new ArgumentNullException();

            // Find dictionary method
            MethodDef dictMethod = null;
            var methods = virtualizationType.Methods;
            foreach(var method in methods)
            {
                if(method.IsPrivate && !method.IsStatic
                && method.Parameters.Count == 1
                && method.HasReturnType
                && method.ReturnType.FullName.StartsWith("System.Collections.Generic.Dictionary"))
                {
                    dictMethod = method;
                    break;
                }
            }

            if (dictMethod == null)
                throw new Exception("Unable to find dictionary method");

            // Each dictionary addition looks like this:
            //IL_000b: ldloc.0  // [0]
            //IL_000c: ldarg.0  // [0]
            //IL_000d: ldfld class Class33 Class805::class33_0 // 0x0400092c // TypeDef of this class (Class33) is important
            //IL_0012: ldfld class Class487 Class33::class487_162 // 0x040000da // FieldDef of this field (class487_162) is important
            //IL_0017: callvirt instance int32 Class487::method_1() // 0x06000ac3
            //IL_001c: ldarg.0  // [0]
            //IL_001d: ldfld class Class33 Class805::class33_0 // 0x0400092c
            //IL_0022: ldfld class Class487 Class33::class487_162 // 0x040000da
            //IL_0027: ldarg.0  // [0]
            //IL_0028: ldftn instance void Class805::method_281(class Class1) // 0x060015ca
            //IL_002e: newobj instance void Class805/Delegate9::.ctor(object, native int) // 0x060015dc
            //IL_0033: newobj instance void Class805/Class808::.ctor(class Class487, class Class805/Delegate9) // 0x060015e5
            //IL_0038: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32, class Class805/Class808>::Add(!0, !1) // 0x0a000b63

            if (!dictMethod.HasBody || !dictMethod.Body.HasInstructions)
                throw new Exception("Dictionary method has no instructions");

            IList<Instruction[]> subsequences = Helpers.FindOpCodePatterns(dictMethod.Body.Instructions, DictionaryAddPattern);

            // Remove this check later..?
            if (subsequences.Count != 203)
                throw new Exception("Number of found subsequences (DictionaryAddPattern) != 203 (expected value)");

            List<VirtualOpCode> vInstructions = new List<VirtualOpCode>();

            TypeDef containerType = null;

            // Each series of instructions represents a virtualized instruction
            foreach(var instrs in subsequences)
            {
                VirtualOpCode vInstruction = new VirtualOpCode();

                containerType = ((FieldDef)instrs[2].Operand).FieldType.TryGetTypeDef(); // ldfld
                FieldDef instructionField = ((FieldDef)instrs[3].Operand); // ldfld
                MethodDef delegateMethod = ((MethodDef)instrs[9].Operand); // ldftn

                vInstruction.Parent = module;
                vInstruction.DictionaryMethod = dictMethod;
                vInstruction.ContainerType = containerType;
                vInstruction.InstructionField = instructionField;
                vInstruction.DelegateMethod = delegateMethod;

                vInstructions.Add(vInstruction);
            }

            if (containerType == null)
                throw new Exception("Container type cannot be null");

            // Get the container .ctor method
            MethodDef containerCtor = null;
            foreach(var m in containerType.FindMethods(".ctor"))
            {
                containerCtor = m;
                break;
            }

            if (containerCtor == null)
                throw new Exception("Container .ctor method cannot be found");

            // Each field construction looks like this:
            //IL_0000: ldarg.0  // [0]
            //IL_0001: ldc.i4 1550052828
            //IL_0006: ldc.i4.5
            //IL_0007: newobj instance void Class487::.ctor(int32, valuetype Enum2) // 0x06000ac1
            //IL_000c: stfld class Class487 Class33::class487_47 // 0x04000067

            if (!containerCtor.HasBody || !containerCtor.Body.HasInstructions)
                throw new Exception("Container .ctor method has no instructions");

            if (containerCtor.Body.Instructions.Count < (vInstructions.Count * 5))
                throw new Exception("Container .ctor not large enough for all virtual instructions");

            // 5 instructions per sequence, with 3 trailing instructions
            int subsequenceCount = (containerCtor.Body.Instructions.Count - 3) / 5;

            // This makes a bit of an assumption..
            for(int i = 0; i < subsequenceCount; i++)
            {
                // Grab the subsequence
                List<Instruction> subsequence = new List<Instruction>();
                for (int j = 0; j < 5; j++)
                    subsequence.Add(containerCtor.Body.Instructions[(i * 5) + j]);

                if (subsequence[0].OpCode.Code != Code.Ldarg_0)
                    throw new Exception("Unexpected opcode in container .ctor subsequence");

                Int32 virtualOpCode = Helpers.GetLdcOperand(subsequence[1]);
                Int32 operandType = Helpers.GetLdcOperand(subsequence[2]);
                FieldDef instructionField = (FieldDef)subsequence[4].Operand;

                // Find virtual instruction with matching instruction field MD token to set
                foreach(var vInstr in vInstructions)
                {
                    if(vInstr.InstructionField.MDToken == instructionField.MDToken)
                    {
                        vInstr.HasVirtualCode = true;
                        vInstr.VirtualCode = virtualOpCode;
                        vInstr.VirtualOperandType = operandType;
                        vInstr.TrySetIdentify(); // Try to identify and set original opcode
                        break;
                    }
                }
            }

            return vInstructions.ToArray();
        }
		public Devirtualizer(EazModule module, DevirtualizeOptions options, ILogger logger)
			: this(module, options, null, logger)
		{
		}
        /// <summary>
        /// Print out information about a devirtualization attempt.
        /// </summary>
        /// <param name="options">MonoOptions set from passed command-line arguments</param>
        /// <param name="module">EazModule</param>
        /// <param name="attempt">Data about the devirtualization attempt</param>
        static void PrintAttempt(MonoOptions options, EazModule module,
                                 DevirtualizeAttempt attempt)
        {
            var reader = attempt.Reader;
            var method = attempt.Method;
            var stub   = attempt.VirtualizedMethod;
            var body   = attempt.MethodBody;

            IList <Local> locals = attempt.Successful ?
                                   body.Variables : reader.Locals;
            IList <ExceptionHandler> handlers = attempt.Successful ?
                                                body.ExceptionHandlers : reader.ExceptionHandlers;
            IList <Instruction> instructions = attempt.Successful ?
                                               body.Instructions : reader.Instructions;

            // Message prefix
            String prefix;

            switch (options.Action)
            {
            case ProgramAction.Devirtualize:
                prefix = "Devirtualized";
                break;

            case ProgramAction.Methods:
            default:
                prefix = "Found";
                break;
            }

            Console.WriteLine("{0} {1} (MDToken = 0x{2:X8})", prefix, method.FullName, method.MDToken.Raw);

            if (options.Action == ProgramAction.Methods || options.Verbose)
            {
                Console.WriteLine("--> Position string: {0}", stub.PositionString);
                Console.WriteLine("--> Position: {0} (0x{0:X8})", stub.Position);
                Console.WriteLine("--> Resource: {0}", stub.ResourceStringId);
                Console.WriteLine("--> Crypto key: {0}", stub.ResourceCryptoKey);
                Console.WriteLine("--> Actual method size: {0} (0x{0:X8})", reader.CodeSize);

                if (options.Action == ProgramAction.Methods)
                {
                    PrintAttemptSuccess(options, module, attempt);
                }
            }

            if (options.Action == ProgramAction.Methods || options.Verbose)
            {
                Console.WriteLine();

                // Print locals
                if (locals.Count > 0)
                {
                    Int32 index = 0;
                    Console.WriteLine("Locals:");
                    Console.WriteLine("-------");
                    foreach (var local in locals)
                    {
                        Console.WriteLine("local[{0}]: {1}", index++, local.Type.FullName);
                    }
                    Console.WriteLine();
                }

                // Print exception handlers
                if (handlers.Count > 0)
                {
                    Int32 index = 0;
                    Console.WriteLine("Exception Handlers:");
                    Console.WriteLine("-------------------");
                    foreach (var handler in handlers)
                    {
                        if (handler.CatchType != null)
                        {
                            Console.WriteLine("handler[{0}]: HandlerType = {1}, CatchType = {2}",
                                              index++, handler.HandlerType, handler.CatchType);
                        }
                        else
                        {
                            Console.WriteLine("handler[{0}]: HandlerType = {1}",
                                              index++, handler.HandlerType);
                        }
                        Console.WriteLine("--> Try:     [{0}, {1}]", handler.TryStart, handler.TryEnd);
                        Console.WriteLine("--> Handler: [{0}, {1}]", handler.HandlerStart, handler.HandlerEnd);
                        Console.WriteLine("--> Filter:  {0}", handler.FilterStart);
                    }
                    Console.WriteLine();
                }

                // Print instructions
                if (instructions != null && instructions.Count > 0)
                {
                    Console.WriteLine("Instructions:");
                    Console.WriteLine("-------------");
                    foreach (var instr in instructions)
                    {
                        Console.WriteLine(instr);
                    }
                    Console.WriteLine();
                }

                // Print out exception, if any
                if (!attempt.Successful && !attempt.WasInstructionUnknown)
                {
                    Console.Write(attempt.Exception);
                    Console.WriteLine();
                    Console.WriteLine();
                }
            }

            if (!(options.Action == ProgramAction.Devirtualize && !options.Verbose))
            {
                Console.WriteLine();
            }
        }
		/// <summary>
		/// Print out information about a devirtualization attempt.
		/// </summary>
		/// <param name="options">MonoOptions set from passed command-line arguments</param>
		/// <param name="module">EazModule</param>
		/// <param name="attempt">Data about the devirtualization attempt</param>
		static void PrintAttempt(MonoOptions options, EazModule module,
			DevirtualizeAttempt attempt)
		{
			var reader = attempt.Reader;
			var method = attempt.Method;
			var stub = attempt.VirtualizedMethod;
			var body = attempt.MethodBody;

			IList<Local> locals = attempt.Successful ?
				body.Variables : reader.Locals;
			IList<ExceptionHandler> handlers = attempt.Successful ?
				body.ExceptionHandlers : reader.ExceptionHandlers;
			IList<Instruction> instructions = attempt.Successful ?
				body.Instructions : reader.Instructions;

			// Message prefix
			String prefix;
			switch(options.Action)
			{
				case ProgramAction.Devirtualize:
					prefix = "Devirtualized";
					break;
				case ProgramAction.Methods:
				default:
					prefix = "Found";
					break;
			}

			Console.WriteLine("{0} {1} (MDToken = 0x{2:X8})", prefix, method.FullName, method.MDToken.Raw);

			if (options.Action == ProgramAction.Methods || options.Verbose)
			{
				Console.WriteLine("--> Position string: {0}", stub.PositionString);
				Console.WriteLine("--> Position: {0} (0x{0:X8})", stub.Position);
				Console.WriteLine("--> Resource: {0}", stub.ResourceStringId);
				Console.WriteLine("--> Crypto key: {0}", stub.ResourceCryptoKey);
				Console.WriteLine("--> Actual method size: {0} (0x{0:X8})", reader.CodeSize);

				if (options.Action == ProgramAction.Methods)
					PrintAttemptSuccess(options, module, attempt);
			}

			if (options.Action == ProgramAction.Methods || options.Verbose)
			{
				Console.WriteLine();

				// Print locals
				if (locals.Count > 0)
				{
					Int32 index = 0;
					Console.WriteLine("Locals:");
					Console.WriteLine("-------");
					foreach (var local in locals)
						Console.WriteLine("local[{0}]: {1}", index++, local.Type.FullName);
					Console.WriteLine();
				}

				// Print exception handlers
				if (handlers.Count > 0)
				{
					Int32 index = 0;
					Console.WriteLine("Exception Handlers:");
					Console.WriteLine("-------------------");
					foreach (var handler in handlers)
					{
						if (handler.CatchType != null)
							Console.WriteLine("handler[{0}]: HandlerType = {1}, CatchType = {2}",
								index++, handler.HandlerType, handler.CatchType);
						else
							Console.WriteLine("handler[{0}]: HandlerType = {1}",
								index++, handler.HandlerType);
						Console.WriteLine("--> Try:     [{0}, {1}]", handler.TryStart, handler.TryEnd);
						Console.WriteLine("--> Handler: [{0}, {1}]", handler.HandlerStart, handler.HandlerEnd);
						Console.WriteLine("--> Filter:  {0}", handler.FilterStart);
					}
					Console.WriteLine();
				}

				// Print instructions
				if (instructions != null && instructions.Count > 0)
				{
					Console.WriteLine("Instructions:");
					Console.WriteLine("-------------");
					foreach (var instr in instructions)
						Console.WriteLine(instr);
					Console.WriteLine();
				}

				// Print out exception, if any
				if (!attempt.Successful && !attempt.WasInstructionUnknown)
				{
					Console.Write(attempt.Exception);
					Console.WriteLine();
					Console.WriteLine();
				}
			}

			if (!(options.Action == ProgramAction.Devirtualize && !options.Verbose))
				Console.WriteLine();
		}
		/// <summary>
		/// Construct an AttributeInjector for a specific module.
		/// </summary>
		/// <param name="module">Target module</param>
		public AttributeInjector(EazModule module)
		{
			this.EazModule = module;
		}
 public VirtualMachineType(EazModule module)
     : this(module, null)
 {
 }
Exemple #18
0
 /// <summary>
 /// Construct a MethodStub from an existing method.
 /// </summary>
 /// <param name="module">Parent module</param>
 /// <param name="method">Stub method</param>
 public MethodStub(EazModule module, MethodDef method)
 {
     this.Parent = module;
     this.Method = method;
     this.Initialize();
 }
Exemple #19
0
 /// <summary>
 /// Construct an AttributeInjector for a specific module.
 /// </summary>
 /// <param name="module">Target module</param>
 public AttributeInjector(EazModule module)
 {
     this.EazModule = module;
 }
Exemple #20
0
		static Boolean TryLoadModule(String path, ILogger logger, out EazModule module)
		{
			try
			{
				ModuleDefMD moduleDef = ModuleDefMD.Load(path);
				AssemblyResolver asmResolver = new AssemblyResolver();
				ModuleContext modCtx = new ModuleContext(asmResolver);
				// All resolved assemblies will also get this same modCtx
				asmResolver.DefaultModuleContext = modCtx;
				moduleDef.Context = modCtx;

				module = new EazModule(moduleDef, logger);
			}
			catch (IOException e)
			{
				// Console.WriteLine(e.Message);
				Console.Write(e);
				module = null;
				return false;
			}

			return true;
		}
Exemple #21
0
		static Boolean TryLoadModule(String path, out EazModule module)
		{
			return TryLoadModule(path, null, out module);
		}
		public Devirtualizer(EazModule module, DevirtualizeOptions options)
			: this(module, options, null)
		{
		}
Exemple #23
0
 public Devirtualizer(EazModule module, ILogger logger)
     : this(module, DevirtualizeOptions.Nothing, logger)
 {
 }
		public Devirtualizer(EazModule module, ILogger logger)
			: this(module, DevirtualizeOptions.Nothing, logger)
		{
		}
Exemple #25
0
 public Devirtualizer(EazModule module, DevirtualizeOptions options, ILogger logger)
     : this(module, options, null, logger)
 {
 }
		public Devirtualizer(EazModule module, IList<Type> fixers, ILogger logger)
			: this(module, DevirtualizeOptions.Nothing, fixers, logger)
		{
		}
Exemple #27
0
 public Devirtualizer(EazModule module, IList <Type> fixers, ILogger logger)
     : this(module, DevirtualizeOptions.Nothing, fixers, logger)
 {
 }
Exemple #28
0
 public Devirtualizer(EazModule module)
     : this(module, DevirtualizeOptions.Nothing)
 {
 }
        /// <summary>
        /// Find all virtual instructions given the main virtualization type.
        /// </summary>
        /// <param name="module">Module</param>
        /// <param name="virtualizationType">Main virtualization type (class)</param>
        /// <returns>All found virtualization instructions</returns>
        public static IList <VirtualOpCode> FindAllInstructions(EazModule module, TypeDef virtualizationType)
        {
            if (module == null || virtualizationType == null)
            {
                throw new ArgumentNullException();
            }

            // Find dictionary method
            MethodDef dictMethod = null;
            var       methods    = virtualizationType.Methods;

            foreach (var method in methods)
            {
                if (method.IsPrivate && !method.IsStatic &&
                    method.Parameters.Count == 1 &&
                    method.HasReturnType &&
                    method.ReturnType.FullName.StartsWith("System.Collections.Generic.Dictionary"))
                {
                    dictMethod = method;
                    break;
                }
            }

            if (dictMethod == null)
            {
                throw new Exception("Unable to find dictionary method");
            }

            // Each dictionary addition looks like this:
            //IL_000b: ldloc.0  // [0]
            //IL_000c: ldarg.0  // [0]
            //IL_000d: ldfld class Class33 Class805::class33_0 // 0x0400092c // TypeDef of this class (Class33) is important
            //IL_0012: ldfld class Class487 Class33::class487_162 // 0x040000da // FieldDef of this field (class487_162) is important
            //IL_0017: callvirt instance int32 Class487::method_1() // 0x06000ac3
            //IL_001c: ldarg.0  // [0]
            //IL_001d: ldfld class Class33 Class805::class33_0 // 0x0400092c
            //IL_0022: ldfld class Class487 Class33::class487_162 // 0x040000da
            //IL_0027: ldarg.0  // [0]
            //IL_0028: ldftn instance void Class805::method_281(class Class1) // 0x060015ca
            //IL_002e: newobj instance void Class805/Delegate9::.ctor(object, native int) // 0x060015dc
            //IL_0033: newobj instance void Class805/Class808::.ctor(class Class487, class Class805/Delegate9) // 0x060015e5
            //IL_0038: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32, class Class805/Class808>::Add(!0, !1) // 0x0a000b63

            if (!dictMethod.HasBody || !dictMethod.Body.HasInstructions)
            {
                throw new Exception("Dictionary method has no instructions");
            }

            IList <Instruction[]> subsequences = Helpers.FindOpCodePatterns(dictMethod.Body.Instructions, DictionaryAddPattern);

            // Remove this check later..?
            if (subsequences.Count != 203)
            {
                throw new Exception(String.Format(
                                        "Number of found subsequences (DictionaryAddPattern) {0} != 203 (expected value)", subsequences.Count));
            }

            List <VirtualOpCode> vInstructions = new List <VirtualOpCode>();

            TypeDef containerType = null;

            // Each series of instructions represents a virtualized instruction
            foreach (var instrs in subsequences)
            {
                VirtualOpCode vInstruction = new VirtualOpCode();

                containerType = ((FieldDef)instrs[2].Operand).FieldType.TryGetTypeDef();   // ldfld
                FieldDef  instructionField = ((FieldDef)instrs[3].Operand);                // ldfld
                MethodDef delegateMethod   = ((MethodDef)instrs[9].Operand);               // ldftn

                vInstruction.Parent           = module;
                vInstruction.DictionaryMethod = dictMethod;
                vInstruction.ContainerType    = containerType;
                vInstruction.InstructionField = instructionField;
                vInstruction.DelegateMethod   = delegateMethod;

                vInstructions.Add(vInstruction);
            }

            if (containerType == null)
            {
                throw new Exception("Container type cannot be null");
            }

            // Get the container .ctor method
            MethodDef containerCtor = null;

            foreach (var m in containerType.FindMethods(".ctor"))
            {
                containerCtor = m;
                break;
            }

            if (containerCtor == null)
            {
                throw new Exception("Container .ctor method cannot be found");
            }

            // Each field construction looks like this:
            //IL_0000: ldarg.0  // [0]
            //IL_0001: ldc.i4 1550052828
            //IL_0006: ldc.i4.5
            //IL_0007: newobj instance void Class487::.ctor(int32, valuetype Enum2) // 0x06000ac1
            //IL_000c: stfld class Class487 Class33::class487_47 // 0x04000067

            if (!containerCtor.HasBody || !containerCtor.Body.HasInstructions)
            {
                throw new Exception("Container .ctor method has no instructions");
            }

            if (containerCtor.Body.Instructions.Count < (vInstructions.Count * 5))
            {
                throw new Exception("Container .ctor not large enough for all virtual instructions");
            }

            // 5 instructions per sequence, with 3 trailing instructions
            int subsequenceCount = (containerCtor.Body.Instructions.Count - 3) / 5;

            // This makes a bit of an assumption..
            for (int i = 0; i < subsequenceCount; i++)
            {
                // Grab the subsequence
                List <Instruction> subsequence = new List <Instruction>();
                for (int j = 0; j < 5; j++)
                {
                    subsequence.Add(containerCtor.Body.Instructions[(i * 5) + j]);
                }

                if (subsequence[0].OpCode.Code != Code.Ldarg_0)
                {
                    throw new Exception("Unexpected opcode in container .ctor subsequence");
                }

                Int32    virtualOpCode    = Helpers.GetLdcOperand(subsequence[1]);
                Int32    operandType      = Helpers.GetLdcOperand(subsequence[2]);
                FieldDef instructionField = (FieldDef)subsequence[4].Operand;

                // Find virtual instruction with matching instruction field MD token to set
                foreach (var vInstr in vInstructions)
                {
                    if (vInstr.InstructionField.MDToken == instructionField.MDToken)
                    {
                        vInstr.HasVirtualCode     = true;
                        vInstr.VirtualCode        = virtualOpCode;
                        vInstr.VirtualOperandType = operandType;
                        vInstr.TrySetIdentify();                         // Try to identify and set original opcode
                        break;
                    }
                }
            }

            return(vInstructions.ToArray());
        }
Exemple #30
0
 /// <summary>
 /// Construct a MethodStub from an existing method.
 /// </summary>
 /// <param name="module">Parent module</param>
 /// <param name="method">Stub method</param>
 public MethodStub(EazModule module, MethodDef method)
 {
     this.Parent = module;
     this.Method = method;
     this.Initialize();
 }
Exemple #31
0
 public Devirtualizer(EazModule module, DevirtualizeOptions options)
     : this(module, options, null)
 {
 }