public void Execute(DevirtualizationCtx ctx)
 {
     ctx.VirtualizedMethods = new List <VirtualizedMethod>();
     foreach (var type in ctx.Module.TopLevelTypes)
     {
         foreach (var method in type.Methods.Where(q =>
                                                   !q.IsNative && q.CilMethodBody != null && q.CilMethodBody.Instructions.Count >= 6 &&
                                                   q.CustomAttributes.Count >= 1))
         {
             var vmAttribute = method.CustomAttributes.First(q =>
                                                             q.Signature.FixedArguments.Count == 2 &&
                                                             q.Signature.FixedArguments[0].ArgumentType == ctx.Module.CorLibTypeFactory.String &&
                                                             q.Signature.FixedArguments[1].ArgumentType == ctx.Module.CorLibTypeFactory.Int32);
             if (vmAttribute == null)
             {
                 continue;
             }
             var virtualizedMethod = new VirtualizedMethod(method,
                                                           (string)vmAttribute.Signature.FixedArguments[0].Element.Value,
                                                           (int)vmAttribute.Signature.FixedArguments[1].Element.Value);
             ctx.VirtualizedMethods.Add(virtualizedMethod);
             if (ctx.Options.Verbose)
             {
                 ctx.Logger.Success(
                     $"Found Virtualized Method [{method.Name}] with ID [{virtualizedMethod.Id}] and Key [{virtualizedMethod.Key}]");
             }
         }
     }
 }
Esempio n. 2
0
        public void Run(DevirtualizationCtx Ctx)
        {
            Ctx.PatternMatcher = new PatternMatcher();

            var opcodeHandlerMethod = FindOpCodeMethod(Ctx.Module);

            if (opcodeHandlerMethod == null)
            {
                throw new DevirtualizationException("Could not locate Opcode Handler method.");
            }
            Ctx.Options.Logger.Success($"Found method {opcodeHandlerMethod.Name} that contains Opcode Handlers!");

            var switchOpCode = opcodeHandlerMethod.CilMethodBody.Instructions.First(q => q.OpCode == CilOpCodes.Switch);

            var values = (List <ICilLabel>)switchOpCode.Operand;

            for (var i = 0; i < values.Count; i++)
            {
                var instructionLabel = (CilInstructionLabel)values[i];
                var index            = opcodeHandlerMethod.CilMethodBody.Instructions.IndexOf(instructionLabel.Instruction);
                var opCode           = Ctx.PatternMatcher.FindOpCode(opcodeHandlerMethod, index);
                if (opCode != VMOpCode.Nop)
                {
                    Ctx.PatternMatcher.SetOpCodeValue(opCode, i);
                }
            }
        }
Esempio n. 3
0
 public void Run(DevirtualizationCtx Ctx)
 {
     Ctx.Parser = new ResourceParser().Parse(Ctx);
     Ctx.Options.Logger.Success("Successfully Parsed Resource!");
     Ctx.Options.Logger.InfoStr("Strings Read", Ctx.Parser.Strings.Length.ToString());
     Ctx.Options.Logger.InfoStr("MethodKeys Read", Ctx.Parser.MethodKeys.Length.ToString());
     Ctx.Options.Logger.InfoStr("Operands Read", Ctx.Parser.Operands.Length.ToString());
 }
Esempio n. 4
0
 public Devirtualizer(DevirtualizationCtx Ctx)
 {
     this.Ctx = Ctx;
     Stages   = new List <IStage>
     {
         new ResourceParsing(),
         new OpcodeMapping(),
         new MethodDisassembling()
     };
 }
Esempio n. 5
0
        public void Run(DevirtualizationCtx Ctx)
        {
            Ctx.VirtualizedMethods = new List <VMMethod>();
            var disassembler = new VMDisassembler(Ctx);

            for (var i = 0; i < Ctx.Parser.MethodKeys.Length; i++)
            {
                var method = disassembler.DisassembleMethod(Ctx.Parser.MethodKeys[i]);
                Ctx.VirtualizedMethods.Add(method);
            }
        }
Esempio n. 6
0
        private static void Main(string[] args)
        {
            var logger = new ConsoleLogger();

            Console.Title = $"Krypton - {CurrentVersion}";
            var opts          = new DevirtualizationOptions(args[0], logger);
            var ctx           = new DevirtualizationCtx(opts);
            var devirtualizer = new Devirtualizer(ctx);

            devirtualizer.Devirtualize();
            devirtualizer.Save();
            Console.ReadLine();
        }
