Esempio n. 1
0
        internal ITypeReference Map(ITypeReference typeReference)
        {
            var result   = new MetadataDeepCopier(host).Copy(typeReference);
            var rewriter = new ActualMutator(host, targetUnit, sourceUnitIdentity);

            return(rewriter.Rewrite(result));
        }
        static void Main(string[] argv)
        {
            if (argv == null || argv.Length < 1)
            {
                Console.WriteLine("Usage: Main <assemblys> [<outputPath>]");
            }

            using (var host = new PeReader.DefaultHost()) {
                var module = host.LoadUnitFrom(argv[0]) as IModule;
                if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                {
                    throw new Exception(argv[0] + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
                }

                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
                {
                    Console.WriteLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");
                }

                using (pdbReader) {
                    var copy = new MetadataDeepCopier(host).Copy(module);
                    var shadowFieldsAddedAssembly           = new ShadowFieldRewriter(host).Rewrite(copy);
                    var shadowFieldsAndMethodsAddedAssembly = new ShadowMethodRewriter(host).Rewrite(shadowFieldsAddedAssembly);
                    var rewrittenAssembly = new FinalizeMethodRewriter(host).Rewrite(shadowFieldsAndMethodsAddedAssembly);

                    var main = rewrittenAssembly.EntryPoint.ResolvedMethod;
                    if (main != Dummy.Method)
                    {
                        var body = main.Body as MethodBody;
                        if (body != null)
                        {
                            new AddGCWaitForFinalization(host, body).Rewrite();
                        }
                    }

                    var validator = new MetadataValidator(host);
                    validator.Validate(rewrittenAssembly as IAssembly);

                    string outputPath     = rewrittenAssembly.Location + ".meta";
                    var    outputFileName = Path.GetFileNameWithoutExtension(outputPath);

                    // Need to not pass in a local scope provider until such time as we have one that will use the mutator
                    // to remap things (like the type of a scope constant) from the original assembly to the mutated one.
                    using (var peStream = File.Create(outputPath)) {
                        using (var pdbWriter = new PdbWriter(outputFileName + ".pdb", pdbReader)) {
                            PeWriter.WritePeToStream(rewrittenAssembly, host, peStream, pdbReader, null, pdbWriter);
                        }
                    }
                }
            }
        }
Esempio n. 3
0
    IAssembly VisitAndMutate(MetadataRewriter mutator, IAssembly assembly)
    {
        var mutableAssembly = new MetadataDeepCopier(host).Copy(assembly);

        assembly = mutator.Rewrite(mutableAssembly);
        Assert.NotNull(assembly);
        return(assembly);
    }
Esempio n. 4
0
    static int Main(string[] args) {

        /*
      if (args == null || args.Length < 1) {
        Console.WriteLine("Usage: ILMutator <assembly> [<outputPath>]");
        return 1;
      }
         */

        String inputFile = @"c:\Users\typ\Documents\Visual Studio 2013\Projects\vererbung\vererbung\bin\Debug\vererbung.exe";


      using (var host = new PeReader.DefaultHost()) {
        //IModule/*?*/ module = host.LoadUnitFrom(args[0]) as IModule;
        IModule/*?*/ module = host.LoadUnitFrom(inputFile) as IModule;
        if (module == null || module is Dummy) {
          Console.WriteLine(args[0] + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
          return 1;
        }
        module = new MetadataDeepCopier(host).Copy(module);

        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 {
          Console.WriteLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");
        }
        using (pdbReader) {
          var localScopeProvider = pdbReader == null ? null : new ILGenerator.LocalScopeProvider(pdbReader);

          module = RewriteStoreLocal.RewriteModule(host, localScopeProvider, pdbReader, module);

          string newName;
          if (args.Length == 2) {
            //newName = args[1];
            newName = @"e:\mutated.exe";
          } else {
            var loc = module.Location;
            var path = Path.GetDirectoryName(loc)??"";
            var fileName = Path.GetFileNameWithoutExtension(loc);
            var ext = Path.GetExtension(loc);
            newName = Path.Combine(path, fileName + "1" + ext);
            newName = @"e:\mutated.exe";
          }

          using (var peStream = File.Create(newName)) {
            using (var pdbWriter = new PdbWriter(Path.ChangeExtension(newName, ".pdb"), pdbReader)) {
              PeWriter.WritePeToStream(module, host, peStream, pdbReader, localScopeProvider, pdbWriter);
            }
          }
        }
        return 0; // success
      }
    }
Esempio n. 5
0
        static int Main(string[] args)
        {
            if (args == null || args.Length < 1)
            {
                Console.WriteLine("Usage: ILMutator <assembly> [<outputPath>]");
                return(1);
            }

            using (var host = new PeReader.DefaultHost()) {
                IModule /*?*/ module = host.LoadUnitFrom(args[0]) as IModule;
                if (module == null || module is Dummy)
                {
                    Console.WriteLine(args[0] + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
                    return(1);
                }
                module = new MetadataDeepCopier(host).Copy(module);

                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
                {
                    Console.WriteLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");
                }
                using (pdbReader) {
                    var       localScopeProvider = pdbReader == null ? null : new ILGenerator.LocalScopeProvider(pdbReader);
                    ILMutator mutator            = new ILMutator(host, pdbReader);
                    module = mutator.Rewrite(module);

                    string newName;
                    if (args.Length == 2)
                    {
                        newName = args[1];
                    }
                    else
                    {
                        var loc      = module.Location;
                        var path     = Path.GetDirectoryName(loc) ?? "";
                        var fileName = Path.GetFileNameWithoutExtension(loc);
                        var ext      = Path.GetExtension(loc);
                        newName = Path.Combine(path, fileName + "1" + ext);
                    }

                    using (var peStream = File.Create(newName)) {
                        using (var pdbWriter = new PdbWriter(Path.ChangeExtension(newName, ".pdb"), pdbReader)) {
                            PeWriter.WritePeToStream(module, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                        }
                    }
                }
                return(0); // success
            }
        }
 internal static IModule GetInstrumented(IMetadataHost host, IModule module, PdbReader/*?*/ pdbReader, INamespaceTypeDefinition logger) {
   var copier = new MetadataDeepCopier(host);
   var copy = copier.Copy(module);
   var loggerCopy = copier.Copy(logger);
   loggerCopy.ContainingUnitNamespace = copy.UnitNamespaceRoot;
   var logEdgeCount = TypeHelper.GetMethod(loggerCopy, host.NameTable.GetNameFor("LogEdgeCount"), host.PlatformType.SystemUInt32);
   new Instrumenter(host, pdbReader, logEdgeCount).Rewrite(copy);
   copy.AllTypes.Add(loggerCopy);
   return copy;
 }
        internal static IModule GetInstrumented(IMetadataHost host, IModule module, PdbReader /*?*/ pdbReader, INamespaceTypeDefinition logger)
        {
            var copier     = new MetadataDeepCopier(host);
            var copy       = copier.Copy(module);
            var loggerCopy = copier.Copy(logger);

            loggerCopy.ContainingUnitNamespace = copy.UnitNamespaceRoot;
            var logEdgeCount = TypeHelper.GetMethod(loggerCopy, host.NameTable.GetNameFor("LogEdgeCount"), host.PlatformType.SystemUInt32);

            new Instrumenter(host, pdbReader, logEdgeCount).Rewrite(copy);
            copy.AllTypes.Add(loggerCopy);
            return(copy);
        }
    static void Main(string[] args) {
      if (args == null || args.Length == 0) {
        Console.WriteLine("usage: PeToPe [path]fileName.ext");
        return;
      }

      using (var host = new PeReader.DefaultHost()) {
        var module = host.LoadUnitFrom(args[0]) as IModule;
        if (module == null || module is Dummy) {
          Console.WriteLine(args[0]+" is not a PE file containing a CLR module or assembly.");
          return;
        }

        PdbReader/*?*/ pdbReader = null;
        string pdbFile = module.DebugInformationLocation;
        if (string.IsNullOrEmpty(pdbFile))
          pdbFile = Path.ChangeExtension(module.Location, "pdb");
        if (File.Exists(pdbFile)) {
          Stream pdbStream = File.OpenRead(pdbFile);
          pdbReader = new PdbReader(pdbStream, host);
        }

        using (pdbReader) {
          //Make a mutable copy of the module.
          var copier = new MetadataDeepCopier(host);
          var mutableModule = copier.Copy(module);

          //Traverse the module. In a real application the MetadataVisitor and/or the MetadataTravers will be subclasses
          //and the traversal will gather information to use during rewriting.
          var traverser = new MetadataTraverser() { PreorderVisitor = new MetadataVisitor(), TraverseIntoMethodBodies = true };
          traverser.Traverse(mutableModule);

          //Rewrite the mutable copy. In a real application the rewriter would be a subclass of MetadataRewriter that actually does something.
          var rewriter = new MetadataRewriter(host);
          var rewrittenModule = rewriter.Rewrite(mutableModule); 

          //Write out rewritten module.
          using (var peStream = File.Create(rewrittenModule.Location + ".pe")) {
            if (pdbReader == null) {
              PeWriter.WritePeToStream(rewrittenModule, host, peStream);
            } else {
              //Note that the default copier and rewriter preserves the locations collections, so the original pdbReader is still a valid ISourceLocationProvider.
              //However, if IL instructions were rewritten, the pdbReader will no longer be an accurate ILocalScopeProvider
              using (var pdbWriter = new PdbWriter(pdbFile + ".pdb", pdbReader)) {
                PeWriter.WritePeToStream(rewrittenModule, host, peStream, pdbReader, pdbReader, pdbWriter);
              }
            }
          }
        }
      }
    }
Esempio n. 9
0
    void RoundTripMutableCopyAndAddGenericParameter2(string assemblyName)
    {
        PeVerifyResult expectedResult = PeVerify.VerifyAssembly(assemblyName);
        IAssembly      assembly       = LoadAssembly(assemblyName);
        var            copier1        = new MetadataDeepCopier(host);
        var            codeAssembly   = copier1.Copy(assembly);

        for (int i = 0; i < 30; i++)
        {
            AddGenericParameters adder = new AddGenericParameters(host, codeAssembly.AllTypes, i);
            codeAssembly = (Assembly)adder.Rewrite(codeAssembly);
        }
        AssertWriteToPeFile(expectedResult, codeAssembly, null);
    }
Esempio n. 10
0
        /// <summary>
        /// Returns a mutable Code Model module that is equivalent to the given Metadata Model module,
        /// except that in the new module method bodies also implement ISourceMethodBody.
        /// </summary>
        /// <param name="host">An object representing the application that is hosting this decompiler. It is used to obtain access to some global
        /// objects and services such as the shared name table and the table for interning references.</param>
        /// <param name="module">The root of the Metadata Model to be converted to a Code Model.</param>
        /// <param name="sourceLocationProvider">An object that can map some kinds of ILocation objects to IPrimarySourceLocation objects. May be null.</param>
        /// <param name="localScopeProvider">An object that can provide information about the local scopes of a method. May be null.</param>
        /// <param name="options">Set of options that control decompilation.</param>
        private static Module GetCodeModelFromMetadataModelHelper(IMetadataHost host, IModule module,
                                                                  ISourceLocationProvider /*?*/ sourceLocationProvider, ILocalScopeProvider /*?*/ localScopeProvider, DecompilerOptions options)
        {
            var result   = new MetadataDeepCopier(host).Copy(module);
            var replacer = new ReplaceMetadataMethodBodiesWithDecompiledMethodBodies(host, module, sourceLocationProvider, localScopeProvider, options);

            replacer.Traverse(result);
            var finder = new HelperTypeFinder(host, sourceLocationProvider);

            finder.Traverse(result);
            var remover = new RemoveUnnecessaryTypes(finder.helperTypes, finder.helperMethods, finder.helperFields);

            remover.Traverse(result);
            result.AllTypes.RemoveAll(td => finder.helperTypes.ContainsKey(td.InternedKey)); // depends on RemoveAll preserving order
            return(result);
        }
Esempio n. 11
0
        public override void RewriteChildren(NamedTypeDefinition typeDefinition)
        {
            if (typeDefinition.Properties == null)
            {
                return;
            }

            var props = typeDefinition.Properties
                .Select(x => new
                {
                    Property = x,
                    Attributes = x.Attributes
                        //.Select(y => (NamespaceTypeDefinition)y.Type)
                        .Select(y => y.Type as NamespaceTypeDefinition)
                        .Where(y => y != null && y.Name.Value == "PropertyChangedAttribute")
                })
                .Where(x => x.Attributes.Any());

            if (!props.Any())
            {
                return;
            }

            foreach (var p in props.ToArray())
            {
                if (p.Property.Setter == null)
                {
                    throw new InvalidOperationException();
                }

                var copier = new MetadataDeepCopier(host);

                var p2 = copier.Copy(p.Property);
                typeDefinition.Properties.Remove(p.Property);
                typeDefinition.Properties.Add(p2);

                var method = copier.Copy(p2.Setter.ResolvedMethod);
                _rewriter.PropertyName = p2.Name.Value;
                _rewriter.Type = method.ContainingTypeDefinition;
                method.Body = _rewriter.Rewrite(method.Body);
                method.ContainingTypeDefinition = typeDefinition;

                var m = typeDefinition.Methods.FirstOrDefault(x => x.Name == p2.Setter.ResolvedMethod.Name);
                typeDefinition.Methods.Remove(m);
                typeDefinition.Methods.Add(method);
            }
        }
Esempio n. 12
0
        public override void RewriteChildren(NamedTypeDefinition typeDefinition)
        {
            if (typeDefinition.Properties == null)
            {
                return;
            }

            var props = typeDefinition.Properties
                        .Select(x => new
            {
                Property   = x,
                Attributes = x.Attributes
                             //.Select(y => (NamespaceTypeDefinition)y.Type)
                             .Select(y => y.Type as NamespaceTypeDefinition)
                             .Where(y => y != null && y.Name.Value == "PropertyChangedAttribute")
            })
                        .Where(x => x.Attributes.Any());

            if (!props.Any())
            {
                return;
            }

            foreach (var p in props.ToArray())
            {
                if (p.Property.Setter == null)
                {
                    throw new InvalidOperationException();
                }

                var copier = new MetadataDeepCopier(host);

                var p2 = copier.Copy(p.Property);
                typeDefinition.Properties.Remove(p.Property);
                typeDefinition.Properties.Add(p2);

                var method = copier.Copy(p2.Setter.ResolvedMethod);
                _rewriter.PropertyName          = p2.Name.Value;
                _rewriter.Type                  = method.ContainingTypeDefinition;
                method.Body                     = _rewriter.Rewrite(method.Body);
                method.ContainingTypeDefinition = typeDefinition;

                var m = typeDefinition.Methods.FirstOrDefault(x => x.Name == p2.Setter.ResolvedMethod.Name);
                typeDefinition.Methods.Remove(m);
                typeDefinition.Methods.Add(method);
            }
        }
Esempio n. 13
0
        private IAssembly LoadAssemblyFrom(string filePath)
        {
            IAssembly module = _host.LoadUnitFrom(filePath) as IAssembly;

            _host.RegisterAsLatest(module);
            if (module == null || module == Dummy.Module || module == Dummy.Assembly)
            {
                throw new AssemblyReadException(filePath + " is not a PE file containing a CLR module or assembly.");
            }

            PdbReader pdbReader;

            TryGetPdbReader(module, out pdbReader);

            module = new MetadataDeepCopier(_host).Copy(module);
            //  var decompiled = Decompiler.GetCodeModelFromMetadataModel(_host, module, pdbReader,
            //      DecompilerOptions.None);
            return(module);
            //  return new CodeDeepCopier(_host, pdbReader).Copy(decompiled);
        }
Esempio n. 14
0
        public static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                Console.WriteLine("Usage: PInvokeCompiler Input.dll Output.dll");
                return;
            }

            var inputFile  = args[0];
            var outputFile = args[1];

            using (var host = new PeReader.DefaultHost())
            {
                var unit     = host.LoadUnitFrom(inputFile);
                var assembly = unit as IAssembly;

                if (assembly == null)
                {
                    Console.WriteLine("Error: Input file not loadable as assembly");
                    return;
                }

                Assembly mutable = new MetadataDeepCopier(host).Copy(assembly);

                var interopHelperReference = new InteropHelperReferences(host, mutable);

                var pinvokeMethodMetadataTraverser = new PInvokeMethodMetadataTraverser(interopHelperReference.PInvokeHelpers);
                pinvokeMethodMetadataTraverser.TraverseChildren(mutable);

                var methodTransformationMetadataRewriter = new MethodTransformationMetadataRewriter(interopHelperReference.LoadLibrary, interopHelperReference.GetProcAddress, interopHelperReference.IsLibraryInitialized, host, pinvokeMethodMetadataTraverser);
                methodTransformationMetadataRewriter.RewriteChildren(mutable);

                var pinvokeMethodMetadataRewriter = new PInvokeMethodMetadataRewriter(interopHelperReference, host, methodTransformationMetadataRewriter);
                pinvokeMethodMetadataRewriter.RewriteChildren(mutable);

                using (var stream = File.Create(outputFile))
                {
                    PeWriter.WritePeToStream(mutable, host, stream);
                }
            }
        }
Esempio n. 15
0
        private static void TransformProgram(WholeProgram wholeProgram,
                                             string transformedBinariesPath,
                                             string reportsPath,
                                             MethodRemoval methodRemoval,
                                             TargetProfile profile)
        {
            System.IO.Directory.CreateDirectory(transformedBinariesPath);

            StubMethodBodyEmitter stubEmitter = GetStubMethodBodyEmitterForProfile(profile, wholeProgram);

            foreach (IAssembly assembly in wholeProgram.AllAssemblies())
            {
                if (AssemblyShouldBeRewritten(assembly))
                {
                    if (assembly.PublicKeyToken.Count() > 0)
                    {
                        Console.WriteLine("Warning: rewriting assembly with a public key token. {0}", assembly);
                    }

                    string outputBinary = transformedBinariesPath + @"\" + Path.GetFileName(assembly.Location);

                    var copy = new MetadataDeepCopier(wholeProgram.Host()).Copy(assembly);


                    DocumentationCommentDefinitionIdStringMap idMap = new DocumentationCommentDefinitionIdStringMap(new IAssembly[] { copy });

                    AssemblyReport assemblyReport = AssemblyReport.CreateAssemblyReportFromPath(copy, reportsPath, idMap);

                    stopwatch.Start();
                    RewriteBinary(copy, assemblyReport, wholeProgram.Host(), outputBinary, methodRemoval, stubEmitter);

                    stopwatch.Start();
                }
                else
                {
                    //Console.WriteLine("Skipping rewrite of of assembly {0}", assembly.Name.Value);
                }
            }
        }
Esempio n. 16
0
        private Prune(
            IMetadataHost host,
            MetadataDeepCopier copier,
            HashSet <object> thingsToKeep,
            HashSet <uint> methodsWhoseBodiesShouldBeKept,
            IDictionary <IMethodDefinition, MethodHashAttribute> methodHashAttributes
            )
            : base(host)
        {
            Contract.Requires(host != null);
            Contract.Requires(copier != null);
            Contract.Requires(thingsToKeep != null);
            Contract.Requires(methodsWhoseBodiesShouldBeKept != null);
            Contract.Requires(methodHashAttributes != null);

            this.copier               = copier;
            this.thingsToKeep         = thingsToKeep;
            this.methodDefsToKeep     = methodsWhoseBodiesShouldBeKept;
            this.methodHashAttributes = methodHashAttributes;

            this.systemInt    = host.PlatformType.SystemInt32;
            this.systemString = host.PlatformType.SystemString;
        }
Esempio n. 17
0
    private Prune(
      IMetadataHost host,
      MetadataDeepCopier copier,
      HashSet<object> thingsToKeep,
      HashSet<uint> methodsWhoseBodiesShouldBeKept,
      IDictionary<IMethodDefinition, MethodHashAttribute> methodHashAttributes
      )
      : base(host) {

      Contract.Requires(host != null);
      Contract.Requires(copier != null);
      Contract.Requires(thingsToKeep != null);
      Contract.Requires(methodsWhoseBodiesShouldBeKept != null);
      Contract.Requires(methodHashAttributes != null);

      this.copier = copier;
      this.thingsToKeep = thingsToKeep;
      this.methodDefsToKeep = methodsWhoseBodiesShouldBeKept;
      this.methodHashAttributes = methodHashAttributes;

      this.systemInt = host.PlatformType.SystemInt32;
      this.systemString = host.PlatformType.SystemString;

    }
Esempio n. 18
0
            public Assembly GenerateFacade(IAssembly contractAssembly, IAssemblyReference seedCoreAssemblyReference, bool ignoreMissingTypes, IAssembly overrideContractAssembly = null)
            {
                Assembly assembly;
                if (overrideContractAssembly != null)
                {
                    MetadataDeepCopier copier = new MetadataDeepCopier(_seedHost);
                    assembly = copier.Copy(overrideContractAssembly); // Use non-empty partial facade if present
                }
                else
                {
                    MetadataDeepCopier copier = new MetadataDeepCopier(_contractHost);
                    assembly = copier.Copy(contractAssembly);
                    ReferenceAssemblyToFacadeRewriter rewriter = new ReferenceAssemblyToFacadeRewriter(_seedHost, _contractHost, seedCoreAssemblyReference, _assemblyFileVersion != null);
                    rewriter.Rewrite(assembly);
                }

                IEnumerable<string> docIds = _docIdTable[contractAssembly.AssemblyIdentity.Name.Value];

                // Add all the type forwards
                bool error = false;

                HashSet<string> existingDocIds = new HashSet<string>(assembly.AllTypes.Select(typeDef => typeDef.RefDocId()));
                IEnumerable<string> missingDocIds = docIds.Where(id => !existingDocIds.Contains(id));
                foreach (string docId in missingDocIds)
                {
                    IReadOnlyList<INamedTypeDefinition> seedTypes;
                    if (!_typeTable.TryGetValue(docId, out seedTypes))
                    {
                        if (!ignoreMissingTypes)
                        {
                            Trace.TraceError("Did not find type '{0}' in any of the seed assemblies.", docId);
                            error = true;
                        }
                        continue;
                    }

                    INamedTypeDefinition seedType = GetSeedType(docId, seedTypes);
                    if (seedType == null)
                    {
                        TraceDuplicateSeedTypeError(docId, seedTypes);
                        error = true;
                        continue;
                    }

                    AddTypeForward(assembly, seedType);
                }

                if (error)
                {
                    return null;
                }

                if (_assemblyFileVersion != null)
                {
                    assembly.AssemblyAttributes.Add(CreateAttribute("System.Reflection.AssemblyFileVersionAttribute", seedCoreAssemblyReference.ResolvedAssembly, _assemblyFileVersion.ToString()));
                    assembly.AssemblyAttributes.Add(CreateAttribute("System.Reflection.AssemblyInformationalVersionAttribute", seedCoreAssemblyReference.ResolvedAssembly, _assemblyFileVersion.ToString()));
                }

                if (_buildDesignTimeFacades)
                {
                    assembly.AssemblyAttributes.Add(CreateAttribute("System.Runtime.CompilerServices.ReferenceAssemblyAttribute", seedCoreAssemblyReference.ResolvedAssembly));
                    assembly.Flags |= ReferenceAssemblyFlag;
                }

                if (_clearBuildAndRevision)
                {
                    assembly.Version = new Version(assembly.Version.Major, assembly.Version.Minor, 0, 0);
                }

                AddWin32VersionResource(contractAssembly.Location, assembly);

                return assembly;
            }
Esempio n. 19
0
            public Assembly GenerateFacade(IAssembly contractAssembly, IAssemblyReference seedCoreAssemblyReference, bool ignoreMissingTypes, IAssembly overrideContractAssembly = null, bool buildPartialReferenceFacade = false)
            {
                Assembly assembly;

                if (overrideContractAssembly != null)
                {
                    MetadataDeepCopier copier = new MetadataDeepCopier(_seedHost);
                    assembly = copier.Copy(overrideContractAssembly); // Use non-empty partial facade if present
                }
                else
                {
                    MetadataDeepCopier copier = new MetadataDeepCopier(_contractHost);
                    assembly = copier.Copy(contractAssembly);

                    // if building a reference facade don't strip the contract
                    if (!buildPartialReferenceFacade)
                    {
                        ReferenceAssemblyToFacadeRewriter rewriter = new ReferenceAssemblyToFacadeRewriter(_seedHost, _contractHost, seedCoreAssemblyReference, _assemblyFileVersion != null);
                        rewriter.Rewrite(assembly);
                    }
                }

                string contractAssemblyName = contractAssembly.AssemblyIdentity.Name.Value;
                IEnumerable <string> docIds = _docIdTable[contractAssemblyName];

                // Add all the type forwards
                bool error = false;

                Dictionary <string, INamedTypeDefinition> existingDocIds = assembly.AllTypes.ToDictionary(typeDef => typeDef.RefDocId(), typeDef => typeDef);
                IEnumerable <string> docIdsToForward = buildPartialReferenceFacade ? existingDocIds.Keys : docIds.Where(id => !existingDocIds.ContainsKey(id));
                Dictionary <string, INamedTypeReference> forwardedTypes = new Dictionary <string, INamedTypeReference>();

                foreach (string docId in docIdsToForward)
                {
                    IReadOnlyList <INamedTypeDefinition> seedTypes;
                    if (!_typeTable.TryGetValue(docId, out seedTypes))
                    {
                        if (!ignoreMissingTypes && !buildPartialReferenceFacade)
                        {
                            Trace.TraceError("Did not find type '{0}' in any of the seed assemblies.", docId);
                            error = true;
                        }
                        continue;
                    }

                    INamedTypeDefinition seedType = GetSeedType(docId, seedTypes);
                    if (seedType == null)
                    {
                        TraceDuplicateSeedTypeError(docId, seedTypes);
                        error = true;
                        continue;
                    }

                    if (buildPartialReferenceFacade)
                    {
                        // honor preferSeedType for keeping contract type
                        string preferredSeedAssembly;
                        bool   keepType = _seedTypePreferences.TryGetValue(docId, out preferredSeedAssembly) &&
                                          contractAssemblyName.Equals(preferredSeedAssembly, StringComparison.OrdinalIgnoreCase);

                        if (keepType)
                        {
                            continue;
                        }

                        assembly.AllTypes.Remove(existingDocIds[docId]);
                        forwardedTypes.Add(docId, seedType);
                    }

                    AddTypeForward(assembly, seedType);
                }

                if (buildPartialReferenceFacade)
                {
                    if (forwardedTypes.Count == 0)
                    {
                        Trace.TraceError("Did not find any types in any of the seed assemblies.");
                        return(null);
                    }
                    else
                    {
                        // for any thing that's now a typeforward, make sure typerefs point to that rather than
                        // the type previously inside the assembly.
                        TypeReferenceRewriter typeRefRewriter = new TypeReferenceRewriter(_seedHost, oldType =>
                        {
                            INamedTypeReference newType = null;
                            return(forwardedTypes.TryGetValue(oldType.DocId(), out newType) ? newType : oldType);
                        });

                        typeRefRewriter.Rewrite(assembly);
                    }
                }

                if (error)
                {
                    return(null);
                }

                if (_assemblyFileVersion != null)
                {
                    assembly.AssemblyAttributes.Add(CreateAttribute("System.Reflection.AssemblyFileVersionAttribute", seedCoreAssemblyReference.ResolvedAssembly, _assemblyFileVersion.ToString()));
                    assembly.AssemblyAttributes.Add(CreateAttribute("System.Reflection.AssemblyInformationalVersionAttribute", seedCoreAssemblyReference.ResolvedAssembly, _assemblyFileVersion.ToString()));
                }

                if (_buildDesignTimeFacades)
                {
                    assembly.AssemblyAttributes.Add(CreateAttribute("System.Runtime.CompilerServices.ReferenceAssemblyAttribute", seedCoreAssemblyReference.ResolvedAssembly));
                    assembly.Flags |= ReferenceAssemblyFlag;
                }

                if (_clearBuildAndRevision)
                {
                    assembly.Version = new Version(assembly.Version.Major, assembly.Version.Minor, 0, 0);
                }

                AddWin32VersionResource(contractAssembly.Location, assembly);

                return(assembly);
            }
Esempio n. 20
0
 /// <summary>
 /// Gets a mutable copy of the target assembly.
 /// </summary>
 /// <param name="target">
 /// The assembly to retrieve the mutable copy for.
 /// </param>
 /// <param name="host">
 /// The host to use when loading the assembly.
 /// </param>
 /// <returns>
 /// A mutable copy of the target assembly.
 /// </returns>
 private static Assembly GetMutableAssembly(IAssemblyTarget target, IMetadataHost host)
 {
     var copier = new MetadataDeepCopier(host);
     return copier.Copy(LoadModule(target, host));
 }
Esempio n. 21
0
        private Task LoadManagedData()
        {
            return _loadingManagedData ?? (_loadingManagedData = _tasks.Start(() => {
                if (_loadOptions.HasFlag(BinaryLoadOptions.NoManaged)) {
                    return;
                }
                // load managed data from working file
                if (!IsManaged) {
                    ILOnly.Value = false;
                    return;
                }
                // copy this to a temporary file, because it locks the file until we're *really* done.

                try {
                    var module = _host.LoadUnitFrom(WorkingCopy) as IModule;

                    if (module == null || module is Dummy) {
                        throw new CoAppException("{0} is not a PE file containing a CLR module or assembly.".format(Filename));
                    }

                    ILOnly.Value = module.ILOnly;

                    //Make a mutable copy of the module.
                    var copier = new MetadataDeepCopier(_host);
                    var mutableModule = copier.Copy(module);

                    //Traverse the module. In a real application the MetadataVisitor and/or the MetadataTravers will be subclasses
                    //and the traversal will gather information to use during rewriting.
                    var traverser = new MetadataTraverser {
                        PreorderVisitor = new MetadataVisitor(),
                        TraverseIntoMethodBodies = true
                    };
                    traverser.Traverse(mutableModule);

                    //Rewrite the mutable copy. In a real application the rewriter would be a subclass of MetadataRewriter that actually does something.
                    var rewriter = new MetadataRewriter(_host);
                    _mutableAssembly = rewriter.Rewrite(mutableModule) as Assembly;
                    AssemblyCulture.Value = _mutableAssembly.Culture;
                    AssemblyVersion.Value = _mutableAssembly.Version;
                } finally {
                    // delete it, or at least trash it & queue it up for next reboot.
                    // temporaryCopy.TryHardToDelete();
                }

                try {
                    if (_mutableAssembly != null) {
                        // we should see if we can get assembly attributes, since sometimes they can be set, but not the native ones.
                        foreach (var a in _mutableAssembly.ContainingAssembly.AssemblyAttributes) {
                            var attributeArgument = (a.Arguments.FirstOrDefault() as MetadataConstant);
                            if (attributeArgument != null) {
                                var attributeValue = attributeArgument.Value.ToString();
                                if (!string.IsNullOrEmpty(attributeValue)) {
                                    switch (a.Type.ToString()) {
                                        case "System.Reflection.AssemblyTitleAttribute":
                                            _fileDescription = _fileDescription ?? attributeValue;
                                            break;
                                        case "System.Reflection.AssemblyCompanyAttribute":
                                            _companyName = _companyName ?? attributeValue;
                                            break;
                                        case "System.Reflection.AssemblyProductAttribute":
                                            _productName = _productName ?? attributeValue;
                                            break;
                                            // case "System.Reflection.AssemblyVersionAttribute":
                                            //  _assemblyVersion = _assemblyVersion == 0L ? (FourPartVersion)attributeValue : _assemblyVersion;
                                            // break;
                                        case "System.Reflection.AssemblyFileVersionAttribute":
                                            _fileVersion = _fileVersion == 0L ? (FourPartVersion)attributeValue : _fileVersion;
                                            _productVersion = _productVersion == 0L ? (FourPartVersion)attributeValue : _productVersion;
                                            break;
                                        case "System.Reflection.AssemblyCopyrightAttribute":
                                            _legalCopyright = _legalCopyright ?? attributeValue;
                                            break;
                                        case "System.Reflection.AssemblyTrademarkAttribute":
                                            _legalTrademarks = _legalTrademarks ?? attributeValue;
                                            break;
                                        case "System.Reflection.AssemblyDescriptionAttribute":
                                            _comments = _comments ?? attributeValue;
                                            break;
                                        case "BugTrackerAttribute":
                                            _bugTracker = _bugTracker ?? attributeValue;
                                            break;
                                    }
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    Console.WriteLine("{0} -- {1}", e.Message, e.StackTrace);
                }

                // if there are dependencies, this will load them.
                if (_loadOptions.HasFlag(BinaryLoadOptions.UnsignedManagedDependencies)) {
                    LoadUnsignedManagedDependencies();
                }
            }));
        }
Esempio n. 22
0
        internal static void Amend(params string[] targets)
        {
            // Ensure that at least one target assembly was specified
            if (targets == null || targets.Length == 0)
            {
                throw new ArgumentException("At least one target assembly must be specified.");
            }

            // Ensure that the target assemblies exist
            for (int i = 0; i < targets.Length; i++)
            {
                var path = targets[i] = Path.GetFullPath(targets[i]);
                if (!File.Exists(path))
                {
                    throw new ArgumentException("The specified target assembly, " + path + ", does not exist.");
                }
            }

            // Determine the set of target directories and backup locations
            var directories = targets
                              .Select(path => Path.GetDirectoryName(path).ToLower())
                              .Distinct()
                              .Select(directory => new { SourcePath = directory, BackupPath = Directory.CreateDirectory(Path.Combine(directory, "Backup")).FullName });

            // Determine the set of dlls, pdbs, and backup files
            var assemblies = targets
                             .Select(dllPath => new
            {
                DllPath       = dllPath,
                DllBackupPath = Path.Combine(Path.Combine(Path.GetDirectoryName(dllPath), "Backup"), Path.GetFileName(dllPath)),
                PdbPath       = Path.Combine(Path.GetDirectoryName(dllPath), Path.GetFileNameWithoutExtension(dllPath) + ".pdb"),
                PdbBackupPath = Path.Combine(Path.Combine(Path.GetDirectoryName(dllPath), "Backup"), Path.GetFileNameWithoutExtension(dllPath) + ".pdb")
            });

            // Backup the directories containing the targeted dll and pdb files
            foreach (var directory in directories)
            {
                foreach (var file in Directory.GetFiles(directory.SourcePath))
                {
                    if (file.ToLower().EndsWith("exe") || file.ToLower().EndsWith("dll") || file.ToLower().EndsWith("pdb"))
                    {
                        File.Copy(file, Path.Combine(directory.BackupPath, Path.GetFileName(file)), true);
                    }
                }
            }

            // Register an assembly resolver to look in backup folders when resolving assemblies
            AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
            {
                try
                {
                    return(System.Reflection.Assembly.Load(e.Name));
                }
                catch
                {
                    foreach (var directory in directories)
                    {
                        var dependency = Path.Combine(directory.BackupPath, e.Name.Substring(0, e.Name.IndexOf(',')) + ".dll");
                        if (File.Exists(dependency))
                        {
                            return(System.Reflection.Assembly.LoadFrom(dependency));
                        }
                    }
                    return(null);
                }
            };

            // Get the set of amendments to apply from all of the specified assemblies
            var amendments = AmendmentAttribute.GetAmendments(assemblies.Select(a => System.Reflection.Assembly.LoadFrom(a.DllBackupPath)).ToArray()).ToList();

            // Exit immediately if there are no amendments in the target assemblies
            if (amendments.Count == 0)
            {
                return;
            }

            // Process each target assembly individually
            foreach (var assembly in assemblies)
            {
                var assemblyAmendments = amendments.Where(a => a.Type.Assembly.Location == assembly.DllBackupPath).ToArray();
                if (assemblyAmendments.Length == 0)
                {
                    continue;
                }

                Console.Write("Amending " + Path.GetFileName(assembly.DllPath));
                var start = DateTime.Now;

                using (var host = new PeReader.DefaultHost())
                {
                    // Load the target assembly
                    IModule module = host.LoadUnitFrom(assembly.DllBackupPath) as IModule;
                    if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                    {
                        throw new ArgumentException(assembly.DllBackupPath + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
                    }

                    // Copy the assembly to enable it to be mutated
                    module = new MetadataDeepCopier(host).Copy(module);

                    // Load the debug file if it exists
                    PdbReader pdbReader = null;
                    if (File.Exists(assembly.PdbBackupPath))
                    {
                        using (var pdbStream = File.OpenRead(assembly.PdbBackupPath))
                        {
                            pdbReader = new PdbReader(pdbStream, host);
                        }
                    }

                    // Amend and persist the target assembly
                    using (pdbReader)
                    {
                        // Create and execute a new assembly amender
                        AssemblyAmender amender = new AssemblyAmender(host, pdbReader, assemblyAmendments);
                        amender.TargetRuntimeVersion = module.TargetRuntimeVersion;
                        module = amender.Visit(module);

                        // Save the amended assembly back to the original directory
                        using (var pdbWriter = pdbReader != null ? new PdbWriter(assembly.PdbPath, pdbReader) : null)
                        {
                            using (var dllStream = File.Create(assembly.DllPath))
                            {
                                PeWriter.WritePeToStream(module, host, dllStream, pdbReader, null, pdbWriter);
                            }
                        }
                    }
                }
                Console.WriteLine(" (" + DateTime.Now.Subtract(start).TotalSeconds.ToString("0.000") + " seconds)");
            }
        }
Esempio n. 23
0
 /// <summary>
 /// Returns a mutable Code Model module that is equivalent to the given Metadata Model module,
 /// except that in the new module method bodies also implement ISourceMethodBody.
 /// </summary>
 /// <param name="host">An object representing the application that is hosting this decompiler. It is used to obtain access to some global
 /// objects and services such as the shared name table and the table for interning references.</param>
 /// <param name="module">The root of the Metadata Model to be converted to a Code Model.</param>
 /// <param name="sourceLocationProvider">An object that can map some kinds of ILocation objects to IPrimarySourceLocation objects. May be null.</param>
 /// <param name="localScopeProvider">An object that can provide information about the local scopes of a method. May be null.</param>
 /// <param name="options">Set of options that control decompilation.</param>
 private static Module GetCodeModelFromMetadataModelHelper(IMetadataHost host, IModule module,
     ISourceLocationProvider/*?*/ sourceLocationProvider, ILocalScopeProvider/*?*/ localScopeProvider, DecompilerOptions options)
 {
     var result = new MetadataDeepCopier(host).Copy(module);
       var replacer = new ReplaceMetadataMethodBodiesWithDecompiledMethodBodies(host, module, sourceLocationProvider, localScopeProvider, options);
       replacer.Traverse(result);
       var finder = new HelperTypeFinder(host, sourceLocationProvider);
       finder.Traverse(result);
       var remover = new RemoveUnnecessaryTypes(finder.helperTypes, finder.helperMethods, finder.helperFields);
       remover.Traverse(result);
       result.AllTypes.RemoveAll(td => finder.helperTypes.ContainsKey(td.InternedKey)); // depends on RemoveAll preserving order
       return result;
 }
Esempio n. 24
0
		/// <summary>
		/// Amends the specified target assembly, optionally using assembly amendments defined in the 
		/// specified amendment assemblies.
		/// </summary>
		/// <param name="targetAssembly"></param>
		/// <param name="amendmentAssemblies"></param>
		internal static void Amend(string targetAssembly, string[] amendmentAssemblies, string[] referenceAssemblies)
		{
			// Verify the target assembly exists
			targetAssembly = Path.GetFullPath(targetAssembly);
			if (!File.Exists(targetAssembly))
				throw new ArgumentException("The specified target assembly, " + targetAssembly + ", does not exist.");

			// Verify the amendment assemblies exist
			if (amendmentAssemblies == null)
				amendmentAssemblies = new string[0];
			for (int i = 0; i < amendmentAssemblies.Length; i++)
			{
				var path = amendmentAssemblies[i] = Path.GetFullPath(amendmentAssemblies[i]);
				if (!File.Exists(path))
					throw new ArgumentException("The specified amendment assembly, " + path + ", does not exist.");
			}

			// Verify that the target has not already been amended
			var afterthoughtTracker = targetAssembly + ".afterthought";
			if (File.Exists(afterthoughtTracker) && File.GetLastWriteTime(targetAssembly) == File.GetLastWriteTime(afterthoughtTracker))
				return;

			// Determine the set of target directories and backup locations
			var targetWriteTime = File.GetLastWriteTime(targetAssembly);
			var backupTargetAssembly = targetAssembly + ".backup";
			var targetDirectory = Path.GetDirectoryName(targetAssembly);
			File.Delete(backupTargetAssembly);
			File.Move(targetAssembly, backupTargetAssembly);

			// Build up a set of paths with resolving assemblies
			var referencePaths = new Dictionary<string, string>();
			foreach (string path in amendmentAssemblies
				.Union(referenceAssemblies)
				.Union(Directory.GetFiles(targetDirectory).Where(p => p.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) && p != targetAssembly)))
				referencePaths[Path.GetFileName(path)] = path;

			// Register an assembly resolver to look in assembly directories when resolving assemblies
			AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
			{
				var assemblyName = new System.Reflection.AssemblyName(e.Name).Name + ".dll";
				string referencePath;
				if (referencePaths.TryGetValue(assemblyName, out referencePath))
					return System.Reflection.Assembly.LoadFrom(referencePath);

				return null;
			};

			// Get the set of amendments to apply from all of the specified assemblies
			var assemblies = new System.Reflection.Assembly[] { System.Reflection.Assembly.LoadFrom(backupTargetAssembly) }.Union(amendmentAssemblies.Select(a => System.Reflection.Assembly.LoadFrom(a)));
			var amendments = AmendmentAttribute.GetAmendments(assemblies.First(), assemblies.Skip(1).ToArray()).ToList();

			// Exit immediately if there are no amendments in the target assemblies
			if (amendments.Count == 0)
			    return;

			// Amend the target assembly
			Console.Write("Amending " + Path.GetFileName(targetAssembly));
			var start = DateTime.Now;

			using (var host = new PeReader.DefaultHost())
			{
				foreach (var referencePath in referencePaths.Select(p => Path.GetDirectoryName(p.Value)).Distinct())
					host.AddLibPath(referencePath);

				// Load the target assembly
				IModule module = host.LoadUnitFrom(backupTargetAssembly) as IModule;
				if (module == null || module == Dummy.Module || module == Dummy.Assembly)
					throw new ArgumentException(backupTargetAssembly + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");

				// Copy the assembly to enable it to be mutated
				module = new MetadataDeepCopier(host).Copy(module);

				// Load the debug file if it exists
				PdbReader pdbReader = null;
				var pdbFile = Path.Combine(targetDirectory, Path.GetFileNameWithoutExtension(targetAssembly) + ".pdb");
				var backupPdbFile = pdbFile + ".backup";
				if (File.Exists(pdbFile))
				{
					File.Delete(backupPdbFile);
					File.Move(pdbFile, backupPdbFile);
					using (var pdbStream = File.OpenRead(backupPdbFile))
					{
						pdbReader = new PdbReader(pdbStream, host);
					}
				}
					
				// Amend and persist the target assembly
				using (pdbReader)
				{
					// Create and execute a new assembly amender
					AssemblyAmender amender = new AssemblyAmender(host, pdbReader, amendments, assemblies);
					amender.TargetRuntimeVersion = module.TargetRuntimeVersion;
					module = amender.Visit(module);

					// Save the amended assembly back to the original directory
					var localScopeProvider = pdbReader == null ? null : new ILGenerator.LocalScopeProvider(pdbReader);
					using (var pdbWriter = pdbReader != null ? new PdbWriter(pdbFile, pdbReader) : null)
					{
						using (var dllStream = File.Create(targetAssembly))
						{
							PeWriter.WritePeToStream(module, host, dllStream, pdbReader, localScopeProvider, pdbWriter);
						}
					}
				}

				File.SetLastWriteTime(targetAssembly, targetWriteTime);
				if (pdbReader != null)
					File.SetLastWriteTime(pdbFile, targetWriteTime);
			}

			Console.WriteLine(" (" + DateTime.Now.Subtract(start).TotalSeconds.ToString("0.000") + " seconds)");

			// Set the last write time of the afterthought tracker to match the amended assembly to prevent accidental reamending
			File.WriteAllText(afterthoughtTracker, "");
			File.SetLastWriteTime(afterthoughtTracker, File.GetLastWriteTime(targetAssembly));
		}
Esempio n. 25
0
        static void Main(string[] args)
        {
            if (args == null || args.Length == 0)
            {
                Console.WriteLine("usage: PeToPe [path]fileName.ext [decompile] [noStack]");
                return;
            }
            bool decompile = args.Length >= 2;
            bool noStack   = args.Length >= 3;

            using (var host = new HostEnvironment()) {
                //Read the Metadata Model from the PE file
                var module = host.LoadUnitFrom(args[0]) as IModule;
                if (module == null || module is Dummy)
                {
                    Console.WriteLine(args[0] + " is not a PE file containing a CLR module or assembly.");
                    return;
                }

                //Get a PDB reader if there is a PDB file.
                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = module.DebugInformationLocation;
                if (string.IsNullOrEmpty(pdbFile) || !File.Exists(pdbFile))
                {
                    pdbFile = Path.ChangeExtension(module.Location, "pdb");
                }
                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile)) {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                using (pdbReader) {
                    ISourceLocationProvider sourceLocationProvider = pdbReader;
                    ILocalScopeProvider     localScopeProvider     = pdbReader;
                    if (decompile)
                    {
                        //Construct a Code Model from the Metadata model via decompilation
                        var options = DecompilerOptions.AnonymousDelegates | DecompilerOptions.Iterators | DecompilerOptions.Loops;
                        if (noStack)
                        {
                            options |= DecompilerOptions.Unstack;
                        }
                        module = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader, options);
                        if (pdbReader != null)
                        {
                            localScopeProvider = new Decompiler.LocalScopeProvider(pdbReader);
                        }
                    }

                    MetadataRewriter   rewriter;
                    MetadataDeepCopier copier;
                    if (decompile)
                    {
                        copier   = new CodeDeepCopier(host, pdbReader, pdbReader);
                        rewriter = new CodeRewriter(host);
                    }
                    else
                    {
                        copier   = new MetadataDeepCopier(host);
                        rewriter = new MetadataRewriter(host);
                    }

                    var mutableModule = copier.Copy(module);
                    module = rewriter.Rewrite(mutableModule);

                    //var validator = new MetadataValidator(host);
                    //List<Microsoft.Cci.ErrorEventArgs> errorEvents = new List<Microsoft.Cci.ErrorEventArgs>();
                    //host.Errors += (object sender, Microsoft.Cci.ErrorEventArgs e) => errorEvents.Add(e);
                    //var assem = module as IAssembly;
                    //validator.Validate(assem);
                    //if (errorEvents.Count != 0)
                    //{
                    //    foreach (var e in errorEvents)
                    //    {
                    //        foreach (var err in e.Errors)
                    //        {
                    //            Console.WriteLine(err.Message);
                    //        }
                    //    }
                    //}

#if DEBUG
                    var newRoot = Path.GetFileNameWithoutExtension(module.Location) + "1";
                    var newName = newRoot + Path.GetExtension(module.Location);
                    using (Stream peStream = File.Create(newName)) {
                        if (pdbReader == null)
                        {
                            PeWriter.WritePeToStream(module, host, peStream);
                        }
                        else
                        {
                            using (var pdbWriter = new PdbWriter(newRoot + ".pdb", pdbReader, emitTokenSourceInfo: true)) {
                                PeWriter.WritePeToStream(module, host, peStream, sourceLocationProvider, localScopeProvider, pdbWriter);
                            }
                        }
                    }
#else
                    using (Stream peStream = File.Create(module.Location)) {
                        if (pdbReader == null)
                        {
                            PeWriter.WritePeToStream(module, host, peStream);
                        }
                        else
                        {
                            using (var pdbWriter = new PdbWriter(pdbFile, pdbReader, emitTokenSourceInfo: true)) {
                                PeWriter.WritePeToStream(module, host, peStream, sourceLocationProvider, localScopeProvider, pdbWriter);
                            }
                        }
                    }
#endif
                }
            }
        }
Esempio n. 26
0
 public ITypeReference Map(ITypeReference typeReference)
 {
     var result = new MetadataDeepCopier(host).Copy(typeReference);
       var rewriter = new ActualMutator(host, targetUnit, sourceUnitIdentity);
       return rewriter.Rewrite(result);
 }
Esempio n. 27
0
        public static Assembly PruneAssembly(HostEnvironment host, ISlice <MethodReferenceAdaptor, FieldReferenceAdaptor, TypeReferenceAdaptor, IAssemblyReference> slice)
        {
            Contract.Requires(host != null);
            Contract.Requires(slice != null);

            var newAssemblyName  = slice.Name;
            var originalAssembly = slice.ContainingAssembly.ResolvedAssembly;

            Contract.Assume(!(originalAssembly is Dummy));
            var methodDefsToKeep = new HashSet <uint>();

            foreach (var m in slice.Methods)
            {
                methodDefsToKeep.Add(m.reference.InternedKey);
            }


            var copier               = new MetadataDeepCopier(host);
            var thingsToKeep         = new HashSet <object>();
            var methodHashAttributes = new Dictionary <IMethodDefinition, MethodHashAttribute>();
            var me = new Prune(host, copier, thingsToKeep, methodDefsToKeep, methodHashAttributes);

            // 1. everything that is specified in the slice should definitely be kept.
            foreach (var c in slice.Chains)
            {
                me.VisitChain(c);
            }

            // 2. everything reachable from the initial set of things to keep should be kept
            Dictionary <IMethodDefinition, uint> contractOffsets;

            FindReachable.Reachable(host, slice, thingsToKeep, methodDefsToKeep, out contractOffsets);
            me.contractOffsets = contractOffsets;

            // 3. copy the original assembly --- entirely!
            var a_prime   = copier.Copy(originalAssembly);
            var nameTable = host.NameTable;

            a_prime.ModuleName = nameTable.GetNameFor(newAssemblyName + ".dll");
            a_prime.Name       = nameTable.GetNameFor(newAssemblyName);

            var mutableRoot             = (RootUnitNamespace)(a_prime.UnitNamespaceRoot);
            var methodHashAttributeType = DefineMethodHashAttributeType(host, mutableRoot);

            me.methodHashAttributeCtor = new Microsoft.Cci.MethodReference(
                host,
                methodHashAttributeType,
                CallingConvention.HasThis,
                host.PlatformType.SystemVoid,
                host.NameTable.Ctor,
                0,
                me.systemString,
                me.systemInt);

            // 4. delete all unwanted things from the mutable copy
            me.RewriteChildren(a_prime);

            var remainingTypes = new List <INamedTypeDefinition>(a_prime.AllTypes.Count); // will only shrink

            remainingTypes.Add(a_prime.AllTypes[0]);                                      // <Module> class is always kept
            for (int i = 1, n = a_prime.AllTypes.Count; i < n; i++)
            {
                var t = a_prime.AllTypes[i];
                Contract.Assume(t != null);
                Contract.Assume(copier.OriginalFor.ContainsKey(t));
                var orig = copier.OriginalFor[t];
                if (thingsToKeep.Contains(orig))
                {
                    remainingTypes.Add(t);
                }
            }
            a_prime.AllTypes = remainingTypes;
            // do this afterwards so it doesn't get visited.
            mutableRoot.Members.Add(methodHashAttributeType);
            a_prime.AllTypes.Add(methodHashAttributeType);

            return(a_prime);
        }
Esempio n. 28
0
        public static void RunBclRewriter(string[] args)
        {
            #region Parse the command-line arguments.
            if (!Parser.ParseArgumentsWithUsage(args, typeof(Program)))
            {
                throw new UsageException();
            }
            #endregion

            #region Figure out paths
            s_assemblyName = Path.GetFullPath(s_assemblyName); // this has to be specified

            string outputBaseName = null;
            if (!String.IsNullOrEmpty(s_output))
            {
                s_output       = Path.GetFullPath(s_output);
                outputBaseName = Path.GetFileNameWithoutExtension(s_output);
            }
            else
            {
                s_output       = Path.Combine(Directory.GetCurrentDirectory(), Path.GetFileNameWithoutExtension(s_assemblyName) + ".small" + Path.GetExtension(s_assemblyName));
                outputBaseName = s_assemblyName;
            }

            string pdbSourceFile = Path.ChangeExtension(s_assemblyName, "pdb");
            string outputPdb     = Path.ChangeExtension(s_output, "pdb");
            string outputFolder  = Path.GetDirectoryName(s_output);

            // if the user wants to do an in-place rewrite, we copy the file to a temp file
            if (s_output == s_assemblyName)
            {
                String tempPath    = s_assemblyName + TempExtension;
                String tempPdbPath = pdbSourceFile + TempExtension;

                File.Copy(s_assemblyName, tempPath, true);
                s_assemblyName = tempPath;

                if (File.Exists(pdbSourceFile))
                {
                    File.Copy(pdbSourceFile, tempPdbPath, true);
                    pdbSourceFile = tempPdbPath;
                }
            }

            if (!Directory.Exists(outputFolder))
            {
                Directory.CreateDirectory(outputFolder);
            }

            #endregion

            #region Load input files
            HostEnvironment host = new HostEnvironment(new NameTable(), s_assemblyDependencyPaths, s_referencedAssemblies);

            IAssembly /*?*/ assembly = host.LoadUnitFrom(s_assemblyName) as IAssembly;
            // TODO: Handle multimodule assemblies
            if (assembly == null || assembly == Dummy.Assembly)
            {
                throw new UsageException(args[0] + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
            }

            if (!File.Exists(s_includeListFile))
            {
                throw new UsageException(String.Format("ERROR: Can't find code model file '{0}'", s_includeListFile));
            }

            ThinModel model = new ThinModel(new ThinnerOptions(host, new AssemblyIdentity[] { assembly.AssemblyIdentity }));
            model.LoadModel(s_includeListFile, new ModelReaderOptions(s_platform, s_architecture, s_flavor, s_treatFxInternalAsPublic, s_defines));
            #endregion

            #region Calculate api closure.
            ConsoleTimer.StartTimer("Calculating api closure");
            model.LoadMetadataFrom(assembly);

            ThinModel apiClosure = model.CalculateApiClosure();
            if (s_keepTempFiles)
            {
                apiClosure.SaveModel(Path.ChangeExtension(s_output, ".apiClosure.xml"));
            }
            ConsoleTimer.EndTimer("Calculating api closure");
            #endregion

            #region Calculate impl closure.
            ConsoleTimer.StartTimer("Calculating implementation closure");
            apiClosure.LoadMetadataFrom(assembly);

            ThinModel implClosure = apiClosure.CalculateImplementationClosure(true, FieldOptions.KeepAll);

            if (s_keepTempFiles)
            {
                implClosure.SaveModel(Path.ChangeExtension(s_output, ".implClosure.xml"));
            }
            ConsoleTimer.EndTimer("Calculating implementation closure");
            #endregion

            #region Trim.
            ConsoleTimer.StartTimer("Trimming assembly");
            IncludeSet includeSet = new IncludeSet();
            includeSet.LoadFrom(implClosure);

            var      copier         = new MetadataDeepCopier(host);
            Assembly copiedAssembly = copier.Copy(assembly);

            Trimmer trimmer = new Trimmer(includeSet, true, false, true, host, s_removeSerializable);
            trimmer.RewriteChildren(copiedAssembly);
            Assembly mutableAssembly = copiedAssembly;
            assembly = mutableAssembly;

            ConsoleTimer.EndTimer("Trimming assembly");
            #endregion

            #region Update assembly name.
            ConsoleTimer.StartTimer("Updating assembly name");

            // If the output assembly name is different, update the internal assembly name to match.
            AssemblyIdentity originalAssemblyIdentity = mutableAssembly.AssemblyIdentity;
            if (!outputBaseName.Equals(originalAssemblyIdentity.Name.ToString(), StringComparison.OrdinalIgnoreCase))
            {
                mutableAssembly.Name       = host.NameTable.GetNameFor(outputBaseName);
                mutableAssembly.ModuleName = mutableAssembly.Name;
            }

            // If we changed the assembly identity, update references to it.
            if (!mutableAssembly.AssemblyIdentity.Equals(originalAssemblyIdentity))
            {
                trimmer.UpdateAssemblyReferences(originalAssemblyIdentity, mutableAssembly.AssemblyIdentity);
            }

            ConsoleTimer.EndTimer("Updating assembly name");
            #endregion

            #region Write out the assembly
            ConsoleTimer.StartTimer("Writing assembly");
            PdbReader pdbReader = null;
            PdbWriter pdbWriter = null;
            if (File.Exists(pdbSourceFile))
            {
                Stream pdbStream = File.OpenRead(pdbSourceFile);
                pdbReader = new PdbReader(pdbStream, host);
                pdbWriter = new PdbWriter(outputPdb, pdbReader);
                Console.WriteLine("Writing pdb: {0}", outputPdb);
            }

            Console.WriteLine("Writing assembly: {0}", s_output);
            FileStream file = File.Create(s_output);

            try
            {
                PeWriter.WritePeToStream(assembly, host, file, pdbReader, pdbReader, pdbWriter);
            }
            finally
            {
                if (file != null)
                {
                    file.Dispose();
                }

                if (pdbWriter != null)
                {
                    pdbWriter.Dispose();
                }
            }

            ConsoleTimer.EndTimer("Writing assembly");
            #endregion
        }
Esempio n. 29
0
        internal static void Amend(params string[] targets)
        {
            // Ensure that at least one target assembly was specified
            if (targets == null || targets.Length == 0)
                throw new ArgumentException("At least one target assembly must be specified.");

            // Ensure that the target assemblies exist
            for (int i = 0; i < targets.Length; i++)
            {
                var path = targets[i] = Path.GetFullPath(targets[i]);
                if (!File.Exists(path))
                    throw new ArgumentException("The specified target assembly, " + path + ", does not exist.");
            }

            // Determine the set of target directories and backup locations
            var directories = targets
                .Select(path => Path.GetDirectoryName(path).ToLower())
                .Distinct()
                .Select(directory => new { SourcePath = directory, BackupPath = Directory.CreateDirectory(Path.Combine(directory, "Backup")).FullName });

            // Determine the set of dlls, pdbs, and backup files
            var assemblies = targets
                .Select(dllPath => new
                {
                    DllPath = dllPath,
                    DllBackupPath = Path.Combine(Path.Combine(Path.GetDirectoryName(dllPath), "Backup"), Path.GetFileName(dllPath)),
                    PdbPath = Path.Combine(Path.GetDirectoryName(dllPath), Path.GetFileNameWithoutExtension(dllPath) + ".pdb"),
                    PdbBackupPath = Path.Combine(Path.Combine(Path.GetDirectoryName(dllPath), "Backup"), Path.GetFileNameWithoutExtension(dllPath) + ".pdb")
                });

            // Backup the directories containing the targeted dll and pdb files
            foreach (var directory in directories)
            {
                foreach (var file in Directory.GetFiles(directory.SourcePath))
                {
                    if (file.ToLower().EndsWith("exe") || file.ToLower().EndsWith("dll") || file.ToLower().EndsWith("pdb"))
                    {
                        var backupPath = Path.Combine(directory.BackupPath, Path.GetFileName(file));
                        if (File.Exists(backupPath))
                            File.SetAttributes(backupPath, File.GetAttributes(backupPath) & ~FileAttributes.ReadOnly);
                        File.Copy(file, backupPath, true);
                    }
                }
            }

            // Register an assembly resolver to look in backup folders when resolving assemblies
            AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
            {
                var assemblyName = new AssemblyName(e.Name).Name + ".dll";

                // First see if the assembly is located in one of the target backup directories
                foreach (var directory in directories)
                {
                    var dependency = Path.Combine(directory.BackupPath, assemblyName);
                    if (File.Exists(dependency))
                        return System.Reflection.Assembly.LoadFrom(dependency);
                }

                return null;
            };

            // Get the set of amendments to apply from all of the specified assemblies
            var amendments = AmendmentAttribute.GetAmendments(assemblies.Select(a => System.Reflection.Assembly.LoadFrom(a.DllBackupPath)).ToArray()).ToList();

            // Exit immediately if there are no amendments in the target assemblies
            if (amendments.Count == 0)
                return;

            // Process each target assembly individually
            foreach (var assembly in assemblies)
            {
                var assemblyAmendments = amendments.Where(a => a.Type.Assembly.Location == assembly.DllBackupPath).ToArray();
                if (assemblyAmendments.Length == 0)
                    continue;

                Console.Write("Amending " + Path.GetFileName(assembly.DllPath));
                var start = DateTime.Now;

                using (var host = new PeReader.DefaultHost())
                {
                    // Load the target assembly
                    IModule module = host.LoadUnitFrom(assembly.DllBackupPath) as IModule;
                    if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                        throw new ArgumentException(assembly.DllBackupPath + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");

                    // Copy the assembly to enable it to be mutated
                    module = new MetadataDeepCopier(host).Copy(module);

                    // Load the debug file if it exists
                    PdbReader pdbReader = null;
                    if (File.Exists(assembly.PdbBackupPath))
                    {
                        using (var pdbStream = File.OpenRead(assembly.PdbBackupPath))
                        {
                            pdbReader = new PdbReader(pdbStream, host);
                        }
                    }

                    // Amend and persist the target assembly
                    using (pdbReader)
                    {
                        // Create and execute a new assembly amender
                        AssemblyAmender amender = new AssemblyAmender(host, pdbReader, assemblyAmendments);
                        amender.TargetRuntimeVersion = module.TargetRuntimeVersion;
                        module = amender.Visit(module);

                        // Save the amended assembly back to the original directory
                        using (var pdbWriter = pdbReader != null ? new PdbWriter(assembly.PdbPath, pdbReader) : null)
                        {
                            using (var dllStream = File.Create(assembly.DllPath))
                            {
                                PeWriter.WritePeToStream(module, host, dllStream, pdbReader, null, pdbWriter);
                            }
                        }
                    }
                }
                Console.WriteLine(" (" + DateTime.Now.Subtract(start).TotalSeconds.ToString("0.000") + " seconds)");
            }
        }
Esempio n. 30
0
        public static bool Execute(
            string seeds,
            string contracts,
            string facadePath,
            Version assemblyFileVersion               = null,
            bool clearBuildAndRevision                = false,
            bool ignoreMissingTypes                   = false,
            bool ignoreBuildAndRevisionMismatch       = false,
            bool buildDesignTimeFacades               = false,
            string inclusionContracts                 = null,
            ErrorTreatment seedLoadErrorTreatment     = ErrorTreatment.Default,
            ErrorTreatment contractLoadErrorTreatment = ErrorTreatment.Default,
            string[] seedTypePreferencesUnsplit       = null,
            bool forceZeroVersionSeeds                = false,
            bool producePdb = true,
            string partialFacadeAssemblyPath = null)
        {
            if (!Directory.Exists(facadePath))
            {
                Directory.CreateDirectory(facadePath);
            }

            var nameTable     = new NameTable();
            var internFactory = new InternFactory();

            try
            {
                Dictionary <string, string> seedTypePreferences = ParseSeedTypePreferences(seedTypePreferencesUnsplit);

                using (var contractHost = new HostEnvironment(nameTable, internFactory))
                    using (var seedHost = new HostEnvironment(nameTable, internFactory))
                    {
                        contractHost.LoadErrorTreatment = contractLoadErrorTreatment;
                        seedHost.LoadErrorTreatment     = seedLoadErrorTreatment;

                        var contractAssemblies = LoadAssemblies(contractHost, contracts);
                        IReadOnlyDictionary <string, IEnumerable <string> > docIdTable = GenerateDocIdTable(contractAssemblies, inclusionContracts);

                        IAssembly[] seedAssemblies = LoadAssemblies(seedHost, seeds).ToArray();

                        IAssemblyReference seedCoreAssemblyRef = ((Microsoft.Cci.Immutable.PlatformType)seedHost.PlatformType).CoreAssemblyRef;

                        if (forceZeroVersionSeeds)
                        {
                            // Create a deep copier, copy the seed assemblies, and zero out their versions.
                            var copier = new MetadataDeepCopier(seedHost);

                            for (int i = 0; i < seedAssemblies.Length; i++)
                            {
                                var mutableSeed = copier.Copy(seedAssemblies[i]);
                                mutableSeed.Version = new Version(0, 0, 0, 0);
                                // Copy the modified seed assembly back.
                                seedAssemblies[i] = mutableSeed;

                                if (mutableSeed.Name.UniqueKey == seedCoreAssemblyRef.Name.UniqueKey)
                                {
                                    seedCoreAssemblyRef = mutableSeed;
                                }
                            }
                        }

                        var typeTable       = GenerateTypeTable(seedAssemblies);
                        var facadeGenerator = new FacadeGenerator(seedHost, contractHost, docIdTable, typeTable, seedTypePreferences, clearBuildAndRevision, buildDesignTimeFacades, assemblyFileVersion);

                        if (partialFacadeAssemblyPath != null)
                        {
                            if (contractAssemblies.Count() != 1)
                            {
                                throw new FacadeGenerationException(
                                          "When partialFacadeAssemblyPath is specified, only exactly one corresponding contract assembly can be specified.");
                            }

                            IAssembly contractAssembly      = contractAssemblies.First();
                            IAssembly partialFacadeAssembly = seedHost.LoadAssembly(partialFacadeAssemblyPath);
                            if (contractAssembly.Name != partialFacadeAssembly.Name ||
                                contractAssembly.Version.Major != partialFacadeAssembly.Version.Major ||
                                contractAssembly.Version.Minor != partialFacadeAssembly.Version.Minor ||
                                (!ignoreBuildAndRevisionMismatch && contractAssembly.Version.Build != partialFacadeAssembly.Version.Build) ||
                                (!ignoreBuildAndRevisionMismatch && contractAssembly.Version.Revision != partialFacadeAssembly.Version.Revision) ||
                                contractAssembly.GetPublicKeyToken() != partialFacadeAssembly.GetPublicKeyToken())
                            {
                                throw new FacadeGenerationException(
                                          string.Format("The partial facade assembly's name, version, and public key token must exactly match the contract to be filled. Contract: {0}, Facade: {1}",
                                                        contractAssembly.AssemblyIdentity,
                                                        partialFacadeAssembly.AssemblyIdentity));
                            }

                            Assembly filledPartialFacade = facadeGenerator.GenerateFacade(contractAssembly, seedCoreAssemblyRef, ignoreMissingTypes, overrideContractAssembly: partialFacadeAssembly);

                            if (filledPartialFacade == null)
                            {
                                Trace.TraceError("Errors were encountered while generating the facade.");
                                return(false);
                            }

                            string pdbLocation = null;

                            if (producePdb)
                            {
                                string pdbFolder = Path.GetDirectoryName(partialFacadeAssemblyPath);
                                pdbLocation = Path.Combine(pdbFolder, contractAssembly.Name + ".pdb");
                                if (producePdb && !File.Exists(pdbLocation))
                                {
                                    pdbLocation = null;
                                    Trace.TraceWarning("No PDB file present for un-transformed partial facade. No PDB will be generated.");
                                }
                            }

                            OutputFacadeToFile(facadePath, seedHost, filledPartialFacade, contractAssembly, pdbLocation);
                        }
                        else
                        {
                            foreach (var contract in contractAssemblies)
                            {
                                Assembly facade = facadeGenerator.GenerateFacade(contract, seedCoreAssemblyRef, ignoreMissingTypes);
                                if (facade == null)
                                {
#if !COREFX
                                    Debug.Assert(Environment.ExitCode != 0);
#endif
                                    return(false);
                                }

                                OutputFacadeToFile(facadePath, seedHost, facade, contract);
                            }
                        }
                    }

                return(true);
            }
            catch (FacadeGenerationException ex)
            {
                Trace.TraceError(ex.Message);
#if !COREFX
                Debug.Assert(Environment.ExitCode != 0);
#endif
                return(false);
            }
        }
Esempio n. 31
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);
                        }
                    }
                }
            }
        }
Esempio n. 32
0
    public static Assembly PruneAssembly(HostEnvironment host, ISlice<MethodReferenceAdaptor, FieldReferenceAdaptor, TypeReferenceAdaptor, IAssemblyReference> slice) {
      Contract.Requires(host != null);
      Contract.Requires(slice != null);

      var newAssemblyName = slice.Name;
      var originalAssembly = slice.ContainingAssembly.ResolvedAssembly;
      Contract.Assume(!(originalAssembly is Dummy));
      var methodDefsToKeep = new HashSet<uint>();
      foreach (var m in slice.Methods) {
        methodDefsToKeep.Add(m.reference.InternedKey);
      }


      var copier = new MetadataDeepCopier(host);
      var thingsToKeep = new HashSet<object>();
      var methodHashAttributes = new Dictionary<IMethodDefinition, MethodHashAttribute>();
      var me = new Prune(host, copier, thingsToKeep, methodDefsToKeep, methodHashAttributes);

      // 1. everything that is specified in the slice should definitely be kept.
      foreach (var c in slice.Chains) {
        me.VisitChain(c);
      }

      // 2. everything reachable from the initial set of things to keep should be kept
      Dictionary<IMethodDefinition, uint> contractOffsets;
      FindReachable.Reachable(host, slice, thingsToKeep, methodDefsToKeep, out contractOffsets);
      me.contractOffsets = contractOffsets;

      // 3. copy the original assembly --- entirely!
      var a_prime = copier.Copy(originalAssembly);
      var nameTable = host.NameTable;
      a_prime.ModuleName = nameTable.GetNameFor(newAssemblyName + ".dll");
      a_prime.Name = nameTable.GetNameFor(newAssemblyName);

      var mutableRoot = (RootUnitNamespace)(a_prime.UnitNamespaceRoot);
      var methodHashAttributeType = DefineMethodHashAttributeType(host, mutableRoot);
      me.methodHashAttributeCtor = new Microsoft.Cci.MethodReference(
          host,
          methodHashAttributeType,
          CallingConvention.HasThis,
          host.PlatformType.SystemVoid,
          host.NameTable.Ctor,
          0,
          me.systemString,
          me.systemInt);

      // 4. delete all unwanted things from the mutable copy
      me.RewriteChildren(a_prime);

      var remainingTypes = new List<INamedTypeDefinition>(a_prime.AllTypes.Count); // will only shrink
      remainingTypes.Add(a_prime.AllTypes[0]); // <Module> class is always kept
      for (int i = 1, n = a_prime.AllTypes.Count; i < n; i++) {
        var t = a_prime.AllTypes[i];
        Contract.Assume(t!= null);
        Contract.Assume(copier.OriginalFor.ContainsKey(t));
        var orig = copier.OriginalFor[t];
        if (thingsToKeep.Contains(orig))
          remainingTypes.Add(t);
      }
      a_prime.AllTypes = remainingTypes;
      // do this afterwards so it doesn't get visited.
      mutableRoot.Members.Add(methodHashAttributeType);
      a_prime.AllTypes.Add(methodHashAttributeType);

      return a_prime;
    }
    private static void TransformProgram(WholeProgram wholeProgram,
        string transformedBinariesPath,
        string reportsPath,
        MethodRemoval methodRemoval,
        TargetProfile profile) {

      System.IO.Directory.CreateDirectory(transformedBinariesPath);

      StubMethodBodyEmitter stubEmitter = GetStubMethodBodyEmitterForProfile(profile, wholeProgram);

      foreach (IAssembly assembly in wholeProgram.AllAssemblies()) {
        if (AssemblyShouldBeRewritten(assembly)) {

          if (assembly.PublicKeyToken.Count() > 0) {
            Console.WriteLine("Warning: rewriting assembly with a public key token. {0}", assembly);
          }

          string outputBinary = transformedBinariesPath + @"\" + Path.GetFileName(assembly.Location);

          var copy = new MetadataDeepCopier(wholeProgram.Host()).Copy(assembly);


          DocumentationCommentDefinitionIdStringMap idMap = new DocumentationCommentDefinitionIdStringMap(new IAssembly[] { copy });

          AssemblyReport assemblyReport = AssemblyReport.CreateAssemblyReportFromPath(copy, reportsPath, idMap);

          stopwatch.Start();
          RewriteBinary(copy, assemblyReport, wholeProgram.Host(), outputBinary, methodRemoval, stubEmitter);

          stopwatch.Start();
        }
        else {
          //Console.WriteLine("Skipping rewrite of of assembly {0}", assembly.Name.Value);
        }
      }
    }
Esempio n. 34
0
            public Assembly GenerateFacade(IAssembly contractAssembly, IAssemblyReference seedCoreAssemblyReference, bool ignoreMissingTypes, IAssembly overrideContractAssembly = null)
            {
                Assembly assembly;

                if (overrideContractAssembly != null)
                {
                    MetadataDeepCopier copier = new MetadataDeepCopier(_seedHost);
                    assembly = copier.Copy(overrideContractAssembly); // Use non-empty partial facade if present
                }
                else
                {
                    MetadataDeepCopier copier = new MetadataDeepCopier(_contractHost);
                    assembly = copier.Copy(contractAssembly);
                    ReferenceAssemblyToFacadeRewriter rewriter = new ReferenceAssemblyToFacadeRewriter(_seedHost, _contractHost, seedCoreAssemblyReference, _assemblyFileVersion != null);
                    rewriter.Rewrite(assembly);
                }

                IEnumerable <string> docIds = _docIdTable[contractAssembly.AssemblyIdentity.Name.Value];

                // Add all the type forwards
                bool error = false;

                HashSet <string>     existingDocIds = new HashSet <string>(assembly.AllTypes.Select(typeDef => typeDef.RefDocId()));
                IEnumerable <string> missingDocIds  = docIds.Where(id => !existingDocIds.Contains(id));

                foreach (string docId in missingDocIds)
                {
                    IReadOnlyList <INamedTypeDefinition> seedTypes;
                    if (!_typeTable.TryGetValue(docId, out seedTypes))
                    {
                        if (!ignoreMissingTypes)
                        {
                            Trace.TraceError("Did not find type '{0}' in any of the seed assemblies.", docId);
                            error = true;
                        }
                        continue;
                    }

                    INamedTypeDefinition seedType = GetSeedType(docId, seedTypes);
                    if (seedType == null)
                    {
                        TraceDuplicateSeedTypeError(docId, seedTypes);
                        error = true;
                        continue;
                    }

                    AddTypeForward(assembly, seedType);
                }

                if (error)
                {
                    return(null);
                }

                if (_assemblyFileVersion != null)
                {
                    assembly.AssemblyAttributes.Add(CreateAttribute("System.Reflection.AssemblyFileVersionAttribute", seedCoreAssemblyReference.ResolvedAssembly, _assemblyFileVersion.ToString()));
                    assembly.AssemblyAttributes.Add(CreateAttribute("System.Reflection.AssemblyInformationalVersionAttribute", seedCoreAssemblyReference.ResolvedAssembly, _assemblyFileVersion.ToString()));
                }

                if (_buildDesignTimeFacades)
                {
                    assembly.AssemblyAttributes.Add(CreateAttribute("System.Runtime.CompilerServices.ReferenceAssemblyAttribute", seedCoreAssemblyReference.ResolvedAssembly));
                    assembly.Flags |= ReferenceAssemblyFlag;
                }

                if (_clearBuildAndRevision)
                {
                    assembly.Version = new Version(assembly.Version.Major, assembly.Version.Minor, 0, 0);
                }

                AddWin32VersionResource(contractAssembly.Location, assembly);

                return(assembly);
            }
Esempio n. 35
0
        static void Main(string[] args)
        {
            if (args == null || args.Length == 0)
            {
                Console.WriteLine("usage: PeToPe [path]fileName.ext");
                return;
            }

            using (var host = new PeReader.DefaultHost()) {
                var module = host.LoadUnitFrom(args[0]) as IModule;
                if (module == null || module is Dummy)
                {
                    Console.WriteLine(args[0] + " is not a PE file containing a CLR module or assembly.");
                    return;
                }

                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = module.DebugInformationLocation;
                if (string.IsNullOrEmpty(pdbFile))
                {
                    pdbFile = Path.ChangeExtension(module.Location, "pdb");
                }
                if (File.Exists(pdbFile))
                {
                    Stream pdbStream = File.OpenRead(pdbFile);
                    pdbReader = new PdbReader(pdbStream, host);
                }

                using (pdbReader) {
                    //Make a mutable copy of the module.
                    var copier        = new MetadataDeepCopier(host);
                    var mutableModule = copier.Copy(module);

                    //Traverse the module. In a real application the MetadataVisitor and/or the MetadataTravers will be subclasses
                    //and the traversal will gather information to use during rewriting.
                    var traverser = new MetadataTraverser()
                    {
                        PreorderVisitor = new MetadataVisitor(), TraverseIntoMethodBodies = true
                    };
                    traverser.Traverse(mutableModule);

                    //Rewrite the mutable copy. In a real application the rewriter would be a subclass of MetadataRewriter that actually does something.
                    var rewriter        = new MetadataRewriter(host);
                    var rewrittenModule = rewriter.Rewrite(mutableModule);

                    //Write out rewritten module.
                    using (var peStream = File.Create(rewrittenModule.Location + ".pe")) {
                        if (pdbReader == null)
                        {
                            PeWriter.WritePeToStream(rewrittenModule, host, peStream);
                        }
                        else
                        {
                            //Note that the default copier and rewriter preserves the locations collections, so the original pdbReader is still a valid ISourceLocationProvider.
                            //However, if IL instructions were rewritten, the pdbReader will no longer be an accurate ILocalScopeProvider
                            using (var pdbWriter = new PdbWriter(pdbFile + ".pdb", pdbReader)) {
                                PeWriter.WritePeToStream(rewrittenModule, host, peStream, pdbReader, pdbReader, pdbWriter);
                            }
                        }
                    }
                }
            }
        }
 IAssembly VisitAndMutate(MetadataRewriter mutator, IAssembly assembly) {
   var mutableAssembly = new MetadataDeepCopier(host).Copy(assembly);
   assembly = mutator.Rewrite(mutableAssembly);
   Assert.NotNull(assembly);
   return assembly;
 }
Esempio n. 37
0
        private IAssembly LoadAssemblyFrom(string filePath)
        {
            IAssembly module = _host.LoadUnitFrom(filePath) as IAssembly;
            _host.RegisterAsLatest(module);
            if (module == null || module == Dummy.Module || module == Dummy.Assembly)
            {
                throw new AssemblyReadException(filePath + " is not a PE file containing a CLR module or assembly.");
            }

            PdbReader pdbReader;
            TryGetPdbReader(module, out pdbReader);

            module = new MetadataDeepCopier(_host).Copy(module);
          //  var decompiled = Decompiler.GetCodeModelFromMetadataModel(_host, module, pdbReader,
          //      DecompilerOptions.None);
            return module;
            //  return new CodeDeepCopier(_host, pdbReader).Copy(decompiled);
        }
Esempio n. 38
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);
                        }
                    }
                }
            }
        }
