/// <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)"); } }
/// <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(); }
public DevirtualizeResults Devirtualize(DevirtualizeOptions options, Action<DevirtualizeAttempt> attemptCallback) { var methods = this.Parent.FindMethodStubs(); if (methods.Length == 0) return new DevirtualizeResults(); var attempts = new List<DevirtualizeAttempt>(); foreach (var method in methods) { var reader = new VirtualizedMethodBodyReader(method, this.Logger, this.Parent.Version); Exception exception = null, fixerException = null; try { reader.Read(); // Read method } catch (Exception e) { exception = e; } DevirtualizeAttempt attempt; if (exception == null) { var body = new CilBody( true, reader.Instructions, reader.ExceptionHandlers, reader.Locals ); method.Method.FreeMethodBody(); method.Method.Body = body; // Perform fixes try { PerformFixes(method.Method); } catch (Exception e) { fixerException = e; } if (fixerException == null) { // Inject DevirtualizedAttribute if specified if (options.HasFlag(DevirtualizeOptions.InjectAttributes)) this.Injector.InjectDevirtualized(method.Method); attempt = new DevirtualizeAttempt(method, reader, body); } else attempt = new DevirtualizeAttempt(method, reader, fixerException); } else attempt = new DevirtualizeAttempt(method, reader, exception); // Add attempt to list and fire callback attempts.Add(attempt); if (attemptCallback != null) attemptCallback(attempt); } return new DevirtualizeResults(attempts); }
public DevirtualizeResults Devirtualize(DevirtualizeOptions options, Action <DevirtualizeAttempt> attemptCallback) { var methods = this.Parent.FindMethodStubs(); if (methods.Length == 0) { return(new DevirtualizeResults()); } var attempts = new List <DevirtualizeAttempt>(); foreach (var method in methods) { var reader = new VirtualizedMethodBodyReader(method, this.Logger); Exception exception = null, fixerException = null; try { reader.Read(); // Read method } catch (Exception e) { exception = e; } DevirtualizeAttempt attempt; if (exception == null) { var body = new CilBody( true, reader.Instructions, reader.ExceptionHandlers, reader.Locals ); method.Method.FreeMethodBody(); method.Method.Body = body; // Perform fixes try { PerformFixes(method.Method); } catch (Exception e) { fixerException = e; } if (fixerException == null) { // Inject DevirtualizedAttribute if specified if (options.HasFlag(DevirtualizeOptions.InjectAttributes)) { this.Injector.InjectDevirtualized(method.Method); } attempt = new DevirtualizeAttempt(method, reader, body); } else { attempt = new DevirtualizeAttempt(method, reader, fixerException); } } else { attempt = new DevirtualizeAttempt(method, reader, exception); } // Add attempt to list and fire callback attempts.Add(attempt); if (attemptCallback != null) { attemptCallback(attempt); } } return(new DevirtualizeResults(attempts)); }
/// <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(); } }