Esempio n. 7
0
        public ResourceParser Parse(DevirtualizationCtx Ctx)
        {
            var resource = Ctx.Module.Resources.First(q => q.Name.Length == 37);

            if (resource == null)
            {
                throw new DevirtualizationException("Could not locate Resource!");
            }

            var data = resource.GetData();

            Ctx.Options.Logger.Success(
                $"Located Resource With Name {resource.Name} And Byte Data Length {data.Length}");

            Reader   = new BinaryReader(new MemoryStream(data));
            Operands = new byte[255];

            var length = ReadEncryptedByte();

            for (var i = 0; i < length; i++)
            {
                var index = Reader.ReadByte();
                Operands[index] = Reader.ReadByte();
            }

            length  = ReadEncryptedByte();
            Strings = new string[length];
            for (var i = 0; i < length; i++)
            {
                Strings[i] = Encoding.Unicode.GetString(Reader.ReadBytes(ReadEncryptedByte()));
            }

            length     = ReadEncryptedByte();
            MethodKeys = new int[length];
            for (var i = 0; i < length; i++)
            {
                MethodKeys[i] = ReadEncryptedByte();
            }

            var pos = (int)Reader.BaseStream.Position;

            for (var i = 0; i < length; i++)
            {
                var res = MethodKeys[i];
                MethodKeys[i] = pos;
                pos          += res;
            }

            return(this);
        }
Esempio n. 8
0
        public void Execute(DevirtualizationCtx ctx)
        {
            foreach (var virtualizedMethod in ctx.VirtualizedMethods)
            {
                if (virtualizedMethod.Instructions == null || virtualizedMethod.Instructions.Count == 0)
                {
                    ctx.Logger.Error($"Couldn't find any instructions for method [{virtualizedMethod.Parent.Name}]");
                    continue;
                }

                var recompiledBody = virtualizedMethod.CreateBody();
                virtualizedMethod.Parent.CilMethodBody = recompiledBody;
                if (ctx.Options.Verbose)
                {
                    ctx.Logger.Success($"Recompiled CilMethodBody for method [{virtualizedMethod.Parent.Name}]");
                }
            }
        }
Esempio n. 9
0
        private static void Main(string[] args)
        {
            var logger = new Logger();

            if (args.Length == 0)
            {
                logger.Error("This is a command line executable.");
                Console.ReadKey(true);
                Environment.Exit(0);
            }

            logger.ShowInfo(CurrentVersion);

            var options2 = Parser.Default.ParseArguments <CommandLineOptions>(args)
                           .WithParsed(o =>
            {
                if (o.Verbose)
                {
                    logger.Info("Verbose Output Enabled!");
                }
            });

            if (options2.Tag == ParserResultType.NotParsed)
            {
                return;
            }
            var options = (Parsed <CommandLineOptions>)options2;

            var ctx    = new DevirtualizationCtx(args[0], options.Value, logger);
            var devirt = new Devirtualizor(ctx);

            if (options.Value.Verbose)
            {
                for (var i = 0; i < devirt.Stages.Count; i++)
                {
                    logger.Info($"Stage[{i + 1}] ({devirt.Stages[i].Name}) - ({devirt.Stages[i].Description})");
                }
            }

            devirt.Devirtualize();
            devirt.Write();
            Console.ReadLine();
        }
Esempio n. 10
0
 public void Execute(DevirtualizationCtx ctx)
 {
     if (!ctx.Options.RecoverVariableTypes)
     {
         return;
     }
     foreach (var method in ctx.VirtualizedMethods)
     {
         var parentMethod = method.Parent;
         CleanupUnusedVariables(parentMethod);
         RecoverVariableTypes(parentMethod);
         if (ctx.Options.Verbose)
         {
             foreach (var variable in method.Parent.CilMethodBody.LocalVariables.Where(q =>
                                                                                       q.VariableType != ctx.Module.CorLibTypeFactory.Object))
             {
                 ctx.Logger.Success(
                     $"Recovered Variable Type [{variable.VariableType.Name}] on Variable Index [{variable.Index}] On Method [{method.Parent.Name}]");
             }
         }
     }
 }
