/// <summary> /// Perform "get-key" verb. /// </summary> /// <param name="options">Options</param> static void DoGetKey(MonoOptions options) { EazModule module; if (!TryLoadModule(options.AssemblyPath, out module)) { return; } MethodStub method = module.FindFirstVirtualizedMethod(); Console.WriteLine("Key: {0}", method.ResourceCryptoKey); }
/// <summary> /// Perform "resource" verb. /// </summary> /// <param name="options">Options</param> static void DoResource(MonoOptions options) { EazModule module; if (!TryLoadModule(options.AssemblyPath, out module)) { return; } // If no action set, set the default action (extract) //if (!options.Extract) // options.Extract = true; MethodStub method = module.FindFirstVirtualizedMethod(); if (method != null) { if (true /* options.Extract */) { String outputPath = options.OutputPath; if (outputPath == null || outputPath.Equals("")) { outputPath = method.ResourceStringId; } FileMode fileMode = FileMode.CreateNew; if (options.OverwriteExisting) { fileMode = FileMode.Create; } using (Stream resourceStream = module.GetResourceStream(options.KeepEncrypted)) { try { using (FileStream fileStream = new FileStream(outputPath, fileMode, FileAccess.Write)) { resourceStream.CopyTo(fileStream); } } catch (IOException e) { Console.Write(e); } } Console.WriteLine("Extracted {0} resource to {1}", options.KeepEncrypted ? "encrypted" : "decrypted", outputPath); } } }
/// <summary> /// Perform "position" verb. /// </summary> /// <param name="options">Options</param> static void DoPosition(MonoOptions options) { IPositionTranslator translator = PositionTranslator.DefaultInstance; Int64 position = 0; if (options.Key.HasValue) { // This doesn't work yet: Command line parser can't parse Nullable? position = translator.ToPosition(options.PositionString, options.Key.Value); } else if (options.AssemblyPath != null) { EazModule module; if (!TryLoadModule(options.AssemblyPath, out module)) { return; } MethodStub method = module.FindFirstVirtualizedMethod(); if (method != null) { try { position = translator.ToPosition(options.PositionString, method.ResourceCryptoKey); } catch (FormatException e) { Console.WriteLine(e.Message); return; } } else { Console.WriteLine("No virtualized methods found in specified assembly"); return; } } else { Console.WriteLine("Provide either the crypto key or assembly from which to extract the crypto key"); return; } Console.WriteLine("{0} => {1:X8}", options.PositionString, position); }
/// <summary> /// Perform "position" verb. /// </summary> /// <param name="options">Options</param> static void DoPosition(MonoOptions options) { Int64 position = 0; if (options.AssemblyPath != null) { EazModule module; if (!TryLoadModule(options.AssemblyPath, out module)) { return; } IPositionTranslator translator = module.PositionTranslator; MethodStub method = module.FindFirstVirtualizedMethod(); if (method != null) { try { position = translator.ToPosition(options.PositionString, method.ResourceCryptoKey); } catch (FormatException e) { Console.WriteLine(e.Message); return; } } else { Console.WriteLine("No virtualized methods found in specified assembly"); return; } } else { Console.WriteLine("Provide either the crypto key or assembly from which to extract the crypto key"); return; } Console.WriteLine("{0} => {1:X8}", options.PositionString, position); }
/// <summary> /// Perform "instructions" verb. /// </summary> /// <param name="options">Options</param> static void DoInstructions(MonoOptions options) { EazModule module; if (!TryLoadModule(options.AssemblyPath, out module)) { return; } MethodStub method = module.FindFirstVirtualizedMethod(); if (method == null) { Console.WriteLine("No methods in assembly seem to be virtualized"); return; } // The virtual-call-method should belong to the main virtualization type TypeDef virtualizationType = method.VirtualCallMethod.DeclaringType; var vInstructions = module.VirtualInstructions; if (vInstructions.Count > 0) { // Get # of identified instructions Int32 identified = 0; foreach (var v in vInstructions) { if (v.IsIdentified) { identified++; } } // Get % of identified instructions as a string String percentIdentified; if (identified == 0) { percentIdentified = "0%"; } else if (identified == vInstructions.Count) { percentIdentified = "100%"; } else { percentIdentified = Math.Floor( (((double)identified) / ((double)vInstructions.Count)) * 100d ) + "%"; } Console.WriteLine("Virtual instruction types found: {0}", vInstructions.Count); Console.WriteLine("{0}/{1} instruction types identified ({2})", identified, vInstructions.Count, percentIdentified); if (!options.Verbose) { Console.WriteLine(); } // If only showing identified instructions, remove all non-identified and sort by name if (options.OnlyIdentified) { vInstructions = new List <VirtualOpCode>(vInstructions .Where((instruction) => { return(instruction.IsIdentified); }) .OrderBy((instruction) => { return(instruction.Name); })); } // If only showing instructions with specific virtual operand types, filter if (options.OperandTypeWhitelist != Int32.MinValue) { vInstructions = new List <VirtualOpCode>(vInstructions .Where((instruction) => { return(options.OperandTypeWhitelist == instruction.VirtualOperandType); })); } foreach (var v in vInstructions) { if (!options.Verbose) // Simple output { if (v.IsIdentified) { Console.WriteLine("Instruction: {0}, Method: {1}", v.Name, v.DelegateMethod.FullName); } else { Console.WriteLine("Instruction: Unknown, Method: {0}", v.DelegateMethod.FullName); } } else // Not-Simple output? { Console.WriteLine(); if (v.IsIdentified) { Console.WriteLine("Instruction: {0}", v.Name); } else { Console.WriteLine("Instruction: Unknown"); } if (v.IsIdentified || !options.OnlyIdentified) { if (v.HasVirtualCode) { Console.WriteLine("--> Virtual OpCode: {0} ({0:X8})", v.VirtualCode); Console.WriteLine("--> Operand type: {0}", v.VirtualOperandType); } { Console.WriteLine("--> Delegate method: {0}", v.DelegateMethod.FullName); } } } } // Print operand information if (options.Operands) { var operandTypeDict = new Dictionary <Int32, Int32>(); foreach (var vInstr in vInstructions) { var type = vInstr.VirtualOperandType; if (operandTypeDict.ContainsKey(type)) { operandTypeDict[type] = (operandTypeDict[type] + 1); } else { operandTypeDict.Add(type, 1); } } Console.WriteLine(); Console.WriteLine("Virtual operand type counts:"); foreach (var kvp in operandTypeDict) { Console.WriteLine(" Operand {0}: {1} occurrence(s)", kvp.Key, kvp.Value); } } } else { Console.WriteLine("No virtual instructions found?"); } }
/// <summary> /// Constructs a successful devirtualize attempt. /// </summary> /// <param name="vmethod">Virtualized method</param> /// <param name="reader">Method body reader</param> /// <param name="body">Devirtualized method body</param> public DevirtualizeAttempt(MethodStub vmethod, VirtualizedMethodBodyReader reader, CilBody body) { this.VirtualizedMethod = vmethod; this.Reader = reader; this.MethodBody = body; }
/// <summary> /// Constructs a failed devirtualize attempt. /// </summary> /// <param name="vmethod">Virtualized method</param> /// <param name="reader">Method body reader</param> /// <param name="exception">Exception that occurred while devirtualizing</param> public DevirtualizeAttempt(MethodStub vmethod, VirtualizedMethodBodyReader reader, Exception exception) { this.VirtualizedMethod = vmethod; this.Reader = reader; this.Exception = exception; }