Exemple #1
0
        public Helper(IModule module, PeReader.DefaultHost host, Log.Log logger)
        {
            this.host   = host;
            this.logger = logger;
            this.module = module;

            // get all needed functions and namespaces
            this.systemString         = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.String");
            this.systemIOTextWriter   = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.IO.TextWriter");
            this.systemIOStreamWriter = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.IO.StreamWriter");
            this.systemInt32          = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.Int32");
            this.systemObject         = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.Object");
            this.systemConsole        = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.Console");
            this.systemRandom         = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.Random");

            ITypeReference[] concatThreeParameterTypes = { this.host.PlatformType.SystemString, this.host.PlatformType.SystemString, this.host.PlatformType.SystemString };
            ITypeReference[] concatTwoParameterTypes   = { this.host.PlatformType.SystemString, this.host.PlatformType.SystemString };
            ITypeReference[] streamWriterAppendTypes   = { this.host.PlatformType.SystemString, this.host.PlatformType.SystemBoolean };

            this.stringConcatThree      = TypeHelper.GetMethod(systemString, this.host.NameTable.GetNameFor("Concat"), concatThreeParameterTypes);
            this.stringConcatTwo        = TypeHelper.GetMethod(systemString, this.host.NameTable.GetNameFor("Concat"), concatTwoParameterTypes);
            this.textWriterWriteLine    = TypeHelper.GetMethod(systemIOTextWriter, this.host.NameTable.GetNameFor("WriteLine"), this.host.PlatformType.SystemString);
            this.streamWriterCtor       = TypeHelper.GetMethod(systemIOStreamWriter, this.host.NameTable.GetNameFor(".ctor"), this.host.PlatformType.SystemString);
            this.streamWriterCtorAppend = TypeHelper.GetMethod(systemIOStreamWriter, this.host.NameTable.GetNameFor(".ctor"), streamWriterAppendTypes);
            this.textWriterWrite        = TypeHelper.GetMethod(systemIOTextWriter, this.host.NameTable.GetNameFor("Write"), this.host.PlatformType.SystemString);
            this.int32ToString          = TypeHelper.GetMethod(systemInt32, this.host.NameTable.GetNameFor("ToString"));
            this.textWriterClose        = TypeHelper.GetMethod(systemIOTextWriter, this.host.NameTable.GetNameFor("Close"));
            this.objectGetHashCode      = TypeHelper.GetMethod(systemObject, this.host.NameTable.GetNameFor("GetHashCode"));
            this.systemConsoleWriteLine = TypeHelper.GetMethod(systemConsole, host.NameTable.GetNameFor("WriteLine"), host.PlatformType.SystemString);
            this.objectCtor             = TypeHelper.GetMethod(systemObject, this.host.NameTable.GetNameFor(".ctor"));
            this.systemRandomCtor       = TypeHelper.GetMethod(systemRandom, this.host.NameTable.GetNameFor(".ctor"));
            this.systemRandomNext       = TypeHelper.GetMethod(systemRandom, this.host.NameTable.GetNameFor("Next"), host.PlatformType.SystemInt32);
        }
        public CfgManipulator(IModule module, PeReader.DefaultHost host, Log.Log logger, MethodCfg methodCfg) {
            this.host = host;
            this.logger = logger;
            this.module = module;

            this.methodCfg = methodCfg;
        }