Esempio n. 11
0
 public void Execute(DevirtualizationCtx ctx)
 {
     foreach (var virtualizedMethod in ctx.VirtualizedMethods)
     {
         if (virtualizedMethod.Instructions != null && virtualizedMethod.Instructions.Count == 0)
         {
             continue;
         }
         var vmAttribute = virtualizedMethod.Parent.CustomAttributes.First(q =>
                                                                           q.Signature.FixedArguments.Count == 2 &&
                                                                           q.Signature.FixedArguments[0].ArgumentType == ctx.Module.CorLibTypeFactory.String &&
                                                                           q.Signature.FixedArguments[1].ArgumentType == ctx.Module.CorLibTypeFactory.Int32);
         virtualizedMethod.Parent.CustomAttributes.Remove(vmAttribute);
         var stream = ctx.Module.Resources.First(q => q.Name == virtualizedMethod.Id);
         ctx.Module.Resources.Remove(stream);
         if (ctx.Options.Verbose)
         {
             ctx.Logger.Success(
                 $"Removed vmAttribute And Resource Stream On Method [{virtualizedMethod.Parent.Name}]");
         }
         virtualizedMethod.Parent.CilMethodBody.Instructions.OptimizeMacros();
     }
 }
Esempio n. 12
0
 public VMDisassembler(DevirtualizationCtx Ctx)
 {
     this.Ctx = Ctx;
 }
Esempio n. 13
0
        public void Execute(DevirtualizationCtx ctx)
        {
            foreach (var virtualizedMethod in ctx.VirtualizedMethods)
            {
                var stream = ctx.Module.Resources.First(q => q.Name == virtualizedMethod.Id);
                if (stream == null)
                {
                    ctx.Logger.Error($"Coulnd't find resource stream {virtualizedMethod.Id}");
                    continue;
                }

                var instructions = stream.GetData();
                if (instructions == null)
                {
                    ctx.Logger.Error($"Resource {virtualizedMethod.Id} has no instructions!");
                    continue;
                }

                instructions = instructions.Select(q => (byte)(q ^ virtualizedMethod.Key)).ToArray();
                var binaryReader = new BinaryReader(new MemoryStream(instructions));
                virtualizedMethod.Instructions = new List <vmInstruction>(binaryReader.ReadInt32());

                for (var i = 0; i < virtualizedMethod.Instructions.Capacity; i++)
                {
                    var instruction = new vmInstruction((vmOpCode)binaryReader.ReadInt32());
                    if (binaryReader.ReadBoolean())
                    {
                        switch (binaryReader.ReadInt32())
                        {
                        case 0:
                            instruction.Operand = binaryReader.ReadString();
                            break;

                        case 1:
                            instruction.Operand = binaryReader.ReadInt16();
                            break;

                        case 2:
                            instruction.Operand = binaryReader.ReadInt32();
                            break;

                        case 3:
                            instruction.Operand = binaryReader.ReadInt64();
                            break;

                        case 4:
                            instruction.Operand = binaryReader.ReadUInt16();
                            break;

                        case 5:
                            instruction.Operand = binaryReader.ReadUInt32();
                            break;

                        case 6:
                            instruction.Operand = binaryReader.ReadUInt64();
                            break;

                        case 7:
                            instruction.Operand = binaryReader.ReadDouble();
                            break;

                        case 8:
                            instruction.Operand = binaryReader.ReadDecimal();
                            break;

                        case 9:
                            instruction.Operand = binaryReader.ReadByte();
                            break;

                        case 10:
                            instruction.Operand = binaryReader.ReadSByte();
                            break;

                        case 11:
                            instruction.Operand = binaryReader.ReadSingle();
                            break;

                        case 12:
                            instruction.Operand = null;
                            break;
                        }
                    }

                    virtualizedMethod.Instructions.Add(instruction);
                }

                if (virtualizedMethod.Instructions.Count != 0 && ctx.Options.Verbose)
                {
                    ctx.Logger.Success(
                        $"Dissasembled [{virtualizedMethod.Instructions.Count}] VM Instructions on method [{virtualizedMethod.Parent.Name}]");
                }
            }
        }
Esempio n. 14
0
 public Devirtualizor(DevirtualizationCtx ctx)
 {
     Ctx = ctx;
 }