public bool Execute(DeoxysContext context) { PurgeCtor(context); RemoveDLL(context); context.Cfg.DeclaringType.Fields.Remove(context.Cfg); return(true); }
public bool Execute(DeoxysContext context) { //Locating Nasha0,Nasha1,Nasha2 Sections var peSections = context.PeFile.Sections.Where(q => q.Name != ".text" && q.Name != ".rsrc" && q.Name != ".reloc" && q.Name.Contains("0") || q.Name.Contains("1") || q.Name.Contains("2")).ToList(); if (!peSections.Any()) { return(false); } if (peSections.Count > 3) { peSections = peSections.Where(q => q.Name.Contains("Nasha")).ToList(); } if (peSections.Count == 3) { context.Nasha0 = peSections[0]; context.Logger.Success( $"Located Nasha Section {context.Nasha0.Name} With Offset {context.Nasha0.Offset}"); context.Nasha1 = peSections[1]; context.Logger.Success( $"Located Nasha Section {context.Nasha1.Name} With Offset {context.Nasha1.Offset}"); context.Nasha2 = peSections[2]; context.Logger.Success( $"Located Nasha Section {context.Nasha2.Name} With Offset {context.Nasha2.Offset}"); return(true); } return(false); }
public void RemoveDLL(DeoxysContext context) { //Removing the dll reference var dll = context.Cfg.Signature.FieldType.GetUnderlyingTypeDefOrRef().Scope; context.Module.AssemblyReferences.Remove(new AssemblyReference(dll.GetAssembly())); context.Logger.Success($"Successfully Removed DLL {dll.Name}"); }
public void PurgeCtor(DeoxysContext context) { //Clearing the .ctor var ctor = context.Module.GetOrCreateModuleConstructor(); ctor.CilMethodBody = new CilMethodBody(ctor); ctor.CilMethodBody.Instructions.Add(new CilInstruction(CilOpCodes.Ret)); context.Logger.Success("Purged NashaVM Runtime Initializer"); }
public void RecompileMethods(DeoxysContext context) { var recompiler = new NashaRecompiler(context); foreach (var method in context.DisassembledVirtualizedMethods) { //Recompiling each method recompiler.RecompileMethod(method); } }
public List <NashaMethod> DisassembleAllMethods(DeoxysContext context) { List <NashaMethod> nashaMethods = new List <NashaMethod>(); var methodDisassembler = new NashaMethodDisassembler(context); foreach (var method in context.VirtualizedMethods) { //Disassembling each method nashaMethods.Add(methodDisassembler.DisassembleMethod(method)); } return(nashaMethods); }
public Devirtualizer(DeoxysContext ctx) { Ctx = ctx; DevirtualizationStages = new List <IDevirtualizationStage> { new SectionDetection(), new CfgDetection(), new MethodDetection(), new OpCodeDetection(), new MethodDisassembly(), new MethodRecompiler(), new Cleanup() }; }
public bool Execute(DeoxysContext context) { var extractedOpCodes = ReadOpCodes(context, context.Nasha2.ToArray()); if (extractedOpCodes.Count < 14) { return(false); } foreach (var opCode in extractedOpCodes) { context.DeoxysOpCodes[opCode.RandomValue] = opCode; } return(true); }
public bool Execute(DeoxysContext context) { //Nasha injects some methods to initialize the vm var ctor = context.Module.GetOrCreateModuleConstructor(); var module = ctor.DeclaringType; if (module.Fields.Count >= 1 && ctor.CilMethodBody.Instructions.Count >= 7) { var field = ctor.CilMethodBody.Instructions[1]; if (field.OpCode == CilOpCodes.Stsfld && field.Operand is FieldDefinition fieldDefinition) { context.Cfg = fieldDefinition; context.Logger.Success($"Detected CFG Field [{context.Cfg.Name}] At Constructor {module.Name}"); return(true); } } return(false); }
private List <NashaOpCode> ReadOpCodes(DeoxysContext context, byte[] opcodeValues) { var opCodes = new List <NashaOpCode>(); var reader = new BinaryReader(new MemoryStream(opcodeValues)); reader.BaseStream.Position += 8; //OpCode scrambling seems to have it's flaws. while (reader.BaseStream.Position != reader.BaseStream.Length) { var opc = ReadOpCode(reader); if (opc.Code == (NashaCode)777 || opc.Code == (NashaCode)1337) // seems to be the exit code { break; } opCodes.Add(opc); context.Logger.Info($"Found OpCode {opc.Code} with Random Value {opc.RandomValue}"); } return(opCodes); }
public static void PrintInfo(DeoxysContext Context) { foreach (var line in @" ______ | _ \ | | | |___ _____ ___ _ ___ | | | / _ \/ _ \ \/ / | | / __| | |/ / __/ (_) > <| |_| \__ \ |___/ \___|\___/_/\_\\__, |___/ __/ | |___/ ".Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)) { WriteLineMiddle(line, Color.Red); } Console.WriteLine(); WriteLineMiddle($"Version - {CurrentVersion} | https://github.com/StackUnderflowRE/Deoxys", Color.CornflowerBlue); Console.WriteLine(); Context.Logger.Success($"Loaded file {Context.Module.Name}"); }
private List <NashaOpCode> ReadOpCodes(DeoxysContext context, byte[] opcodeValues) { var opCodes = new List <NashaOpCode>(); var reader = new BinaryReader(new MemoryStream(opcodeValues)); reader.BaseStream.Position += 4; var first = reader.ReadInt32(); //OpCode scrambling seems to have it's flaws. while (reader.BaseStream.Position != reader.BaseStream.Length) { var opc = ReadOpCode(reader); if (opc.Code > (NashaCode)byte.MaxValue) { break; } opCodes.Add(opc); } var newCodes = new List <NashaOpCode>(); int currentId = first; for (int i = 0; i < opCodes.Count; i++) { if (currentId > byte.MaxValue) { break; } var opc = opCodes.First(q => q.Code == (NashaCode)currentId); var newOpCode = new NashaOpCode((NashaCode)i, opc.RandomValue); newCodes.Add(newOpCode); context.Logger.Info($"Found OpCode {newOpCode.Code} with Random Value {newOpCode.RandomValue}"); currentId = opc.NextId; } return(newCodes); }
private void MapMethods(DeoxysContext context) { foreach (var type in context.Module.GetAllTypes()) { foreach (var method in type.Methods.Where(q => q.IsIL && q.CilMethodBody.Instructions.Count >= 7)) { var instructions = method.CilMethodBody.Instructions; if (instructions.First().OpCode == CilOpCodes.Newobj && ((IMethodDescriptor)instructions.First().Operand).DeclaringType != context.Cfg.Signature.FieldType.GetUnderlyingTypeDefOrRef()) { var instructionField = instructions.First(q => q.OpCode == CilOpCodes.Ldsfld); if (instructionField != null) { var index = instructions.IndexOf(instructionField); var methodKey = instructions[index - 1].GetLdcI4Constant(); context.VirtualizedMethods.Add(new NashaMethodInfo(method, methodKey)); context.Logger.Success($"Found Virtualized Method {method.Name} With Key {methodKey}"); } } } } }
public static void Main(string[] args) { Console.Title = $"Deoxys - Version {CurrentVersion} | https://github.com/StackUnderflowRE/Deoxys"; ILogger logger = new ConsoleLogger(); if (args.Length == 0) { logger.Error("Use <Deoxys.exe> --help"); Console.ReadLine(); return; } var options = Parser.Default.ParseArguments <ParseOptions>(args).WithNotParsed(q => { logger.Info($"Usage : <Deoxys.exe> <Input File> <Settings>"); Console.ReadLine(); Environment.Exit(0); }); var deoxysOptions = new DeoxysOptions(args[0], options.Value); var ctx = new DeoxysContext(deoxysOptions, logger); PrintInfo(ctx); var devirtualizer = new Devirtualizer(ctx); bool result = devirtualizer.Devirtualize(); if (result) { devirtualizer.Save(); logger.Success("Finished Devirtualization With No Errors!"); } else { logger.Error("Could not finish Devirtualization."); } Console.ReadLine(); }
public NashaMethodDisassembler(DeoxysContext context) { Context = context; InstructionDisassembler = new NashaInstructionDisassembler(this); }
public bool Execute(DeoxysContext context) { PurgeCtor(context); RemoveDLL(context); return(true); }
public NashaRecompiler(DeoxysContext context) { Context = context; }
public bool Execute(DeoxysContext context) { MapMethods(context); return(context.VirtualizedMethods.Count != 0); }
public NashaOperandResolver(DeoxysContext context) { Context = context; }
public bool Execute(DeoxysContext context) { RecompileMethods(context); return(true); }
public bool Execute(DeoxysContext context) { context.DisassembledVirtualizedMethods = DisassembleAllMethods(context); return(context.DisassembledVirtualizedMethods.Count == context.VirtualizedMethods.Count); }