Exemple #3
0
        public Helper(IModule module, PeReader.DefaultHost host, Log.Log logger)
        {
            this.host = host;
            this.logger = logger;
            this.module = module;

            // get all needed functions and namespaces
            this.systemString = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.String");
            this.systemIOTextWriter = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.IO.TextWriter");
            this.systemIOStreamWriter = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.IO.StreamWriter");
            this.systemInt32 = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.Int32");
            this.systemObject = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.Object");
            this.systemConsole = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.Console");
            this.systemRandom = UnitHelper.FindType(this.host.NameTable, this.host.LoadAssembly(this.host.CoreAssemblySymbolicIdentity), "System.Random");

            ITypeReference[] concatThreeParameterTypes = { this.host.PlatformType.SystemString, this.host.PlatformType.SystemString, this.host.PlatformType.SystemString };
            ITypeReference[] concatTwoParameterTypes = { this.host.PlatformType.SystemString, this.host.PlatformType.SystemString };
            ITypeReference[] streamWriterAppendTypes = { this.host.PlatformType.SystemString, this.host.PlatformType.SystemBoolean };

            this.stringConcatThree = TypeHelper.GetMethod(systemString, this.host.NameTable.GetNameFor("Concat"), concatThreeParameterTypes);
            this.stringConcatTwo = TypeHelper.GetMethod(systemString, this.host.NameTable.GetNameFor("Concat"), concatTwoParameterTypes);
            this.textWriterWriteLine = TypeHelper.GetMethod(systemIOTextWriter, this.host.NameTable.GetNameFor("WriteLine"), this.host.PlatformType.SystemString);
            this.streamWriterCtor = TypeHelper.GetMethod(systemIOStreamWriter, this.host.NameTable.GetNameFor(".ctor"), this.host.PlatformType.SystemString);
            this.streamWriterCtorAppend = TypeHelper.GetMethod(systemIOStreamWriter, this.host.NameTable.GetNameFor(".ctor"), streamWriterAppendTypes);
            this.textWriterWrite = TypeHelper.GetMethod(systemIOTextWriter, this.host.NameTable.GetNameFor("Write"), this.host.PlatformType.SystemString);
            this.int32ToString = TypeHelper.GetMethod(systemInt32, this.host.NameTable.GetNameFor("ToString"));
            this.textWriterClose = TypeHelper.GetMethod(systemIOTextWriter, this.host.NameTable.GetNameFor("Close"));
            this.objectGetHashCode = TypeHelper.GetMethod(systemObject, this.host.NameTable.GetNameFor("GetHashCode"));
            this.systemConsoleWriteLine = TypeHelper.GetMethod(systemConsole, host.NameTable.GetNameFor("WriteLine"), host.PlatformType.SystemString);
            this.objectCtor = TypeHelper.GetMethod(systemObject, this.host.NameTable.GetNameFor(".ctor"));
            this.systemRandomCtor = TypeHelper.GetMethod(systemRandom, this.host.NameTable.GetNameFor(".ctor"));
            this.systemRandomNext = TypeHelper.GetMethod(systemRandom, this.host.NameTable.GetNameFor("Next"), host.PlatformType.SystemInt32);
        }
 public InterfaceTransformer(IModule module, PeReader.DefaultHost host, Log.Log logger)
 {
     this.host        = host;
     this.logger      = logger;
     this.module      = module;
     this.helperClass = new Helper(module, host, logger);
 }
        public InterfaceTransformer(IModule module, PeReader.DefaultHost host, Log.Log logger) {

            this.host = host;
            this.logger = logger;
            this.module = module;
            this.helperClass = new Helper(module, host, logger);

        }
        public CfgManipulator(IModule module, PeReader.DefaultHost host, Log.Log logger, MethodCfg methodCfg)
        {
            this.host   = host;
            this.logger = logger;
            this.module = module;

            this.methodCfg = methodCfg;
        }
Exemple #7
0
        public CodeGenerator(IModule module, PeReader.DefaultHost host, Log.Log logger, Random prng, MethodCfg methodCfg,
                             bool debugging = false, CfgManipulator manipulator = null)
        {
            this.host        = host;
            this.logger      = logger;
            this.module      = module;
            this.prng        = prng;
            this.methodCfg   = methodCfg;
            this.debugging   = debugging;
            this.manipulator = manipulator;

            callableMethods = retrieveCallableMethods();
        }
Exemple #8
0
        public CodeMutator(IModule module, PeReader.DefaultHost host, Log.Log logger, Random prng, MethodCfg methodCfg,
                           CfgManipulator manipulator, bool debugging = false)
        {
            this.host        = host;
            this.logger      = logger;
            this.module      = module;
            this.prng        = prng;
            this.methodCfg   = methodCfg;
            this.debugging   = debugging;
            this.manipulator = manipulator;

            returnBlock = new BasicBlock();
            var exitBranch = new ExitBranchTarget();

            returnBlock.exitBranch = exitBranch;
            returnBlock.operations.Add(createNewOperation(OperationCode.Ret));

            methodCfg.basicBlocks.Add(returnBlock);
        }
        public GraphRandomStateGenerator(IModule module, PeReader.DefaultHost host, Log.Log logger, CfgManipulator cfgManipulator, Helper helperClass, Graph.Graph graph, MethodCfg methodCfg, bool debugging) {

            this.module = module;
            this.host = host;
            this.logger = logger;
            this.cfgManipulator = cfgManipulator;            
            this.helperClass = helperClass;
            this.graph = graph;
            this.methodCfg = methodCfg;
            this.debugging = debugging;

            // add local random generator variable
            this.tempRandomLocal = new LocalDefinition();
            this.tempRandomLocal.IsReference = false;
            this.tempRandomLocal.IsPinned = false;
            this.tempRandomLocal.IsModified = false;
            this.tempRandomLocal.Type = this.helperClass.systemRandom;
            this.tempRandomLocal.MethodDefinition = methodCfg.method;
            cfgManipulator.addLocalVariable(this.tempRandomLocal);


        }
 public NopTransformer(IModule module, PeReader.DefaultHost host, Log.Log logger) {
     this.host = host;
     this.logger = logger;
     this.module = module;
 }