Esempio n. 39
0
        static int Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("Usage: ILWeave [Assembly]");

                return(1);
            }

            string tmpDir, newName, newPdb;

            using (var host = new PeReader.DefaultHost())
            {
                var module = host.LoadUnitFrom(args[0]) as IModule;

                if (module == null || module is Dummy)
                {
                    Console.WriteLine("{0} is not a PE file containing a CLR assembly, or an error occurred when loading it.", args[0]);

                    return(1);
                }

                module = new MetadataDeepCopier(host).Copy(module);
                PdbReader pdbReader = null;
                var       pdbFile   = Path.ChangeExtension(module.Location, "pdb");

                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile))
                    {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                else
                {
                    Console.WriteLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");
                }
                using (pdbReader)
                {
                    var localScopeProvider = pdbReader == null ? null : new ILGenerator.LocalScopeProvider(pdbReader);

                    module = PropertyChangedWeaver.RewriteModule(
                        host,
                        localScopeProvider,
                        pdbReader,
                        module);

                    tmpDir  = Directory.CreateDirectory(Path.GetRandomFileName()).FullName;
                    newName = Path.Combine(tmpDir, Path.GetFileName(args[0]));

                    using (var peStream = File.Create(newName))
                    {
                        newPdb = Path.ChangeExtension(newName, ".pdb");

                        using (var pdbWriter = new PdbWriter(newPdb, pdbReader))
                        {
                            PeWriter.WritePeToStream(module, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                        }
                    }
                }
            }

            var dst = Path.GetDirectoryName(args[0]);

            foreach (var s in Directory.GetFiles(tmpDir))
            {
                File.Copy(s, Path.Combine(dst, Path.GetFileName(s)), true);
            }

            Directory.Delete(tmpDir, true);

            return(0);
        }
    static void Main(string[] argv) {
      if (argv == null || argv.Length < 1) {
        Console.WriteLine("Usage: Main <assemblys> [<outputPath>]");
      }

      using (var host = new PeReader.DefaultHost()) {
        var module = host.LoadUnitFrom(argv[0]) as IModule;
        if (module == null || module == Dummy.Module || module == Dummy.Assembly) {
          throw new Exception(argv[0] + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
        } 

        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
          Console.WriteLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");

        using (pdbReader) {

          var copy = new MetadataDeepCopier(host).Copy(module);
          var shadowFieldsAddedAssembly = new ShadowFieldRewriter(host).Rewrite(copy);
          var shadowFieldsAndMethodsAddedAssembly = new ShadowMethodRewriter(host).Rewrite(shadowFieldsAddedAssembly);
          var rewrittenAssembly = new FinalizeMethodRewriter(host).Rewrite(shadowFieldsAndMethodsAddedAssembly);

          var main = rewrittenAssembly.EntryPoint.ResolvedMethod;
          if (main != Dummy.Method) {
            var body = main.Body as MethodBody;
            if (body != null)
              new AddGCWaitForFinalization(host, body).Rewrite();
          }

          var validator = new MetadataValidator(host);
          validator.Validate(rewrittenAssembly as IAssembly);

          string outputPath = rewrittenAssembly.Location + ".meta";
          var outputFileName = Path.GetFileNameWithoutExtension(outputPath);

          // Need to not pass in a local scope provider until such time as we have one that will use the mutator
          // to remap things (like the type of a scope constant) from the original assembly to the mutated one.
          using (var peStream = File.Create(outputPath)) {
            using (var pdbWriter = new PdbWriter(outputFileName + ".pdb", pdbReader)) {
              PeWriter.WritePeToStream(rewrittenAssembly, host, peStream, pdbReader, null, pdbWriter);
            }
          }
        }
      }
    }
Esempio n. 41
0
        public static void RunBclRewriter(string[] args)
        {
            #region Parse the command-line arguments.
            if (!Parser.ParseArgumentsWithUsage(args, typeof(Program)))
                throw new UsageException();
            #endregion

            #region Figure out paths
            s_assemblyName = Path.GetFullPath(s_assemblyName); // this has to be specified

            string outputBaseName = null;
            if (!String.IsNullOrEmpty(s_output))
            {
                s_output = Path.GetFullPath(s_output);
                outputBaseName = Path.GetFileNameWithoutExtension(s_output);
            }
            else
            {
                s_output = Path.Combine(Directory.GetCurrentDirectory(), Path.GetFileNameWithoutExtension(s_assemblyName) + ".small" + Path.GetExtension(s_assemblyName));
                outputBaseName = s_assemblyName;
            }

            string pdbSourceFile = Path.ChangeExtension(s_assemblyName, "pdb");
            string outputPdb = Path.ChangeExtension(s_output, "pdb");
            string outputFolder = Path.GetDirectoryName(s_output);

            // if the user wants to do an in-place rewrite, we copy the file to a temp file
            if (s_output == s_assemblyName)
            {
                String tempPath = s_assemblyName + TempExtension;
                String tempPdbPath = pdbSourceFile + TempExtension;

                File.Copy(s_assemblyName, tempPath, true);
                s_assemblyName = tempPath;

                if (File.Exists(pdbSourceFile))
                {
                    File.Copy(pdbSourceFile, tempPdbPath, true);
                    pdbSourceFile = tempPdbPath;
                }
            }

            if (!Directory.Exists(outputFolder))
                Directory.CreateDirectory(outputFolder);

            #endregion

            #region Load input files
            HostEnvironment host = new HostEnvironment(new NameTable(), s_assemblyDependencyPaths, s_referencedAssemblies);

            IAssembly/*?*/ assembly = host.LoadUnitFrom(s_assemblyName) as IAssembly;
            // TODO: Handle multimodule assemblies
            if (assembly == null || assembly == Dummy.Assembly)
            {
                throw new UsageException(args[0] + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
            }

            if (!File.Exists(s_includeListFile))
            {
                throw new UsageException(String.Format("ERROR: Can't find code model file '{0}'", s_includeListFile));
            }

            ThinModel model = new ThinModel(new ThinnerOptions(host, new AssemblyIdentity[] { assembly.AssemblyIdentity }));
            model.LoadModel(s_includeListFile, new ModelReaderOptions(s_platform, s_architecture, s_flavor, s_treatFxInternalAsPublic, s_defines));
            #endregion

            #region Calculate api closure.
            ConsoleTimer.StartTimer("Calculating api closure");
            model.LoadMetadataFrom(assembly);

            ThinModel apiClosure = model.CalculateApiClosure();
            if (s_keepTempFiles)
                apiClosure.SaveModel(Path.ChangeExtension(s_output, ".apiClosure.xml"));
            ConsoleTimer.EndTimer("Calculating api closure");
            #endregion

            #region Calculate impl closure.
            ConsoleTimer.StartTimer("Calculating implementation closure");
            apiClosure.LoadMetadataFrom(assembly);

            ThinModel implClosure = apiClosure.CalculateImplementationClosure(true, FieldOptions.KeepAll);

            if (s_keepTempFiles)
                implClosure.SaveModel(Path.ChangeExtension(s_output, ".implClosure.xml"));
            ConsoleTimer.EndTimer("Calculating implementation closure");
            #endregion

            #region Trim.
            ConsoleTimer.StartTimer("Trimming assembly");
            IncludeSet includeSet = new IncludeSet();
            includeSet.LoadFrom(implClosure);

            var copier = new MetadataDeepCopier(host);
            Assembly copiedAssembly = copier.Copy(assembly);

            Trimmer trimmer = new Trimmer(includeSet, true, false, true, host, s_removeSerializable);
            trimmer.RewriteChildren(copiedAssembly);
            Assembly mutableAssembly = copiedAssembly;
            assembly = mutableAssembly;

            ConsoleTimer.EndTimer("Trimming assembly");
            #endregion

            #region Update assembly name.
            ConsoleTimer.StartTimer("Updating assembly name");

            // If the output assembly name is different, update the internal assembly name to match.
            AssemblyIdentity originalAssemblyIdentity = mutableAssembly.AssemblyIdentity;
            if (!outputBaseName.Equals(originalAssemblyIdentity.Name.ToString(), StringComparison.OrdinalIgnoreCase))
            {
                mutableAssembly.Name = host.NameTable.GetNameFor(outputBaseName);
                mutableAssembly.ModuleName = mutableAssembly.Name;
            }

            // If we changed the assembly identity, update references to it.
            if (!mutableAssembly.AssemblyIdentity.Equals(originalAssemblyIdentity))
            {
                trimmer.UpdateAssemblyReferences(originalAssemblyIdentity, mutableAssembly.AssemblyIdentity);
            }

            ConsoleTimer.EndTimer("Updating assembly name");
            #endregion

            #region Write out the assembly
            ConsoleTimer.StartTimer("Writing assembly");
            PdbReader pdbReader = null;
            PdbWriter pdbWriter = null;
            if (File.Exists(pdbSourceFile))
            {
                Stream pdbStream = File.OpenRead(pdbSourceFile);
                pdbReader = new PdbReader(pdbStream, host);
                pdbWriter = new PdbWriter(outputPdb, pdbReader);
                Console.WriteLine("Writing pdb: {0}", outputPdb);
            }

            Console.WriteLine("Writing assembly: {0}", s_output);
            FileStream file = File.Create(s_output);

            try
            {
                PeWriter.WritePeToStream(assembly, host, file, pdbReader, pdbReader, pdbWriter);
            }
            finally
            {
                if (file != null)
                {
                    file.Dispose();
                }

                if (pdbWriter != null)
                {
                    pdbWriter.Dispose();
                }
            }

            ConsoleTimer.EndTimer("Writing assembly");
            #endregion
        }
Esempio n. 42
0
 /// <summary>
 /// A rewriter for CodeModel method bodies, which changes any anynomous delegate expressions found in the body into delegates over
 /// methods of either the containing type of the method, or of a nested type of that type.
 /// </summary>
 /// <param name="host">An object representing the application that is hosting the converter. It is used to obtain access to some global
 /// objects and services such as the shared name table and the table for interning references.</param>
 /// <param name="sourceLocationProvider">An object that can map the ILocation objects found in a block of statements to IPrimarySourceLocation objects. May be null.</param>
 public AnonymousDelegateRemover(IMetadataHost host, ISourceLocationProvider/*?*/ sourceLocationProvider)
     : base(host)
 {
     this.copier = new MetadataDeepCopier(host);
       this.sourceLocationProvider = sourceLocationProvider;
       var compilerGeneratedCtor = this.GetReferenceToDefaultConstructor(host.PlatformType.SystemRuntimeCompilerServicesCompilerGeneratedAttribute);
       this.compilerGenerated = new CustomAttribute() { Constructor = compilerGeneratedCtor };
       this.objectCtor = this.GetReferenceToDefaultConstructor(this.host.PlatformType.SystemObject);
 }
Esempio n. 43
0
        public static void Main(string[] args)
        {
            string seeds = null;
            string contracts = null;
            string facadePath = null;
            Version assemblyFileVersion = null;
            bool clearBuildAndRevision = false;
            bool ignoreMissingTypes = false;
            bool buildDesignTimeFacades = false;
            string inclusionContracts = null;
            ErrorTreatment seedLoadErrorTreatment = ErrorTreatment.Default;
            ErrorTreatment contractLoadErrorTreatment = ErrorTreatment.Default;
            string[] seedTypePreferencesUnsplit = null;
            bool forceZeroVersionSeeds = false;
            bool producePdb = true;
            string partialFacadeAssemblyPath = null;

            bool parsingSucceeded = CommandLineParser.ParseForConsoleApplication((parser) =>
            {
                parser.DefineQualifier("facadePath", ref facadePath, "Path to output the facades.");
                parser.DefineQualifier("seeds", ref seeds, "Path to the seed assemblies. Can contain multiple assemblies or directories delimited by ',' or ';'.");
                parser.DefineQualifier("contracts", ref contracts, "Path to the contract assemblies. Can contain multiple assemblies or directories delimited by ',' or ';'.");
                parser.DefineOptionalQualifier("assemblyFileVersion", ref assemblyFileVersion, "Override the AssemblyFileVersion attribute from the contract with the given version for the generated facade.");
                parser.DefineOptionalQualifier("clearBuildAndRevision", ref clearBuildAndRevision, "Generate facade assembly version x.y.0.0 for contract version x.y.z.w");
                parser.DefineOptionalQualifier("ignoreMissingTypes", ref ignoreMissingTypes, "Ignore types that cannot be found in the seed assemblies. This is not recommended but is sometimes helpful while hacking around or trying to produce partial facades.");
                parser.DefineOptionalQualifier("designTime", ref buildDesignTimeFacades, "Enable design-time facade generation (marks facades with reference assembly flag and attribute).");
                parser.DefineOptionalQualifier("include", ref inclusionContracts, "Add types from these contracts to the facades. Can contain multiple assemblies or directories delimited by ',' or ';'.");
                parser.DefineOptionalQualifier("seedError", ref seedLoadErrorTreatment, "Error handling for seed assembly load failure.");
                parser.DefineOptionalQualifier("contractError", ref seedLoadErrorTreatment, "Error handling for contract assembly load failure.");
                parser.DefineOptionalQualifier("preferSeedType", ref seedTypePreferencesUnsplit, "Set which seed assembly to choose for a given type when it is defined in more than one assembly. Format: FullTypeName=PreferredSeedAssemblyName");
                parser.DefineOptionalQualifier("forceZeroVersionSeeds", ref forceZeroVersionSeeds, "Forces all seed assembly versions to 0.0.0.0, regardless of their true version.");
                parser.DefineOptionalQualifier("partialFacadeAssemblyPath", ref partialFacadeAssemblyPath, "Specifies the path to a single partial facade assembly, into which appropriate type forwards will be added to satisfy the given contract. If this option is specified, only a single partial assembly and a single contract may be given.");
                parser.DefineOptionalQualifier("producePdb", ref producePdb, "Specifices if a PDB file should be produced for the resulting partial facade.");
            }, args);

            if (!parsingSucceeded)
            {
                return;
            }

            CommandLineTraceHandler.Enable();

            if (!Directory.Exists(facadePath))
                Directory.CreateDirectory(facadePath);

            var nameTable = new NameTable();
            var internFactory = new InternFactory();

            try
            {
                Dictionary<string, string> seedTypePreferences = ParseSeedTypePreferences(seedTypePreferencesUnsplit);

                using (var contractHost = new HostEnvironment(nameTable, internFactory))
                using (var seedHost = new HostEnvironment(nameTable, internFactory))
                {
                    contractHost.LoadErrorTreatment = contractLoadErrorTreatment;
                    seedHost.LoadErrorTreatment = seedLoadErrorTreatment;

                    var contractAssemblies = LoadAssemblies(contractHost, contracts);
                    IReadOnlyDictionary<string, IEnumerable<string>> docIdTable = GenerateDocIdTable(contractAssemblies, inclusionContracts);

                    IAssembly[] seedAssemblies = LoadAssemblies(seedHost, seeds).ToArray();

                    IAssemblyReference seedCoreAssemblyRef = ((Microsoft.Cci.Immutable.PlatformType)seedHost.PlatformType).CoreAssemblyRef;

                    if (forceZeroVersionSeeds)
                    {
                        // Create a deep copier, copy the seed assemblies, and zero out their versions.
                        var copier = new MetadataDeepCopier(seedHost);

                        for (int i = 0; i < seedAssemblies.Length; i++)
                        {
                            var mutableSeed = copier.Copy(seedAssemblies[i]);
                            mutableSeed.Version = new Version(0, 0, 0, 0);
                            // Copy the modified seed assembly back.
                            seedAssemblies[i] = mutableSeed;

                            if (mutableSeed.Name.UniqueKey == seedCoreAssemblyRef.Name.UniqueKey)
                            {
                                seedCoreAssemblyRef = mutableSeed;
                            }
                        }
                    }

                    var typeTable = GenerateTypeTable(seedAssemblies);
                    var facadeGenerator = new FacadeGenerator(seedHost, contractHost, docIdTable, typeTable, seedTypePreferences, clearBuildAndRevision, buildDesignTimeFacades, assemblyFileVersion);

                    if (partialFacadeAssemblyPath != null)
                    {
                        if (contractAssemblies.Count() != 1)
                        {
                            throw new FacadeGenerationException(
                                "When partialFacadeAssemblyPath is specified, only exactly one corresponding contract assembly can be specified.");
                        }

                        IAssembly contractAssembly = contractAssemblies.First();
                        IAssembly partialFacadeAssembly = seedHost.LoadAssembly(partialFacadeAssemblyPath);
                        if (contractAssembly.Name != partialFacadeAssembly.Name
                            || contractAssembly.Version != partialFacadeAssembly.Version
                            || contractAssembly.GetPublicKeyToken() != partialFacadeAssembly.GetPublicKeyToken())
                        {
                            throw new FacadeGenerationException(
                                string.Format("The partial facade assembly's name, version, and public key token must exactly match the contract to be filled. Contract: {0}, Facade: {1}",
                                    contractAssembly.AssemblyIdentity,
                                    partialFacadeAssembly.AssemblyIdentity));
                        }

                        Assembly filledPartialFacade = facadeGenerator.GenerateFacade(contractAssembly, seedCoreAssemblyRef, ignoreMissingTypes, overrideContractAssembly: partialFacadeAssembly);

                        string pdbLocation = null;

                        if (producePdb)
                        {
                            string pdbFolder = Path.GetDirectoryName(partialFacadeAssemblyPath);
                            pdbLocation = Path.Combine(pdbFolder, contractAssembly.Name + ".pdb");
                            if (producePdb && !File.Exists(pdbLocation))
                            {
                                pdbLocation = null;
                                Trace.TraceWarning("No PDB file present for un-transformed partial facade. No PDB will be generated.");
                            }
                        }

                        OutputFacadeToFile(facadePath, seedHost, filledPartialFacade, contractAssembly, pdbLocation);
                    }
                    else
                    {
                        foreach (var contract in contractAssemblies)
                        {
                            Assembly facade = facadeGenerator.GenerateFacade(contract, seedCoreAssemblyRef, ignoreMissingTypes);
                            if (facade == null)
                            {
#if !COREFX
                                Debug.Assert(Environment.ExitCode != 0);
#endif
                                continue;
                            }

                            OutputFacadeToFile(facadePath, seedHost, facade, contract);
                        }
                    }
                }
            }
            catch (FacadeGenerationException ex)
            {
                Trace.TraceError(ex.Message);
#if !COREFX
                Debug.Assert(Environment.ExitCode != 0);
#endif
            }
        }
Esempio n. 44
0
        /// <summary>
        /// Amends the specified target assembly, optionally using assembly amendments defined in the
        /// specified amendment assemblies.
        /// </summary>
        /// <param name="targetAssembly"></param>
        /// <param name="amendmentAssemblies"></param>
        internal static void Amend(string targetAssembly, string[] amendmentAssemblies, string[] referenceAssemblies)
        {
            // Verify the target assembly exists
            targetAssembly = Path.GetFullPath(targetAssembly);
            if (!File.Exists(targetAssembly))
            {
                throw new ArgumentException("The specified target assembly, " + targetAssembly + ", does not exist.");
            }

            // Verify the amendment assemblies exist
            if (amendmentAssemblies == null)
            {
                amendmentAssemblies = new string[0];
            }
            for (int i = 0; i < amendmentAssemblies.Length; i++)
            {
                var path = amendmentAssemblies[i] = Path.GetFullPath(amendmentAssemblies[i]);
                if (!File.Exists(path))
                {
                    throw new ArgumentException("The specified amendment assembly, " + path + ", does not exist.");
                }
            }

            // Verify that the target has not already been amended
            var afterthoughtTracker = targetAssembly + ".afterthought";

            if (File.Exists(afterthoughtTracker) && File.GetLastWriteTime(targetAssembly) == File.GetLastWriteTime(afterthoughtTracker))
            {
                return;
            }

            // Determine the set of target directories and backup locations
            var targetWriteTime      = File.GetLastWriteTime(targetAssembly);
            var backupTargetAssembly = targetAssembly + ".backup";
            var targetDirectory      = Path.GetDirectoryName(targetAssembly);

            File.Delete(backupTargetAssembly);
            File.Move(targetAssembly, backupTargetAssembly);

            // Build up a set of paths with resolving assemblies
            var referencePaths = new Dictionary <string, string>();

            foreach (string path in amendmentAssemblies
                     .Union(referenceAssemblies)
                     .Union(Directory.GetFiles(targetDirectory).Where(p => p.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) && p != targetAssembly)))
            {
                referencePaths[Path.GetFileName(path)] = path;
            }

            // Register an assembly resolver to look in assembly directories when resolving assemblies
            AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
            {
                var    assemblyName = new System.Reflection.AssemblyName(e.Name).Name + ".dll";
                string referencePath;
                if (referencePaths.TryGetValue(assemblyName, out referencePath))
                {
                    return(System.Reflection.Assembly.LoadFrom(referencePath));
                }

                return(null);
            };

            // Get the set of amendments to apply from all of the specified assemblies
            var assemblies = new System.Reflection.Assembly[] { System.Reflection.Assembly.LoadFrom(backupTargetAssembly) }.Union(amendmentAssemblies.Select(a => System.Reflection.Assembly.LoadFrom(a)));
            var amendments = AmendmentAttribute.GetAmendments(assemblies.First(), assemblies.Skip(1).ToArray()).ToList();

            // Exit immediately if there are no amendments in the target assemblies
            //if (amendments.Count == 0)
            //    return;

            // Amend the target assembly

            Console.Write("Amending " + Path.GetFileName(targetAssembly));
            var start = DateTime.Now;

            using (var host = new PeReader.DefaultHost())
            {
                // Load the target assembly
                IModule module = host.LoadUnitFrom(backupTargetAssembly) as IModule;
                if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                {
                    throw new ArgumentException(backupTargetAssembly + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
                }

                // Copy the assembly to enable it to be mutated
                module = new MetadataDeepCopier(host).Copy(module);

                // Load the debug file if it exists
                PdbReader pdbReader     = null;
                var       pdbFile       = Path.Combine(targetDirectory, Path.GetFileNameWithoutExtension(targetAssembly) + ".pdb");
                var       backupPdbFile = pdbFile + ".backup";
                if (File.Exists(pdbFile))
                {
                    File.Delete(backupPdbFile);
                    File.Move(pdbFile, backupPdbFile);
                    using (var pdbStream = File.OpenRead(backupPdbFile))
                    {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }

                // Amend and persist the target assembly
                using (pdbReader)
                {
                    // Create and execute a new assembly amender
                    AssemblyAmender amender = new AssemblyAmender(host, pdbReader, amendments, assemblies);
                    amender.TargetRuntimeVersion = module.TargetRuntimeVersion;
                    module = amender.Visit(module);

                    // Save the amended assembly back to the original directory
                    var localScopeProvider = pdbReader == null ? null : new ILGenerator.LocalScopeProvider(pdbReader);
                    using (var pdbWriter = pdbReader != null ? new PdbWriter(pdbFile, pdbReader) : null)
                    {
                        using (var dllStream = File.Create(targetAssembly))
                        {
                            PeWriter.WritePeToStream(module, host, dllStream, pdbReader, localScopeProvider, pdbWriter);
                        }
                    }
                }

                File.SetLastWriteTime(targetAssembly, targetWriteTime);
                if (pdbReader != null)
                {
                    File.SetLastWriteTime(pdbFile, targetWriteTime);
                }
            }

            Console.WriteLine(" (" + DateTime.Now.Subtract(start).TotalSeconds.ToString("0.000") + " seconds)");

            // Set the last write time of the afterthought tracker to match the amended assembly to prevent accidental reamending
            File.WriteAllText(afterthoughtTracker, "");
            File.SetLastWriteTime(afterthoughtTracker, File.GetLastWriteTime(targetAssembly));
        }
Esempio n. 45
0
        static void Main(string[] args) {

            //String inputFile = @"c:\Users\typ\Documents\Visual Studio 2013\Projects\vererbung\vererbung\bin\Debug\vererbung.exe";
            String inputFile = @"e:\dile_v0_2_12_x86\Dile.exe";

            

            globalLog = new Log(@"e:\merge_logfile.txt");

            System.Console.WriteLine(inputFile);

            /*
            if (args == null || args.Length == 0)
            {
                Console.WriteLine("Usage: ILMutator <assembly> [<outputPath>]");
                return;
            }
            */




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







                if (module == null || module == Dummy.Module || module == Dummy.Assembly) {
                    //Console.WriteLine(args[0] + " is not a PE file containing a CLR module or 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) {
                    globalLog.writeLine("File does not have CIL assembly");
                    return;
                }


                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 {
                    globalLog.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);
                    }











                    // AB HIER DER INTERESSANTE PART ZUM MERGEN, DAVOR NUR INIT CRAP

                    // search for class in namespace
                    NamespaceTypeDefinition foundClass = null;
                    foreach (var asdf in module.GetAllTypes()) {
                        //if (asdf.ToString() == "vererbung.Erber") {
                        if (asdf.ToString() == "Dile.Disassemble.Assembly") {                            
                            foundClass = (asdf as NamespaceTypeDefinition);
                            break;
                        }
                    }
                    if (foundClass == null) {
                        globalLog.writeLine("Class not found!");
                        return;
                    }

                    // merge class
                    globalLog.writeLine("Merge class \"" + foundClass.ToString() + "\" with all ancestors");
                    mergeClassWithAllAncestors(foundClass, host);






                    string newName;
                    if (args.Length == 2) {
                        newName = args[1];
                        //newName = @"e:\dile_v0_2_12_x86\dile_classes.exe";
                        newName = @"e:\test.exe";
                    }
                    else {
                        var loc = module.Location;
                        var path = Path.GetDirectoryName(loc) ?? "";
                        var fileName = Path.GetFileNameWithoutExtension(loc);
                        var ext = Path.GetExtension(loc);
                        newName = Path.Combine(path, fileName + "1" + ext);
                        //newName = @"e:\dile_v0_2_12_x86\dile_classes.exe";
                        newName = @"e:\test.exe";
                    }

                    using (var peStream = File.Create(newName)) {
                        using (var pdbWriter = new PdbWriter(Path.ChangeExtension(newName, ".pdb"), pdbReader)) {
                            PeWriter.WritePeToStream(module, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                        }
                    }
                }
            }
        }
Esempio n. 46
0
        internal int Run()
        {
            SecurityKeepOptions securityKeepOptions = options.onlySecurityTransparent ? SecurityKeepOptions.OnlyNonCritical : SecurityKeepOptions.All;

            if (options.doBreak)
            {
                System.Diagnostics.Debugger.Launch();
            }

            string assemblyName = null;

            if (options.GeneralArguments.Count == 1)
            {
                assemblyName = options.GeneralArguments[0];
            }
            if (assemblyName == null)
            {
                errorLogger("Must specify an input file.");
                return(1);
            }

            using (var host = new AsmMetaHostEnvironment(options.libPaths.ToArray(), options.searchGAC))
            {
                foreach (var p in options.resolvedPaths)
                {
                    host.AddResolvedPath(p);
                }

                IAssembly /*?*/ assembly = host.LoadUnitFrom(assemblyName) as IAssembly;
                if (assembly == null || assembly is Dummy)
                {
                    errorLogger(assemblyName + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
                    return(1);
                }

                var rewrittenAttribute = CreateTypeReference(host, assembly, "System.Diagnostics.Contracts.RuntimeContractsAttribute");
                if (AttributeHelper.Contains(assembly.Attributes, rewrittenAttribute))
                {
                    errorLogger(assemblyName + " is already rewritten, cannot generate a reference assembly from it.");
                    return(1);
                }

                if (options.backwardCompatibility)
                { // redundant because RemoveMethodBodies.ctor also does this when the flag is set
                    options.whatToEmit     = KeepOptions.ExtVis;
                    options.emitAttributes = false;
                }

                PdbReader /*?*/ pdbReader = null;
                if (options.includeSourceTextInContract)
                { // No point getting the PDB file unless we want to use it for source text
                    string pdbFile = Path.ChangeExtension(assembly.Location, "pdb");
                    if (File.Exists(pdbFile))
                    {
                        using (var pdbStream = File.OpenRead(pdbFile))
                        {
                            pdbReader = new PdbReader(pdbStream, host);
                        }
                    }
                    else
                    {
                        errorLogger("Could not load the PDB file for the assembly '" + assembly.Name.Value + "' . Source text will not be preserved in the reference assembly. Proceeding anyway.");
                    }
                }
                using (pdbReader)
                {
                    // We might be working on the assembly that defines the contract class and/or the type System.Void.
                    // (Or any other platform type!)
                    // But the host.PlatformType object has not been duplicated, so its properties will continue to be references to the immutable ones.
                    // This is OK, except if the assembly is being renamed.
                    this.compilerGeneratedAttributeType = host.PlatformType.SystemRuntimeCompilerServicesCompilerGeneratedAttribute;
                    this.contractClassType   = host.PlatformType.SystemDiagnosticsContractsContract;
                    this.systemAttributeType = host.PlatformType.SystemAttribute;
                    this.systemBooleanType   = host.PlatformType.SystemBoolean;
                    this.systemStringType    = host.PlatformType.SystemString;
                    this.systemObjectType    = host.PlatformType.SystemObject;
                    this.systemVoidType      = host.PlatformType.SystemVoid;
                    //new FindPlatformTypes(this).Traverse(assembly); //update the above fields if any of those types are defined in mutable

                    Assembly mutable = new MetadataDeepCopier(host).Copy(assembly);

                    #region Rename the assembly in a separate pass because things done in later passes depend on interned keys that are computed based (in part) on the assembly identity

                    if (options.rename)
                    {
                        if (options.output != null)
                        {
                            mutable.Name = host.NameTable.GetNameFor(Path.GetFileNameWithoutExtension(options.output));
                        }
                        else
                        {
                            mutable.Name = host.NameTable.GetNameFor(assembly.Name.Value + ".Contracts");
                        }
                        mutable.ModuleName = mutable.Name;
                        mutable.Kind       = ModuleKind.DynamicallyLinkedLibrary;
                        mutable            = (Assembly)RenameAssembly.ReparentAssemblyIdentity(host, assembly.AssemblyIdentity, mutable.AssemblyIdentity, mutable);
                    }

                    #endregion Rename the assembly in a separate pass because things done in later passes depend on interned keys that are computed based (in part) on the assembly identity
                    if (!options.renameOnly)
                    {
                        if (options.contracts)
                        {
                            if (options.rename)
                            {
                                // We might be working on the assembly that defines the contract class and/or the type System.Void.
                                // (Or any other platform type!)
                                // But the host.PlatformType object has not been duplicated, so its properties will continue to be references to the immutable ones.
                                // This is OK, except if the assembly is being renamed.

                                var systemNamespace = GetFirstMatchingNamespace(host, mutable.UnitNamespaceRoot, "System");
                                if (systemNamespace != null)
                                {
                                    var typeDefinition = GetFirstMatchingTypeDefinition(host, systemNamespace, "Attribute");
                                    if (typeDefinition != null)
                                    {
                                        this.systemAttributeType = typeDefinition;
                                    }
                                    typeDefinition = GetFirstMatchingTypeDefinition(host, systemNamespace, "Boolean");
                                    if (typeDefinition != null)
                                    {
                                        this.systemBooleanType = typeDefinition;
                                    }
                                    typeDefinition = GetFirstMatchingTypeDefinition(host, systemNamespace, "Object");
                                    if (typeDefinition != null)
                                    {
                                        this.systemObjectType = typeDefinition;
                                    }
                                    typeDefinition = GetFirstMatchingTypeDefinition(host, systemNamespace, "String");
                                    if (typeDefinition != null)
                                    {
                                        this.systemStringType = typeDefinition;
                                    }
                                    typeDefinition = GetFirstMatchingTypeDefinition(host, systemNamespace, "Void");
                                    if (typeDefinition != null)
                                    {
                                        this.systemVoidType = typeDefinition;
                                    }

                                    var systemRuntimeNamespace = GetFirstMatchingNamespace(host, systemNamespace, "Runtime");
                                    if (systemRuntimeNamespace != null)
                                    {
                                        var systemRuntimeCompilerServicesNamespace = GetFirstMatchingNamespace(host, systemRuntimeNamespace, "CompilerServices");
                                        if (systemRuntimeCompilerServicesNamespace != null)
                                        {
                                            typeDefinition = GetFirstMatchingTypeDefinition(host, systemRuntimeCompilerServicesNamespace, "CompilerGeneratedAttribute");
                                            if (typeDefinition != null)
                                            {
                                                this.compilerGeneratedAttributeType = typeDefinition;
                                            }
                                        }
                                    }

                                    var systemDiagnosticsNamespace = GetFirstMatchingNamespace(host, systemNamespace, "Diagnostics");
                                    if (systemDiagnosticsNamespace != null)
                                    {
                                        var systemDiagnosticsContractsNamespace = GetFirstMatchingNamespace(host, systemDiagnosticsNamespace, "Contracts");
                                        if (systemDiagnosticsContractsNamespace != null)
                                        {
                                            typeDefinition = GetFirstMatchingTypeDefinition(host, systemDiagnosticsContractsNamespace, "Contract");
                                            if (typeDefinition != null)
                                            {
                                                this.contractClassType = typeDefinition;
                                            }
                                        }
                                    }
                                }
                            }

                            mutable = AsmMetaRewriter.RewriteModule(host,
                                                                    pdbReader,
                                                                    mutable,
                                                                    contractClassType,
                                                                    compilerGeneratedAttributeType,
                                                                    systemAttributeType,
                                                                    systemBooleanType,
                                                                    systemObjectType,
                                                                    systemStringType,
                                                                    systemVoidType
                                                                    ) as Assembly;
                        }
                        #region Delete things that are not to be kept
                        if (options.backwardCompatibility || options.whatToEmit != KeepOptions.All || !options.emitAttributes || (options.attrs != null && 0 < options.attrs.Count))
                        {
                            DeleteThings thinner = new DeleteThings(host, options.whatToEmit, securityKeepOptions, options.emitAttributes, options.attrs.ToArray(), options.backwardCompatibility);
                            if (securityKeepOptions == SecurityKeepOptions.OnlyNonCritical && host.platformType.SystemSecuritySecurityCriticalAttribute.ResolvedType is Dummy)
                            {
                                errorLogger("You asked to remove security critical methods, but the version of mscorlib doesn't support the SecurityCriticalAttribute.");
                                return(1);
                            }
                            thinner.RewriteChildren(mutable);
                            #region Fix up dangling references to things that were deleted
                            FixUpReferences patcher = new FixUpReferences(host, thinner.WhackedMethods, thinner.WhackedTypes);
                            patcher.RewriteChildren(mutable);
                            #endregion Fix up dangling references to things that were deleted
                        }
                        #endregion Delete things that are not to be kept
                        #region Output is always a dll, so mark the assembly as that
                        mutable.EntryPoint = Dummy.MethodReference;
                        mutable.Kind       = ModuleKind.DynamicallyLinkedLibrary;
                        #endregion Output is always a dll, so mark the assembly as that
                    }

                    assembly = mutable;

                    string outputPath;
                    if (options.output != null) // user specified, they'd better make sure it doesn't conflict with anything
                    {
                        outputPath = options.output;
                    }
                    else if (options.rename) // A.dll ==> A.Contracts.dll (Always! Even if the input is an exe!)
                    {
                        outputPath = assembly.Name.Value + ".dll";
                    }
                    else // A.dll ==> A.dll.meta
                    {
                        outputPath = assembly.Name.Value + Path.GetExtension(assemblyName) + ".meta";
                    }
                    // NB: Do *not* pass a pdbWriter to WritePeToStream. No need to create a PDB file and if
                    // it is provided, then it might find things (like constants in a scope) that don't get
                    // visited and so don't have any type references modified as they should be.
                    using (var outputFile = File.Create(outputPath))
                    {
                        if (pdbReader != null && options.writePDB)
                        {
                            using (var pdbWriter = new PdbWriter(Path.ChangeExtension(outputPath, "pdb"), pdbReader))
                            {
                                // Need to not pass in a local scope provider until such time as we have one that will use the mutator
                                // to remap things (like the type of a scope constant) from the original assembly to the mutated one.
                                PeWriter.WritePeToStream(assembly, host, outputFile, pdbReader, null /*pdbReader*/, pdbWriter);
                            }
                        }
                        else
                        {
                            PeWriter.WritePeToStream(assembly, host, outputFile);
                        }
                    }
                }
            }
            return(0); // success
        }
Esempio n. 47
0
        public static void Main(string[] args)
        {
            string         seeds                          = null;
            string         contracts                      = null;
            string         facadePath                     = null;
            Version        assemblyFileVersion            = null;
            bool           clearBuildAndRevision          = false;
            bool           ignoreMissingTypes             = false;
            bool           ignoreBuildAndRevisionMismatch = false;
            bool           buildDesignTimeFacades         = false;
            string         inclusionContracts             = null;
            ErrorTreatment seedLoadErrorTreatment         = ErrorTreatment.Default;
            ErrorTreatment contractLoadErrorTreatment     = ErrorTreatment.Default;

            string[] seedTypePreferencesUnsplit = null;
            bool     forceZeroVersionSeeds      = false;
            bool     producePdb = true;
            string   partialFacadeAssemblyPath = null;

            bool parsingSucceeded = CommandLineParser.ParseForConsoleApplication((parser) =>
            {
                parser.DefineQualifier("facadePath", ref facadePath, "Path to output the facades.");
                parser.DefineQualifier("seeds", ref seeds, "Path to the seed assemblies. Can contain multiple assemblies or directories delimited by ',' or ';'.");
                parser.DefineQualifier("contracts", ref contracts, "Path to the contract assemblies. Can contain multiple assemblies or directories delimited by ',' or ';'.");
                parser.DefineOptionalQualifier("assemblyFileVersion", ref assemblyFileVersion, "Override the AssemblyFileVersion attribute from the contract with the given version for the generated facade.");
                parser.DefineOptionalQualifier("clearBuildAndRevision", ref clearBuildAndRevision, "Generate facade assembly version x.y.0.0 for contract version x.y.z.w");
                parser.DefineOptionalQualifier("ignoreBuildAndRevisionMismatch", ref ignoreBuildAndRevisionMismatch, "Ignore a mismatch in revision and build for partial facade.");
                parser.DefineOptionalQualifier("ignoreMissingTypes", ref ignoreMissingTypes, "Ignore types that cannot be found in the seed assemblies. This is not recommended but is sometimes helpful while hacking around or trying to produce partial facades.");
                parser.DefineOptionalQualifier("designTime", ref buildDesignTimeFacades, "Enable design-time facade generation (marks facades with reference assembly flag and attribute).");
                parser.DefineOptionalQualifier("include", ref inclusionContracts, "Add types from these contracts to the facades. Can contain multiple assemblies or directories delimited by ',' or ';'.");
                parser.DefineOptionalQualifier("seedError", ref seedLoadErrorTreatment, "Error handling for seed assembly load failure.");
                parser.DefineOptionalQualifier("contractError", ref seedLoadErrorTreatment, "Error handling for contract assembly load failure.");
                parser.DefineOptionalQualifier("preferSeedType", ref seedTypePreferencesUnsplit, "Set which seed assembly to choose for a given type when it is defined in more than one assembly. Format: FullTypeName=PreferredSeedAssemblyName");
                parser.DefineOptionalQualifier("forceZeroVersionSeeds", ref forceZeroVersionSeeds, "Forces all seed assembly versions to 0.0.0.0, regardless of their true version.");
                parser.DefineOptionalQualifier("partialFacadeAssemblyPath", ref partialFacadeAssemblyPath, "Specifies the path to a single partial facade assembly, into which appropriate type forwards will be added to satisfy the given contract. If this option is specified, only a single partial assembly and a single contract may be given.");
                parser.DefineOptionalQualifier("producePdb", ref producePdb, "Specifices if a PDB file should be produced for the resulting partial facade.");
            }, args);

            if (!parsingSucceeded)
            {
                return;
            }

            CommandLineTraceHandler.Enable();

            if (!Directory.Exists(facadePath))
            {
                Directory.CreateDirectory(facadePath);
            }

            var nameTable     = new NameTable();
            var internFactory = new InternFactory();

            try
            {
                Dictionary <string, string> seedTypePreferences = ParseSeedTypePreferences(seedTypePreferencesUnsplit);

                using (var contractHost = new HostEnvironment(nameTable, internFactory))
                    using (var seedHost = new HostEnvironment(nameTable, internFactory))
                    {
                        contractHost.LoadErrorTreatment = contractLoadErrorTreatment;
                        seedHost.LoadErrorTreatment     = seedLoadErrorTreatment;

                        var contractAssemblies = LoadAssemblies(contractHost, contracts);
                        IReadOnlyDictionary <string, IEnumerable <string> > docIdTable = GenerateDocIdTable(contractAssemblies, inclusionContracts);

                        IAssembly[] seedAssemblies = LoadAssemblies(seedHost, seeds).ToArray();

                        IAssemblyReference seedCoreAssemblyRef = ((Microsoft.Cci.Immutable.PlatformType)seedHost.PlatformType).CoreAssemblyRef;

                        if (forceZeroVersionSeeds)
                        {
                            // Create a deep copier, copy the seed assemblies, and zero out their versions.
                            var copier = new MetadataDeepCopier(seedHost);

                            for (int i = 0; i < seedAssemblies.Length; i++)
                            {
                                var mutableSeed = copier.Copy(seedAssemblies[i]);
                                mutableSeed.Version = new Version(0, 0, 0, 0);
                                // Copy the modified seed assembly back.
                                seedAssemblies[i] = mutableSeed;

                                if (mutableSeed.Name.UniqueKey == seedCoreAssemblyRef.Name.UniqueKey)
                                {
                                    seedCoreAssemblyRef = mutableSeed;
                                }
                            }
                        }

                        var typeTable       = GenerateTypeTable(seedAssemblies);
                        var facadeGenerator = new FacadeGenerator(seedHost, contractHost, docIdTable, typeTable, seedTypePreferences, clearBuildAndRevision, buildDesignTimeFacades, assemblyFileVersion);

                        if (partialFacadeAssemblyPath != null)
                        {
                            if (contractAssemblies.Count() != 1)
                            {
                                throw new FacadeGenerationException(
                                          "When partialFacadeAssemblyPath is specified, only exactly one corresponding contract assembly can be specified.");
                            }

                            IAssembly contractAssembly      = contractAssemblies.First();
                            IAssembly partialFacadeAssembly = seedHost.LoadAssembly(partialFacadeAssemblyPath);
                            if (contractAssembly.Name != partialFacadeAssembly.Name ||
                                contractAssembly.Version.Major != partialFacadeAssembly.Version.Major ||
                                contractAssembly.Version.Minor != partialFacadeAssembly.Version.Minor ||
                                (!ignoreBuildAndRevisionMismatch && contractAssembly.Version.Build != partialFacadeAssembly.Version.Build) ||
                                (!ignoreBuildAndRevisionMismatch && contractAssembly.Version.Revision != partialFacadeAssembly.Version.Revision) ||
                                contractAssembly.GetPublicKeyToken() != partialFacadeAssembly.GetPublicKeyToken())
                            {
                                throw new FacadeGenerationException(
                                          string.Format("The partial facade assembly's name, version, and public key token must exactly match the contract to be filled. Contract: {0}, Facade: {1}",
                                                        contractAssembly.AssemblyIdentity,
                                                        partialFacadeAssembly.AssemblyIdentity));
                            }

                            Assembly filledPartialFacade = facadeGenerator.GenerateFacade(contractAssembly, seedCoreAssemblyRef, ignoreMissingTypes, overrideContractAssembly: partialFacadeAssembly);

                            string pdbLocation = null;

                            if (producePdb)
                            {
                                string pdbFolder = Path.GetDirectoryName(partialFacadeAssemblyPath);
                                pdbLocation = Path.Combine(pdbFolder, contractAssembly.Name + ".pdb");
                                if (producePdb && !File.Exists(pdbLocation))
                                {
                                    pdbLocation = null;
                                    Trace.TraceWarning("No PDB file present for un-transformed partial facade. No PDB will be generated.");
                                }
                            }

                            OutputFacadeToFile(facadePath, seedHost, filledPartialFacade, contractAssembly, pdbLocation);
                        }
                        else
                        {
                            foreach (var contract in contractAssemblies)
                            {
                                Assembly facade = facadeGenerator.GenerateFacade(contract, seedCoreAssemblyRef, ignoreMissingTypes);
                                if (facade == null)
                                {
#if !COREFX
                                    Debug.Assert(Environment.ExitCode != 0);
#endif
                                    continue;
                                }

                                OutputFacadeToFile(facadePath, seedHost, facade, contract);
                            }
                        }
                    }
            }
            catch (FacadeGenerationException ex)
            {
                Trace.TraceError(ex.Message);
#if !COREFX
                Debug.Assert(Environment.ExitCode != 0);
#endif
            }
        }
Esempio n. 48
0
        static int RealMain(string[] args)
        {
            int errorReturnValue = -1;

            #region Check options

            ILMerge.options = new ILMergeOptions();
            options.Parse(args);

            if (options.HelpRequested)
            {
                options.PrintOptions("");
                return(errorReturnValue);
            }
            if (options.HasErrors)
            {
                options.PrintErrorsAndExit(Console.Out);
            }

            if (options.breakIntoDebugger)
            {
                System.Diagnostics.Debugger.Break();
            }
            #endregion

            Version version = null;
            if (options.version != null)
            {
                TryGetVersionNumber(options.version, out version);
            }

            using (var host = new ILMergeHost(options.libpaths)) {
                if (options.libpaths != null)
                {
                    foreach (var libpath in options.libpaths)
                    {
                        host.AddLibPath(libpath);
                    }
                }

                Assembly /*?*/ primaryAssembly = null;
                var            modules         = new List <Module>();
                var            unit2SourceLocationProviderMap = new Dictionary <IUnit, ISourceLocationProvider>();
                var            unit2LocalScopeProviderMap     = new Dictionary <IUnit, ILocalScopeProvider>();
                try {
                    for (int i = 0; i < options.GeneralArguments.Count; i++)
                    {
                        var unitName = options.GeneralArguments[i];
                        var u        = host.LoadUnitFrom(unitName) as IModule;
                        if (i == 0)
                        {
                            IAssembly /*?*/ assembly = u as IAssembly;
                            if (assembly == null || assembly is Dummy)
                            {
                                Console.WriteLine(unitName + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
                                return(errorReturnValue);
                            }
                            // Use (the copy of) the first input assembly as the merged assembly!
                            primaryAssembly = new MetadataDeepCopier(host).Copy(assembly);
                        }
                        else
                        {
                            var copier        = new MetadataDeepCopier(host, primaryAssembly);
                            var mutableModule = copier.Copy(u);
                            modules.Add(mutableModule);
                        }
                        PdbReader /*?*/ pdbReader = null;
                        string          pdbFile   = Path.ChangeExtension(u.Location, "pdb");
                        if (File.Exists(pdbFile))
                        {
                            using (var pdbStream = File.OpenRead(pdbFile)) {
                                pdbReader = new PdbReader(pdbStream, host);
                            }
                            unit2SourceLocationProviderMap.Add(u, pdbReader);
                            unit2LocalScopeProviderMap.Add(u, pdbReader);
                        }
                        else
                        {
                            Console.WriteLine("Could not load the PDB file for the unit '" + u.Name.Value + "' . Proceeding anyway.");
                            unit2SourceLocationProviderMap.Add(u, null);
                        }
                    }

                    //PdbWriter/*?*/ pdbWriter = null;

                    RewriteUnitReferences renamer = new RewriteUnitReferences(host, modules, options);
                    renamer.targetAssembly           = primaryAssembly;
                    renamer.originalAssemblyIdentity = primaryAssembly.AssemblyIdentity;

                    int totalNumberOfTypes = primaryAssembly.AllTypes.Count;

                    #region Pass 1: Mutate each input module (including the primary assembly) so everything is re-parented to the merged assembly
                    renamer.RewriteChildren(primaryAssembly);
                    for (int i = 0, n = modules.Count; i < n; i++)
                    {
                        var mutableModule = modules[i];
                        // call Rewrite and not RewriteChildren so dynamic dispatch can call the right rewriter method
                        // otherwise, it just rewrites it as a module, not whatever subtype it is.
                        renamer.Rewrite(mutableModule);
                        // However, the rewriter does *not* rewrite parents. So need to re-parent the root unit namespace
                        // of the mutable assembly so it points to the merged assembly. Otherwise, interning (among other
                        // things) will not work correctly.
                        var rootUnitNs = (RootUnitNamespace)mutableModule.UnitNamespaceRoot;
                        rootUnitNs.Unit     = primaryAssembly;
                        totalNumberOfTypes += mutableModule.AllTypes.Count;
                    }
                    #endregion

                    #region Pass 2: Collect all of the types into the merged assembly

                    var mergedTypes = new List <INamedTypeDefinition>(totalNumberOfTypes);

                    #region Merge together all of the <Module> classes from the input assemblies
                    // TODO: Merge all of the <Module> classes, i.e., type 0 from each of the input assemblies
                    mergedTypes.Add(primaryAssembly.AllTypes[0]);
                    #endregion

                    var internedKeys = new HashSet <string>(); // keep track of all namespace type definitions

                    #region Types from the primary assembly
                    for (int i = 1, n = primaryAssembly.AllTypes.Count; i < n; i++)
                    {
                        var t = primaryAssembly.AllTypes[i];
                        mergedTypes.Add(t);
                        if (t is INamespaceTypeDefinition) // don't care about nested types
                        {
                            var key = TypeHelper.GetTypeName(t, NameFormattingOptions.None);
                            internedKeys.Add(key);
                        }
                    }
                    #endregion

                    #region Types from the other input assemblies, taking care of duplicates

                    for (int i = 0, n = modules.Count; i < n; i++)
                    {
                        var module   = modules[i];
                        var unitName = module.Name.Value;
                        for (int j = 1, m = module.AllTypes.Count; j < m; j++)
                        {
                            var t = module.AllTypes[j];
                            var namespaceTypeDefinition = t as NamespaceTypeDefinition;
                            // duplicates can be only at the top-level: namespace type definitions
                            // if a namespace type definition is unique, then so are all of its nested types
                            if (namespaceTypeDefinition != null)
                            {
                                var typeName = TypeHelper.GetTypeName(namespaceTypeDefinition, NameFormattingOptions.UseGenericTypeNameSuffix);
                                if (internedKeys.Contains(typeName)) // error: duplicate!
                                {
                                    if (!namespaceTypeDefinition.IsPublic || options.allowDup)
                                    {
                                        var newName = String.Format("{0}_from_{1}", namespaceTypeDefinition.Name.Value, unitName);
                                        namespaceTypeDefinition.Name = host.NameTable.GetNameFor(newName);
                                        var newTypeName = TypeHelper.GetTypeName(namespaceTypeDefinition, NameFormattingOptions.UseGenericTypeNameSuffix);
                                        Console.WriteLine("Adding '{0}' as '{1}'", typeName, newTypeName);
                                        internedKeys.Add(typeName);
                                        t = namespaceTypeDefinition;
                                    }
                                    else
                                    {
                                        Console.WriteLine("Error: Duplicate type '{0}'", typeName);
                                        continue; //TODO: set a flag somewhere to force a failure.
                                    }
                                }
                                else
                                {
                                    //Console.WriteLine("Adding '{0}'", typeName);
                                    internedKeys.Add(typeName);
                                }
                            }
                            mergedTypes.Add(t);
                        }
                    }
                    #endregion

                    primaryAssembly.AllTypes = mergedTypes;

                    #endregion

                    CopyResourcesToPrimaryAssembly(primaryAssembly, modules);

                    if (version != null)
                    {
                        primaryAssembly.Version = version;
                    }

                    string outputPath;
                    if (options.output != null)
                    {
                        outputPath = options.output;
                    }
                    else
                    {
                        outputPath = primaryAssembly.Name.Value + Path.GetExtension(options.GeneralArguments[0]) + ".meta";
                    }

                    using (var aggregateSourceLocationProvider = new AggregatingSourceLocationProvider(unit2SourceLocationProviderMap)) {
                        using (var aggregateLocalScopeProvider = new AggregatingLocalScopeProvider(unit2LocalScopeProviderMap)) {
                            using (var peStream = File.Create(outputPath)) {
                                using (var pdbWriter = new PdbWriter(Path.ChangeExtension(outputPath, "pdb"), aggregateSourceLocationProvider)) {
                                    PeWriter.WritePeToStream(primaryAssembly, host, peStream, aggregateSourceLocationProvider, aggregateLocalScopeProvider, pdbWriter);
                                }
                            }
                        }
                    }
                } finally {
                }

                return(0); // success
            }
        }
Esempio n. 49
0
        static int Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("Usage: ILWeave [Assembly]");

                return 1;
            }

            string tmpDir, newName, newPdb;

            using (var host = new PeReader.DefaultHost())
            {
                var module = host.LoadUnitFrom(args[0]) as IModule;

                if (module == null || module is Dummy)
                {
                    Console.WriteLine("{0} is not a PE file containing a CLR assembly, or an error occurred when loading it.", args[0]);

                    return 1;
                }

                module = new MetadataDeepCopier(host).Copy(module);
                PdbReader pdbReader = null;
                var pdbFile = Path.ChangeExtension(module.Location, "pdb");

                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile))
                    {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                else
                {
                    Console.WriteLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");
                }
                using (pdbReader)
                {
                    var localScopeProvider = pdbReader == null ? null : new ILGenerator.LocalScopeProvider(pdbReader);

                    try
                    {
                        module = PropertyChangedWeaver.RewriteModule(
                            host,
                            localScopeProvider,
                            pdbReader,
                            module);
                    }
                    catch (InvalidOperationException e)
                    {
                        Console.WriteLine("Error: {0}", e);
                        Environment.Exit(5);
                    }

                    tmpDir = Directory.CreateDirectory(Path.GetRandomFileName()).FullName;
                    newName = Path.Combine(tmpDir, Path.GetFileName(args[0]));

                    using (var peStream = File.Create(newName))
                    {
                        newPdb = Path.ChangeExtension(newName, ".pdb");

                        using (var pdbWriter = new PdbWriter(newPdb, pdbReader))
                        {
                            PeWriter.WritePeToStream(module, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                        }
                    }
                }
            }

            var dst = Path.GetDirectoryName(args[0]);

            foreach (var s in Directory.GetFiles(tmpDir))
            {
                File.Copy(s, Path.Combine(dst, Path.GetFileName(s)), true);
            }

            Directory.Delete(tmpDir, true);

            return 0;
        }
Esempio n. 50
0
        static void Main(string[] args)
        {
            //String inputFile = @"c:\Users\typ\Documents\Visual Studio 2013\Projects\vererbung\vererbung\bin\Debug\vererbung.exe";
            String inputFile = @"e:\dile_v0_2_12_x86\Dile.exe";



            globalLog = new Log(@"e:\merge_logfile.txt");

            System.Console.WriteLine(inputFile);

            /*
             * if (args == null || args.Length == 0)
             * {
             *  Console.WriteLine("Usage: ILMutator <assembly> [<outputPath>]");
             *  return;
             * }
             */



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



                if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                {
                    //Console.WriteLine(args[0] + " is not a PE file containing a CLR module or 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)
                {
                    globalLog.writeLine("File does not have CIL assembly");
                    return;
                }


                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
                {
                    globalLog.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);
                    }



                    // AB HIER DER INTERESSANTE PART ZUM MERGEN, DAVOR NUR INIT CRAP

                    // search for class in namespace
                    NamespaceTypeDefinition foundClass = null;
                    foreach (var asdf in module.GetAllTypes())
                    {
                        //if (asdf.ToString() == "vererbung.Erber") {
                        if (asdf.ToString() == "Dile.Disassemble.Assembly")
                        {
                            foundClass = (asdf as NamespaceTypeDefinition);
                            break;
                        }
                    }
                    if (foundClass == null)
                    {
                        globalLog.writeLine("Class not found!");
                        return;
                    }

                    // merge class
                    globalLog.writeLine("Merge class \"" + foundClass.ToString() + "\" with all ancestors");
                    mergeClassWithAllAncestors(foundClass, host);



                    string newName;
                    if (args.Length == 2)
                    {
                        newName = args[1];
                        //newName = @"e:\dile_v0_2_12_x86\dile_classes.exe";
                        newName = @"e:\test.exe";
                    }
                    else
                    {
                        var loc      = module.Location;
                        var path     = Path.GetDirectoryName(loc) ?? "";
                        var fileName = Path.GetFileNameWithoutExtension(loc);
                        var ext      = Path.GetExtension(loc);
                        newName = Path.Combine(path, fileName + "1" + ext);
                        //newName = @"e:\dile_v0_2_12_x86\dile_classes.exe";
                        newName = @"e:\test.exe";
                    }

                    using (var peStream = File.Create(newName)) {
                        using (var pdbWriter = new PdbWriter(Path.ChangeExtension(newName, ".pdb"), pdbReader)) {
                            PeWriter.WritePeToStream(module, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                        }
                    }
                }
            }
        }