Exemple #11
0
        static void Main(string[] args) {
            String inputFile;
            String targetFile;
            String targetNamespace;
            String targetClass;
            String targetMethod;
            int depth;
            int dimension;
            int numberValidPaths;
            int duplicateBasicBlockWeight;
            int duplicateBasicBlockCorrectionValue;
            int stateChangeWeight;
            int stateChangeCorrectionValue;
            int insertOpaquePredicateWeight;
            int seed;

            // Add debugging code into the obfuscated method (dump obfuscation graphs and so on)
            bool graphTransformerDebug = false;

            // Should the obfuscated code contain information to trace the control flow?
            bool basicBlockTrace = false;

            // When debugging is active, should the whole obfuscation graph be dumped or only the vpaths in it?
            bool graphOnlyDumpVPaths = true;

            // The number of random interfaces that are added to the program
            int numberRandomInterfaces = 100;

            if (args.Length != 14) {
                System.Console.WriteLine("Needed parameters: <inputBinary> <outputBinary> <namespace> <class> <method> <depth> <dimension> <numberValidPaths> <duplicateBasicBlockWeight> <duplicateBasicBlockCorrectionValue> <stateChangeWeight> <stateChangeCorrectionValue> <insertOpaquePredicateWeight> <seed>");
                return;
            }
            else {
                inputFile = args[0];
                targetFile = args[1];
                targetNamespace = args[2];
                targetClass = args[3];
                targetMethod = args[4];
                depth = Convert.ToInt32(args[5]);
                dimension = Convert.ToInt32(args[6]);
                numberValidPaths = Convert.ToInt32(args[7]);
                duplicateBasicBlockWeight = Convert.ToInt32(args[8]);
                duplicateBasicBlockCorrectionValue = Convert.ToInt32(args[9]);
                stateChangeWeight = Convert.ToInt32(args[10]);
                stateChangeCorrectionValue = Convert.ToInt32(args[11]);
                insertOpaquePredicateWeight = Convert.ToInt32(args[12]);
                seed = Convert.ToInt32(args[13]);
            }

            String logDir = Path.GetDirectoryName(targetFile);
            Log.Log logger = new Log.Log(logDir, "probfuscation_logfile.txt");

            System.Console.WriteLine("Obfuscating: " + inputFile);
            logger.writeLine("Obfuscating: " + inputFile);
            System.Console.WriteLine("Output file: " + targetFile);
            logger.writeLine("Output file: " + targetFile);
            System.Console.WriteLine("Target namespace: " + targetNamespace);
            logger.writeLine("Target namespace: " + targetNamespace);
            System.Console.WriteLine("Target class: " + targetClass);
            logger.writeLine("Target class: " + targetClass);
            System.Console.WriteLine("Target method: " + targetMethod);
            logger.writeLine("Target method: " + targetMethod);
            System.Console.WriteLine("Depth: " + depth);
            logger.writeLine("Depth: " + depth);
            System.Console.WriteLine("Dimension: " + dimension);
            logger.writeLine("Dimension: " + dimension);
            System.Console.WriteLine("Number of vpaths: " + numberValidPaths);
            logger.writeLine("Number of vpaths: " + numberValidPaths);
            System.Console.WriteLine("Basic Block duplication weight: " + duplicateBasicBlockWeight);
            logger.writeLine("Basic Block duplication weight: " + duplicateBasicBlockWeight);
            System.Console.WriteLine("Basic Block duplication correction value: " + duplicateBasicBlockCorrectionValue);
            logger.writeLine("Basic Block duplication correction value: " + duplicateBasicBlockCorrectionValue);
            System.Console.WriteLine("State change weight: " + stateChangeWeight);
            logger.writeLine("State change weight: " + stateChangeWeight);
            System.Console.WriteLine("State change correction value: " + stateChangeCorrectionValue);
            logger.writeLine("State change correction value: " + stateChangeCorrectionValue);
            System.Console.WriteLine("Opaque predicate weight: " + insertOpaquePredicateWeight);
            logger.writeLine("Opaque predicate weight: " + insertOpaquePredicateWeight);
            System.Console.WriteLine("Seed: " + seed);
            logger.writeLine("Seed: " + seed);

            // Seed PRNG for interfaces
            PRNGRandomInterfaces = new Random(seed);

            using (var host = new PeReader.DefaultHost()) {
                IModule/*?*/ module = host.LoadUnitFrom(inputFile) as IModule;

                if (module == null || module == Dummy.Module || module == Dummy.Assembly) {
                    Console.WriteLine(inputFile + " is not a PE file containing a CLR module or assembly.");
                    return;
                }

                module = new MetadataDeepCopier(host).Copy(module);

                if (module as Assembly == null) {
                    logger.writeLine("File does not have CIL assembly");
                    return;
                }

                // create analyzer object object                
                CfgBuilder analyze = new Cfg.CfgBuilder(module, host, logger);

                PdbReader/*?*/ pdbReader = null;
                string pdbFile = Path.ChangeExtension(module.Location, "pdb");
                if (File.Exists(pdbFile)) {
                    using (var pdbStream = File.OpenRead(pdbFile)) {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                else {
                    logger.writeLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");
                }

                using (pdbReader) {

                    Microsoft.Cci.ILGenerator.LocalScopeProvider localScopeProvider = null;
                    if (pdbReader != null) {
                        localScopeProvider = new ILGenerator.LocalScopeProvider(pdbReader);
                    }

                    // search the namespace the interface should be added to
                    IUnitNamespace foundNamespace = null;
                    foreach (var tempMember in module.UnitNamespaceRoot.Members) {

                        if ((tempMember as IUnitNamespace) == null) {
                            continue;
                        }

                        IUnitNamespace tempNamespace = (tempMember as IUnitNamespace);

                        if (tempNamespace.ToString() == targetNamespace) {
                            foundNamespace = tempNamespace;
                            break;
                        }
                    }
                    if (foundNamespace == null) {
                        throw new ArgumentException("Not able to find target namespace.");
                    }

                    // add created interface (and implemented methods) to all classes
                    bool classFound = false;
                    foreach (var tempClass in module.GetAllTypes()) {
                        if ((tempClass as NamespaceTypeDefinition) == null
                            || tempClass.IsAbstract) {
                            continue;
                        }

                        NamespaceTypeDefinition foundClass = (tempClass as NamespaceTypeDefinition);

                        if (foundClass.ContainingUnitNamespace.ToString() == "") {
                            continue;
                        }
                        if (foundClass.ToString() != targetNamespace + "." + targetClass) {
                            continue;
                        }
                        classFound = true;

                        Random prng = new Random();
                        GraphTransformer graphTransformer = new GraphTransformer(module, host, logger, prng, foundNamespace, foundClass, depth, dimension, graphTransformerDebug);

                        graphTransformer.duplicateBasicBlockWeight = duplicateBasicBlockWeight;
                        graphTransformer.duplicateBasicBlockCorrectionValue = duplicateBasicBlockCorrectionValue;
                        graphTransformer.stateChangeWeight = stateChangeWeight;
                        graphTransformer.stateChangeCorrectionValue = stateChangeCorrectionValue;
                        graphTransformer.insertOpaquePredicateWeight = insertOpaquePredicateWeight;
                        graphTransformer.trace = basicBlockTrace;
                        graphTransformer.graphOnlyDumpVPaths = graphOnlyDumpVPaths;
                        graphTransformer.debuggingDumpLocation = logDir;

                        // Add 100 random interfaces to the namespace
                        Helper testHelper = new Helper(module, host, logger);
                        List<NamespaceTypeDefinition> randomInterfaces = new List<NamespaceTypeDefinition>();
                        for (int i = 0; i < numberRandomInterfaces; i++) {
                            String randName = randomString(20);
                            NamespaceTypeDefinition temp = testHelper.createNewInterface(randName, foundNamespace);
                            randomInterfaces.Add(temp);
                        }

                        InterfaceTransformer interfaceTransformer = new InterfaceTransformer(module, host, logger);
                        foreach (var classToAdd in module.GetAllTypes()) {
                            if ((classToAdd as NamespaceTypeDefinition) == null
                                || classToAdd.IsAbstract
                                || classToAdd.IsInterface
                                || classToAdd.IsEnum
                                || classToAdd.IsDelegate
                                || classToAdd.IsGeneric
                                || classToAdd.IsStruct) {
                                continue;
                            }

                            if (((NamespaceTypeDefinition)classToAdd).ContainingUnitNamespace.ToString() == "") {
                                continue;
                            }

                            /*
                            // Use this code if you want to add standard interfaces to the target class
                            interfaceTransformer.addStdInterfacesGivenByFile(@"e:\code\dotnet_standard_interfaces.txt");

                            // add std interfaces to class
                            if (foundClass != (classToAdd as NamespaceTypeDefinition)) {
                                foreach (ITypeDefinition temp in interfaceTransformer.getInterfacesList()) {
                                    interfaceTransformer.addInterface((classToAdd as NamespaceTypeDefinition), temp);
                                }
                            }
                            */

                            // Add random interfaces to the classes
                            List<NamespaceTypeDefinition> alreadyAdded = new List<NamespaceTypeDefinition>();
                            int max = PRNGRandomInterfaces.Next(numberRandomInterfaces);
                            NamespaceTypeDefinition interfaceClass = (classToAdd as NamespaceTypeDefinition);
                            logger.writeLine("Adding " + max + " random interfaces to class \"" + interfaceClass.ToString() + "\"");
                            for (int i = 0; i < max; i++) {
                                NamespaceTypeDefinition randInterface = randomInterfaces.ElementAt(PRNGRandomInterfaces.Next(randomInterfaces.Count));
                                if (alreadyAdded.Contains(randInterface)) {
                                    continue;
                                }
                                alreadyAdded.Add(randInterface);
                                logger.writeLine("Adding interface: \"" + randInterface.ToString() + "\"");

                                // add nodes interface to class
                                if (interfaceClass.Interfaces != null) {
                                    interfaceClass.Interfaces.Add(randInterface);
                                }
                                else {
                                    interfaceClass.Interfaces = new List<ITypeReference>();
                                    interfaceClass.Interfaces.Add(randInterface);
                                }
                            }
                            logger.writeLine("");

                            // Add special interface for the obfuscation scheme to the class
                            // (makes sure that all needed attributes and methods are implemented)
                            graphTransformer.addNodeInterfaceToTargetClass((classToAdd as NamespaceTypeDefinition));
                        }

                        // Prepare obfuscation graph
                        graphTransformer.generateGraph(numberValidPaths);
                        graphTransformer.createGraphMethods();

                        // Search method to obfuscate
                        MethodDefinition methodToObfu = null;
                        foreach (MethodDefinition tempMethod in foundClass.Methods) {
                            if (tempMethod.Name.ToString() == targetMethod) {
                                methodToObfu = tempMethod;
                                break;
                            }
                        }
                        if (methodToObfu == null) {
                            throw new ArgumentException("Not able to find target method.");
                        }

                        // Obfuscate target method
                        MethodCfg cfg = analyze.buildCfgForMethod(methodToObfu);
                        logger.dumpMethodCfg(cfg, "before");
                        graphTransformer.addObfuscationToMethod(cfg);
                        analyze.createMethodFromCfg(cfg);
                        logger.dumpMethodCfg(cfg, "after");

                        break;
                    }
                    if (!classFound) {
                        throw new ArgumentException("Not able to find target class.");
                    }


                    /*
                     * This code can be used if not only one specific method should be obfuscated,
                     * but the whole class.
                    List<ClassCfg> classCfgList = new List<ClassCfg>();
                    foreach (var tempClass in module.GetAllTypes()) {
                        if ((tempClass as NamespaceTypeDefinition) == null
                            || tempClass.IsAbstract) {
                            continue;
                        }

                        // create basic blocks
                        NamespaceTypeDefinition foundClass = (tempClass as NamespaceTypeDefinition);

                        logger.writeLine("Create CFG for class \"" + foundClass.Name.ToString() + "\"");
                        ClassCfg temp = analyze.buildCfgForClass(foundClass);
                        classCfgList.Add(temp);
                        logger.writeLine("\n---------------------------------\n");
                    }

                    // transform each function
                    NopTransformer transformator = new NopTransformer(module, host, logger);
                    foreach (ClassCfg tempClassCfg in classCfgList) {
                        foreach (MethodCfg tempMethodCfg in tempClassCfg.methodCfgs) {
                            logger.writeLine("Transform method CFG of \"" + tempMethodCfg.method.ToString() + "\"");
                            transformator.addNopsToCfg(tempMethodCfg);
                            logger.writeLine("\n---------------------------------\n");
                        }
                    }

                    foreach (ClassCfg tempClassCfg in classCfgList) {
                        logger.writeLine("Create class from CFG for \"" + tempClassCfg.classObj.Name.ToString() + "\"");
                        analyze.createClassFromCfg(tempClassCfg);
                        logger.writeLine("\n---------------------------------\n");
                    }
                    */

                    using (var peStream = File.Create(targetFile)) {
                        using (var pdbWriter = new PdbWriter(Path.ChangeExtension(targetFile, ".pdb"), pdbReader)) {
                            PeWriter.WritePeToStream(module, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                        }
                    }
                }
            }
        }
Exemple #12
0
 public CfgBuilder(IModule module, PeReader.DefaultHost host, Log.Log logger) {
     this.host = host;
     this.logger = logger;
     this.module = module;
 }
Exemple #13
0
        static void Main(string[] args)
        {
            String inputFile;
            String targetFile;
            String targetNamespace;
            String targetClass;
            String targetMethod;
            int    depth;
            int    dimension;
            int    numberValidPaths;
            int    duplicateBasicBlockWeight;
            int    duplicateBasicBlockCorrectionValue;
            int    stateChangeWeight;
            int    stateChangeCorrectionValue;
            int    insertOpaquePredicateWeight;
            int    seed;

            // Add debugging code into the obfuscated method (dump obfuscation graphs and so on)
            bool graphTransformerDebug = false;

            // Should the obfuscated code contain information to trace the control flow?
            bool basicBlockTrace = false;

            // When debugging is active, should the whole obfuscation graph be dumped or only the vpaths in it?
            bool graphOnlyDumpVPaths = true;

            // The number of random interfaces that are added to the program
            int numberRandomInterfaces = 100;

            if (args.Length != 14)
            {
                System.Console.WriteLine("Needed parameters: <inputBinary> <outputBinary> <namespace> <class> <method> <depth> <dimension> <numberValidPaths> <duplicateBasicBlockWeight> <duplicateBasicBlockCorrectionValue> <stateChangeWeight> <stateChangeCorrectionValue> <insertOpaquePredicateWeight> <seed>");
                return;
            }
            else
            {
                inputFile                          = args[0];
                targetFile                         = args[1];
                targetNamespace                    = args[2];
                targetClass                        = args[3];
                targetMethod                       = args[4];
                depth                              = Convert.ToInt32(args[5]);
                dimension                          = Convert.ToInt32(args[6]);
                numberValidPaths                   = Convert.ToInt32(args[7]);
                duplicateBasicBlockWeight          = Convert.ToInt32(args[8]);
                duplicateBasicBlockCorrectionValue = Convert.ToInt32(args[9]);
                stateChangeWeight                  = Convert.ToInt32(args[10]);
                stateChangeCorrectionValue         = Convert.ToInt32(args[11]);
                insertOpaquePredicateWeight        = Convert.ToInt32(args[12]);
                seed = Convert.ToInt32(args[13]);
            }

            String logDir = Path.GetDirectoryName(targetFile);

            Log.Log logger = new Log.Log(logDir, "probfuscation_logfile.txt");

            System.Console.WriteLine("Obfuscating: " + inputFile);
            logger.writeLine("Obfuscating: " + inputFile);
            System.Console.WriteLine("Output file: " + targetFile);
            logger.writeLine("Output file: " + targetFile);
            System.Console.WriteLine("Target namespace: " + targetNamespace);
            logger.writeLine("Target namespace: " + targetNamespace);
            System.Console.WriteLine("Target class: " + targetClass);
            logger.writeLine("Target class: " + targetClass);
            System.Console.WriteLine("Target method: " + targetMethod);
            logger.writeLine("Target method: " + targetMethod);
            System.Console.WriteLine("Depth: " + depth);
            logger.writeLine("Depth: " + depth);
            System.Console.WriteLine("Dimension: " + dimension);
            logger.writeLine("Dimension: " + dimension);
            System.Console.WriteLine("Number of vpaths: " + numberValidPaths);
            logger.writeLine("Number of vpaths: " + numberValidPaths);
            System.Console.WriteLine("Basic Block duplication weight: " + duplicateBasicBlockWeight);
            logger.writeLine("Basic Block duplication weight: " + duplicateBasicBlockWeight);
            System.Console.WriteLine("Basic Block duplication correction value: " + duplicateBasicBlockCorrectionValue);
            logger.writeLine("Basic Block duplication correction value: " + duplicateBasicBlockCorrectionValue);
            System.Console.WriteLine("State change weight: " + stateChangeWeight);
            logger.writeLine("State change weight: " + stateChangeWeight);
            System.Console.WriteLine("State change correction value: " + stateChangeCorrectionValue);
            logger.writeLine("State change correction value: " + stateChangeCorrectionValue);
            System.Console.WriteLine("Opaque predicate weight: " + insertOpaquePredicateWeight);
            logger.writeLine("Opaque predicate weight: " + insertOpaquePredicateWeight);
            System.Console.WriteLine("Seed: " + seed);
            logger.writeLine("Seed: " + seed);

            // Seed PRNG for interfaces
            PRNGRandomInterfaces = new Random(seed);

            using (var host = new PeReader.DefaultHost()) {
                IModule /*?*/ module = host.LoadUnitFrom(inputFile) as IModule;

                if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                {
                    Console.WriteLine(inputFile + " is not a PE file containing a CLR module or assembly.");
                    return;
                }

                module = new MetadataDeepCopier(host).Copy(module);

                if (module as Assembly == null)
                {
                    logger.writeLine("File does not have CIL assembly");
                    return;
                }

                // create analyzer object object
                CfgBuilder analyze = new Cfg.CfgBuilder(module, host, logger);

                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = Path.ChangeExtension(module.Location, "pdb");
                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile)) {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                else
                {
                    logger.writeLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");
                }

                using (pdbReader) {
                    Microsoft.Cci.ILGenerator.LocalScopeProvider localScopeProvider = null;
                    if (pdbReader != null)
                    {
                        localScopeProvider = new ILGenerator.LocalScopeProvider(pdbReader);
                    }

                    // search the namespace the interface should be added to
                    IUnitNamespace foundNamespace = null;
                    foreach (var tempMember in module.UnitNamespaceRoot.Members)
                    {
                        if ((tempMember as IUnitNamespace) == null)
                        {
                            continue;
                        }

                        IUnitNamespace tempNamespace = (tempMember as IUnitNamespace);

                        if (tempNamespace.ToString() == targetNamespace)
                        {
                            foundNamespace = tempNamespace;
                            break;
                        }
                    }
                    if (foundNamespace == null)
                    {
                        throw new ArgumentException("Not able to find target namespace.");
                    }

                    // add created interface (and implemented methods) to all classes
                    bool classFound = false;
                    foreach (var tempClass in module.GetAllTypes())
                    {
                        if ((tempClass as NamespaceTypeDefinition) == null ||
                            tempClass.IsAbstract)
                        {
                            continue;
                        }

                        NamespaceTypeDefinition foundClass = (tempClass as NamespaceTypeDefinition);

                        if (foundClass.ContainingUnitNamespace.ToString() == "")
                        {
                            continue;
                        }
                        if (foundClass.ToString() != targetNamespace + "." + targetClass)
                        {
                            continue;
                        }
                        classFound = true;

                        Random           prng             = new Random();
                        GraphTransformer graphTransformer = new GraphTransformer(module, host, logger, prng, foundNamespace, foundClass, depth, dimension, graphTransformerDebug);

                        graphTransformer.duplicateBasicBlockWeight          = duplicateBasicBlockWeight;
                        graphTransformer.duplicateBasicBlockCorrectionValue = duplicateBasicBlockCorrectionValue;
                        graphTransformer.stateChangeWeight           = stateChangeWeight;
                        graphTransformer.stateChangeCorrectionValue  = stateChangeCorrectionValue;
                        graphTransformer.insertOpaquePredicateWeight = insertOpaquePredicateWeight;
                        graphTransformer.trace = basicBlockTrace;
                        graphTransformer.graphOnlyDumpVPaths   = graphOnlyDumpVPaths;
                        graphTransformer.debuggingDumpLocation = logDir;

                        // Add 100 random interfaces to the namespace
                        Helper testHelper = new Helper(module, host, logger);
                        List <NamespaceTypeDefinition> randomInterfaces = new List <NamespaceTypeDefinition>();
                        for (int i = 0; i < numberRandomInterfaces; i++)
                        {
                            String randName = randomString(20);
                            NamespaceTypeDefinition temp = testHelper.createNewInterface(randName, foundNamespace);
                            randomInterfaces.Add(temp);
                        }

                        InterfaceTransformer interfaceTransformer = new InterfaceTransformer(module, host, logger);
                        foreach (var classToAdd in module.GetAllTypes())
                        {
                            if ((classToAdd as NamespaceTypeDefinition) == null ||
                                classToAdd.IsAbstract ||
                                classToAdd.IsInterface ||
                                classToAdd.IsEnum ||
                                classToAdd.IsDelegate ||
                                classToAdd.IsGeneric ||
                                classToAdd.IsStruct)
                            {
                                continue;
                            }

                            if (((NamespaceTypeDefinition)classToAdd).ContainingUnitNamespace.ToString() == "")
                            {
                                continue;
                            }

                            /*
                             * // Use this code if you want to add standard interfaces to the target class
                             * interfaceTransformer.addStdInterfacesGivenByFile(@"e:\code\dotnet_standard_interfaces.txt");
                             *
                             * // add std interfaces to class
                             * if (foundClass != (classToAdd as NamespaceTypeDefinition)) {
                             *  foreach (ITypeDefinition temp in interfaceTransformer.getInterfacesList()) {
                             *      interfaceTransformer.addInterface((classToAdd as NamespaceTypeDefinition), temp);
                             *  }
                             * }
                             */

                            // Add random interfaces to the classes
                            List <NamespaceTypeDefinition> alreadyAdded = new List <NamespaceTypeDefinition>();
                            int max = PRNGRandomInterfaces.Next(numberRandomInterfaces);
                            NamespaceTypeDefinition interfaceClass = (classToAdd as NamespaceTypeDefinition);
                            logger.writeLine("Adding " + max + " random interfaces to class \"" + interfaceClass.ToString() + "\"");
                            for (int i = 0; i < max; i++)
                            {
                                NamespaceTypeDefinition randInterface = randomInterfaces.ElementAt(PRNGRandomInterfaces.Next(randomInterfaces.Count));
                                if (alreadyAdded.Contains(randInterface))
                                {
                                    continue;
                                }
                                alreadyAdded.Add(randInterface);
                                logger.writeLine("Adding interface: \"" + randInterface.ToString() + "\"");

                                // add nodes interface to class
                                if (interfaceClass.Interfaces != null)
                                {
                                    interfaceClass.Interfaces.Add(randInterface);
                                }
                                else
                                {
                                    interfaceClass.Interfaces = new List <ITypeReference>();
                                    interfaceClass.Interfaces.Add(randInterface);
                                }
                            }
                            logger.writeLine("");

                            // Add special interface for the obfuscation scheme to the class
                            // (makes sure that all needed attributes and methods are implemented)
                            graphTransformer.addNodeInterfaceToTargetClass((classToAdd as NamespaceTypeDefinition));
                        }

                        // Prepare obfuscation graph
                        graphTransformer.generateGraph(numberValidPaths);
                        graphTransformer.createGraphMethods();

                        // Search method to obfuscate
                        MethodDefinition methodToObfu = null;
                        foreach (MethodDefinition tempMethod in foundClass.Methods)
                        {
                            if (tempMethod.Name.ToString() == targetMethod)
                            {
                                methodToObfu = tempMethod;
                                break;
                            }
                        }
                        if (methodToObfu == null)
                        {
                            throw new ArgumentException("Not able to find target method.");
                        }

                        // Obfuscate target method
                        MethodCfg cfg = analyze.buildCfgForMethod(methodToObfu);
                        logger.dumpMethodCfg(cfg, "before");
                        graphTransformer.addObfuscationToMethod(cfg);
                        analyze.createMethodFromCfg(cfg);
                        logger.dumpMethodCfg(cfg, "after");

                        break;
                    }
                    if (!classFound)
                    {
                        throw new ArgumentException("Not able to find target class.");
                    }


                    /*
                     * This code can be used if not only one specific method should be obfuscated,
                     * but the whole class.
                     * List<ClassCfg> classCfgList = new List<ClassCfg>();
                     * foreach (var tempClass in module.GetAllTypes()) {
                     *  if ((tempClass as NamespaceTypeDefinition) == null
                     || tempClass.IsAbstract) {
                     ||     continue;
                     || }
                     ||
                     || // create basic blocks
                     || NamespaceTypeDefinition foundClass = (tempClass as NamespaceTypeDefinition);
                     ||
                     || logger.writeLine("Create CFG for class \"" + foundClass.Name.ToString() + "\"");
                     || ClassCfg temp = analyze.buildCfgForClass(foundClass);
                     || classCfgList.Add(temp);
                     || logger.writeLine("\n---------------------------------\n");
                     ||}
                     ||
                     ||// transform each function
                     ||NopTransformer transformator = new NopTransformer(module, host, logger);
                     ||foreach (ClassCfg tempClassCfg in classCfgList) {
                     || foreach (MethodCfg tempMethodCfg in tempClassCfg.methodCfgs) {
                     ||     logger.writeLine("Transform method CFG of \"" + tempMethodCfg.method.ToString() + "\"");
                     ||     transformator.addNopsToCfg(tempMethodCfg);
                     ||     logger.writeLine("\n---------------------------------\n");
                     || }
                     ||}
                     ||
                     ||foreach (ClassCfg tempClassCfg in classCfgList) {
                     || logger.writeLine("Create class from CFG for \"" + tempClassCfg.classObj.Name.ToString() + "\"");
                     || analyze.createClassFromCfg(tempClassCfg);
                     || logger.writeLine("\n---------------------------------\n");
                     ||}
                     */

                    using (var peStream = File.Create(targetFile)) {
                        using (var pdbWriter = new PdbWriter(Path.ChangeExtension(targetFile, ".pdb"), pdbReader)) {
                            PeWriter.WritePeToStream(module, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                        }
                    }
                }
            }
        }
Exemple #14
0
        public CodeGenerator(IModule module, PeReader.DefaultHost host, Log.Log logger, Random prng, MethodCfg methodCfg,
            bool debugging=false, CfgManipulator manipulator=null)
        {
            this.host = host;
            this.logger = logger;
            this.module = module;
            this.prng = prng;
            this.methodCfg = methodCfg;
            this.debugging = debugging;
            this.manipulator = manipulator;

            callableMethods = retrieveCallableMethods();
        }
Exemple #15
0
        public CodeMutator(IModule module, PeReader.DefaultHost host, Log.Log logger, Random prng, MethodCfg methodCfg,
            CfgManipulator manipulator, bool debugging=false)
        {
            this.host = host;
            this.logger = logger;
            this.module = module;
            this.prng = prng;
            this.methodCfg = methodCfg;
            this.debugging = debugging;
            this.manipulator = manipulator;

            returnBlock = new BasicBlock();
            var exitBranch = new ExitBranchTarget();

            returnBlock.exitBranch = exitBranch;
            returnBlock.operations.Add(createNewOperation(OperationCode.Ret));

            methodCfg.basicBlocks.Add(returnBlock);
        }
 public NopTransformer(IModule module, PeReader.DefaultHost host, Log.Log logger)
 {
     this.host   = host;
     this.logger = logger;
     this.module = module;
 }
        public GraphTransformer(IModule module, PeReader.DefaultHost host, Log.Log logger, Random prng, IUnitNamespace targetNamespace, NamespaceTypeDefinition targetClass, int depth, int dimension, bool debugging = false) {
            this.host = host;
            this.logger = logger;
            this.module = module;
            this.prng = prng;
            this.helperClass = new Helper(module, host, logger);
            this.cfgBuilder = new Cfg.CfgBuilder(module, host, logger);

            this.targetClass = targetClass;

            this.graphDepth = depth;
            this.graphDimension = dimension;

            this.debugging = debugging;
            this.debuggingNumber = 0;

            // create iNode interface
            this.createNodeInterface(targetNamespace);

            // add created iNode interface to the given target class
            this.addNodeInterfaceToTargetClass(this.targetClass);
        }