546 строки
22 KiB
C#
546 строки
22 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Confuser.Core.Project;
|
|
using Confuser.Core.Services;
|
|
using dnlib.DotNet;
|
|
using dnlib.DotNet.Emit;
|
|
using dnlib.DotNet.Writer;
|
|
using Microsoft.Win32;
|
|
using InformationalAttribute = System.Reflection.AssemblyInformationalVersionAttribute;
|
|
using ProductAttribute = System.Reflection.AssemblyProductAttribute;
|
|
using CopyrightAttribute = System.Reflection.AssemblyCopyrightAttribute;
|
|
using MethodAttributes = dnlib.DotNet.MethodAttributes;
|
|
using MethodImplAttributes = dnlib.DotNet.MethodImplAttributes;
|
|
using TypeAttributes = dnlib.DotNet.TypeAttributes;
|
|
|
|
namespace Confuser.Core {
|
|
/// <summary>
|
|
/// The processing engine of ConfuserEx.
|
|
/// </summary>
|
|
public static class ConfuserEngine {
|
|
/// <summary>
|
|
/// The version of ConfuserEx.
|
|
/// </summary>
|
|
public static readonly string Version;
|
|
|
|
static readonly string Copyright;
|
|
|
|
static ConfuserEngine() {
|
|
Assembly assembly = typeof(ConfuserEngine).Assembly;
|
|
var nameAttr = (ProductAttribute)assembly.GetCustomAttributes(typeof(ProductAttribute), false)[0];
|
|
var verAttr = (InformationalAttribute)assembly.GetCustomAttributes(typeof(InformationalAttribute), false)[0];
|
|
var cpAttr = (CopyrightAttribute)assembly.GetCustomAttributes(typeof(CopyrightAttribute), false)[0];
|
|
Version = string.Format("{0} {1}", nameAttr.Product, verAttr.InformationalVersion);
|
|
Copyright = cpAttr.Copyright;
|
|
|
|
AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => {
|
|
try {
|
|
var asmName = new AssemblyName(e.Name);
|
|
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
|
if (asm.GetName().Name == asmName.Name)
|
|
return asm;
|
|
return null;
|
|
}
|
|
catch {
|
|
return null;
|
|
}
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Runs the engine with the specified parameters.
|
|
/// </summary>
|
|
/// <param name="parameters">The parameters.</param>
|
|
/// <param name="token">The token used for cancellation.</param>
|
|
/// <returns>Task to run the engine.</returns>
|
|
/// <exception cref="System.ArgumentNullException">
|
|
/// <paramref name="parameters" />.Project is <c>null</c>.
|
|
/// </exception>
|
|
public static Task Run(ConfuserParameters parameters, CancellationToken? token = null) {
|
|
if (parameters.Project == null)
|
|
throw new ArgumentNullException("parameters");
|
|
if (token == null)
|
|
token = new CancellationTokenSource().Token;
|
|
return Task.Factory.StartNew(() => RunInternal(parameters, token.Value), token.Value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Runs the engine.
|
|
/// </summary>
|
|
/// <param name="parameters">The parameters.</param>
|
|
/// <param name="token">The cancellation token.</param>
|
|
static void RunInternal(ConfuserParameters parameters, CancellationToken token) {
|
|
// 1. Setup context
|
|
var context = new ConfuserContext();
|
|
context.Logger = parameters.GetLogger();
|
|
context.Project = parameters.Project.Clone();
|
|
context.PackerInitiated = parameters.PackerInitiated;
|
|
context.token = token;
|
|
|
|
PrintInfo(context);
|
|
|
|
bool ok = false;
|
|
try {
|
|
// Enable watermarking by default
|
|
context.Project.Rules.Insert(0, new Rule {
|
|
new SettingItem<Protection>(WatermarkingProtection._Id)
|
|
});
|
|
|
|
var asmResolver = new AssemblyResolver();
|
|
asmResolver.EnableTypeDefCache = true;
|
|
asmResolver.DefaultModuleContext = new ModuleContext(asmResolver);
|
|
context.Resolver = asmResolver;
|
|
context.BaseDirectory = Path.Combine(Environment.CurrentDirectory, context.Project.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar);
|
|
context.OutputDirectory = Path.Combine(context.Project.BaseDirectory, context.Project.OutputDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar);
|
|
foreach (string probePath in context.Project.ProbePaths)
|
|
asmResolver.PostSearchPaths.Insert(0, Path.Combine(context.BaseDirectory, probePath));
|
|
|
|
context.CheckCancellation();
|
|
|
|
Marker marker = parameters.GetMarker();
|
|
|
|
// 2. Discover plugins
|
|
context.Logger.Debug("Discovering plugins...");
|
|
|
|
IList<Protection> prots;
|
|
IList<Packer> packers;
|
|
IList<ConfuserComponent> components;
|
|
parameters.GetPluginDiscovery().GetPlugins(context, out prots, out packers, out components);
|
|
|
|
context.Logger.InfoFormat("Discovered {0} protections, {1} packers.", prots.Count, packers.Count);
|
|
|
|
context.CheckCancellation();
|
|
|
|
// 3. Resolve dependency
|
|
context.Logger.Debug("Resolving component dependency...");
|
|
try {
|
|
var resolver = new DependencyResolver(prots);
|
|
prots = resolver.SortDependency();
|
|
}
|
|
catch (CircularDependencyException ex) {
|
|
context.Logger.ErrorException("", ex);
|
|
throw new ConfuserException(ex);
|
|
}
|
|
|
|
components.Insert(0, new CoreComponent(context, marker));
|
|
foreach (Protection prot in prots)
|
|
components.Add(prot);
|
|
foreach (Packer packer in packers)
|
|
components.Add(packer);
|
|
|
|
context.CheckCancellation();
|
|
|
|
// 4. Load modules
|
|
context.Logger.Info("Loading input modules...");
|
|
marker.Initalize(prots, packers);
|
|
MarkerResult markings = marker.MarkProject(context.Project, context);
|
|
context.Modules = new ModuleSorter(markings.Modules).Sort().ToList().AsReadOnly();
|
|
foreach (var module in context.Modules)
|
|
module.EnableTypeDefFindCache = false;
|
|
context.OutputModules = Enumerable.Repeat<byte[]>(null, context.Modules.Count).ToArray();
|
|
context.OutputSymbols = Enumerable.Repeat<byte[]>(null, context.Modules.Count).ToArray();
|
|
context.OutputPaths = Enumerable.Repeat<string>(null, context.Modules.Count).ToArray();
|
|
context.Packer = markings.Packer;
|
|
context.ExternalModules = markings.ExternalModules;
|
|
|
|
context.CheckCancellation();
|
|
|
|
// 5. Initialize components
|
|
context.Logger.Info("Initializing...");
|
|
foreach (ConfuserComponent comp in components) {
|
|
try {
|
|
comp.Initialize(context);
|
|
}
|
|
catch (Exception ex) {
|
|
context.Logger.ErrorException("Error occured during initialization of '" + comp.Name + "'.", ex);
|
|
throw new ConfuserException(ex);
|
|
}
|
|
context.CheckCancellation();
|
|
}
|
|
|
|
context.CheckCancellation();
|
|
|
|
// 6. Build pipeline
|
|
context.Logger.Debug("Building pipeline...");
|
|
var pipeline = new ProtectionPipeline();
|
|
context.Pipeline = pipeline;
|
|
foreach (ConfuserComponent comp in components) {
|
|
comp.PopulatePipeline(pipeline);
|
|
}
|
|
|
|
context.CheckCancellation();
|
|
|
|
//7. Run pipeline
|
|
RunPipeline(pipeline, context);
|
|
|
|
ok = true;
|
|
}
|
|
catch (AssemblyResolveException ex) {
|
|
context.Logger.ErrorException("Failed to resolve an assembly, check if all dependencies are present in the correct version.", ex);
|
|
PrintEnvironmentInfo(context);
|
|
}
|
|
catch (TypeResolveException ex) {
|
|
context.Logger.ErrorException("Failed to resolve a type, check if all dependencies are present in the correct version.", ex);
|
|
PrintEnvironmentInfo(context);
|
|
}
|
|
catch (MemberRefResolveException ex) {
|
|
context.Logger.ErrorException("Failed to resolve a member, check if all dependencies are present in the correct version.", ex);
|
|
PrintEnvironmentInfo(context);
|
|
}
|
|
catch (IOException ex) {
|
|
context.Logger.ErrorException("An IO error occurred, check if all input/output locations are readable/writable.", ex);
|
|
}
|
|
catch (OperationCanceledException) {
|
|
context.Logger.Error("Operation cancelled.");
|
|
}
|
|
catch (ConfuserException) {
|
|
// Exception is already handled/logged, so just ignore and report failure
|
|
}
|
|
catch (Exception ex) {
|
|
context.Logger.ErrorException("Unknown error occurred.", ex);
|
|
}
|
|
finally {
|
|
if (context.Resolver != null)
|
|
context.Resolver.Clear();
|
|
context.Logger.Finish(ok);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Runs the protection pipeline.
|
|
/// </summary>
|
|
/// <param name="pipeline">The protection pipeline.</param>
|
|
/// <param name="context">The context.</param>
|
|
static void RunPipeline(ProtectionPipeline pipeline, ConfuserContext context) {
|
|
Func<IList<IDnlibDef>> getAllDefs = () => context.Modules.SelectMany(module => module.FindDefinitions()).ToList();
|
|
Func<ModuleDef, IList<IDnlibDef>> getModuleDefs = module => module.FindDefinitions().ToList();
|
|
|
|
context.CurrentModuleIndex = -1;
|
|
|
|
pipeline.ExecuteStage(PipelineStage.Inspection, Inspection, () => getAllDefs(), context);
|
|
|
|
var options = new ModuleWriterOptionsBase[context.Modules.Count];
|
|
for (int i = 0; i < context.Modules.Count; i++) {
|
|
context.CurrentModuleIndex = i;
|
|
context.CurrentModuleWriterOptions = null;
|
|
|
|
pipeline.ExecuteStage(PipelineStage.BeginModule, BeginModule, () => getModuleDefs(context.CurrentModule), context);
|
|
pipeline.ExecuteStage(PipelineStage.ProcessModule, ProcessModule, () => getModuleDefs(context.CurrentModule), context);
|
|
pipeline.ExecuteStage(PipelineStage.OptimizeMethods, OptimizeMethods, () => getModuleDefs(context.CurrentModule), context);
|
|
pipeline.ExecuteStage(PipelineStage.EndModule, EndModule, () => getModuleDefs(context.CurrentModule), context);
|
|
|
|
options[i] = context.CurrentModuleWriterOptions;
|
|
}
|
|
|
|
for (int i = 0; i < context.Modules.Count; i++) {
|
|
context.CurrentModuleIndex = i;
|
|
context.CurrentModuleWriterOptions = options[i];
|
|
|
|
pipeline.ExecuteStage(PipelineStage.WriteModule, WriteModule, () => getModuleDefs(context.CurrentModule), context);
|
|
|
|
context.OutputModules[i] = context.CurrentModuleOutput;
|
|
context.OutputSymbols[i] = context.CurrentModuleSymbol;
|
|
context.CurrentModuleWriterOptions = null;
|
|
context.CurrentModuleOutput = null;
|
|
context.CurrentModuleSymbol = null;
|
|
}
|
|
|
|
context.CurrentModuleIndex = -1;
|
|
|
|
pipeline.ExecuteStage(PipelineStage.Debug, Debug, () => getAllDefs(), context);
|
|
pipeline.ExecuteStage(PipelineStage.Pack, Pack, () => getAllDefs(), context);
|
|
pipeline.ExecuteStage(PipelineStage.SaveModules, SaveModules, () => getAllDefs(), context);
|
|
|
|
if (!context.PackerInitiated)
|
|
context.Logger.Info("Done.");
|
|
}
|
|
|
|
static void Inspection(ConfuserContext context) {
|
|
context.Logger.Info("Resolving dependencies...");
|
|
foreach (var dependency in context.Modules
|
|
.SelectMany(module => module.GetAssemblyRefs().Select(asmRef => Tuple.Create(asmRef, module)))) {
|
|
try {
|
|
AssemblyDef assembly = context.Resolver.ResolveThrow(dependency.Item1, dependency.Item2);
|
|
}
|
|
catch (AssemblyResolveException ex) {
|
|
context.Logger.ErrorException("Failed to resolve dependency of '" + dependency.Item2.Name + "'.", ex);
|
|
throw new ConfuserException(ex);
|
|
}
|
|
}
|
|
|
|
context.Logger.Debug("Checking Strong Name...");
|
|
foreach (var module in context.Modules) {
|
|
CheckStrongName(context, module);
|
|
}
|
|
|
|
var marker = context.Registry.GetService<IMarkerService>();
|
|
|
|
context.Logger.Debug("Creating global .cctors...");
|
|
foreach (ModuleDefMD module in context.Modules) {
|
|
TypeDef modType = module.GlobalType;
|
|
if (modType == null) {
|
|
modType = new TypeDefUser("", "<Module>", null);
|
|
modType.Attributes = TypeAttributes.AnsiClass;
|
|
module.Types.Add(modType);
|
|
marker.Mark(modType, null);
|
|
}
|
|
MethodDef cctor = modType.FindOrCreateStaticConstructor();
|
|
if (!marker.IsMarked(cctor))
|
|
marker.Mark(cctor, null);
|
|
}
|
|
}
|
|
|
|
static void CheckStrongName(ConfuserContext context, ModuleDef module) {
|
|
var snKey = context.Annotations.Get<StrongNameKey>(module, Marker.SNKey);
|
|
var snPubKeyBytes = context.Annotations.Get<StrongNamePublicKey>(module, Marker.SNPubKey)?.CreatePublicKey();
|
|
var snDelaySign = context.Annotations.Get<bool>(module, Marker.SNDelaySig);
|
|
|
|
if (snPubKeyBytes == null && snKey != null)
|
|
snPubKeyBytes = snKey.PublicKey;
|
|
|
|
bool moduleIsSignedOrDelayedSigned = module.IsStrongNameSigned || !module.Assembly.PublicKey.IsNullOrEmpty;
|
|
|
|
bool isKeyProvided = snKey != null || (snDelaySign && snPubKeyBytes != null);
|
|
|
|
if (!isKeyProvided && moduleIsSignedOrDelayedSigned)
|
|
context.Logger.WarnFormat("[{0}] SN Key or SN public Key is not provided for a signed module, the output may not be working.", module.Name);
|
|
else if (isKeyProvided && !moduleIsSignedOrDelayedSigned)
|
|
context.Logger.WarnFormat("[{0}] SN Key or SN public Key is provided for an unsigned module, the output may not be working.", module.Name);
|
|
else if (snPubKeyBytes != null && moduleIsSignedOrDelayedSigned &&
|
|
!module.Assembly.PublicKey.Data.SequenceEqual(snPubKeyBytes))
|
|
context.Logger.WarnFormat("[{0}] Provided SN public Key and signed module's public key do not match, the output may not be working.",
|
|
module.Name);
|
|
}
|
|
|
|
static void CopyPEHeaders(PEHeadersOptions writerOptions, ModuleDefMD module) {
|
|
var image = module.Metadata.PEImage;
|
|
writerOptions.MajorImageVersion = image.ImageNTHeaders.OptionalHeader.MajorImageVersion;
|
|
writerOptions.MajorLinkerVersion = image.ImageNTHeaders.OptionalHeader.MajorLinkerVersion;
|
|
writerOptions.MajorOperatingSystemVersion = image.ImageNTHeaders.OptionalHeader.MajorOperatingSystemVersion;
|
|
writerOptions.MajorSubsystemVersion = image.ImageNTHeaders.OptionalHeader.MajorSubsystemVersion;
|
|
writerOptions.MinorImageVersion = image.ImageNTHeaders.OptionalHeader.MinorImageVersion;
|
|
writerOptions.MinorLinkerVersion = image.ImageNTHeaders.OptionalHeader.MinorLinkerVersion;
|
|
writerOptions.MinorOperatingSystemVersion = image.ImageNTHeaders.OptionalHeader.MinorOperatingSystemVersion;
|
|
writerOptions.MinorSubsystemVersion = image.ImageNTHeaders.OptionalHeader.MinorSubsystemVersion;
|
|
}
|
|
|
|
static void BeginModule(ConfuserContext context) {
|
|
context.Logger.InfoFormat("Processing module '{0}'...", context.CurrentModule.Name);
|
|
|
|
context.CurrentModuleWriterOptions = new ModuleWriterOptions(context.CurrentModule);
|
|
context.CurrentModuleWriterOptions.WriterEvent += (sender, e) => context.CheckCancellation();
|
|
CopyPEHeaders(context.CurrentModuleWriterOptions.PEHeadersOptions, context.CurrentModule);
|
|
|
|
if (!context.CurrentModule.IsILOnly || context.CurrentModule.VTableFixups != null)
|
|
context.RequestNative();
|
|
|
|
var snKey = context.Annotations.Get<StrongNameKey>(context.CurrentModule, Marker.SNKey);
|
|
var snPubKey = context.Annotations.Get<StrongNamePublicKey>(context.CurrentModule, Marker.SNPubKey);
|
|
var snSigKey = context.Annotations.Get<StrongNameKey>(context.CurrentModule, Marker.SNSigKey);
|
|
var snSigPubKey = context.Annotations.Get<StrongNamePublicKey>(context.CurrentModule, Marker.SNSigPubKey);
|
|
|
|
var snDelaySig = context.Annotations.Get<bool>(context.CurrentModule, Marker.SNDelaySig, false);
|
|
|
|
context.CurrentModuleWriterOptions.DelaySign = snDelaySig;
|
|
|
|
if (snKey != null && snPubKey != null && snSigKey != null && snSigPubKey != null)
|
|
context.CurrentModuleWriterOptions.InitializeEnhancedStrongNameSigning(context.CurrentModule, snSigKey, snSigPubKey, snKey, snPubKey);
|
|
else if (snSigPubKey != null && snSigKey != null)
|
|
context.CurrentModuleWriterOptions.InitializeEnhancedStrongNameSigning(context.CurrentModule, snSigKey, snSigPubKey);
|
|
else
|
|
context.CurrentModuleWriterOptions.InitializeStrongNameSigning(context.CurrentModule, snKey);
|
|
|
|
if (snDelaySig) {
|
|
context.CurrentModuleWriterOptions.StrongNamePublicKey = snPubKey;
|
|
context.CurrentModuleWriterOptions.StrongNameKey = null;
|
|
}
|
|
|
|
foreach (TypeDef type in context.CurrentModule.GetTypes())
|
|
foreach (MethodDef method in type.Methods) {
|
|
if (method.Body != null) {
|
|
method.Body.Instructions.SimplifyMacros(method.Body.Variables, method.Parameters);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void ProcessModule(ConfuserContext context) { }
|
|
|
|
static void OptimizeMethods(ConfuserContext context) {
|
|
foreach (TypeDef type in context.CurrentModule.GetTypes())
|
|
foreach (MethodDef method in type.Methods) {
|
|
if (method.Body != null)
|
|
method.Body.Instructions.OptimizeMacros();
|
|
}
|
|
}
|
|
|
|
static void EndModule(ConfuserContext context) {
|
|
string output = context.Modules[context.CurrentModuleIndex].Location;
|
|
if (output != null) {
|
|
if (!Path.IsPathRooted(output))
|
|
output = Path.Combine(Environment.CurrentDirectory, output);
|
|
output = Utils.GetRelativePath(output, context.BaseDirectory);
|
|
}
|
|
else {
|
|
output = context.CurrentModule.Name;
|
|
}
|
|
context.OutputPaths[context.CurrentModuleIndex] = output;
|
|
}
|
|
|
|
static void WriteModule(ConfuserContext context) {
|
|
context.Logger.InfoFormat("Writing module '{0}'...", context.CurrentModule.Name);
|
|
|
|
MemoryStream pdb = null, output = new MemoryStream();
|
|
|
|
if (context.CurrentModule.PdbState != null) {
|
|
pdb = new MemoryStream();
|
|
context.CurrentModuleWriterOptions.WritePdb = true;
|
|
context.CurrentModuleWriterOptions.PdbFileName = Path.ChangeExtension(Path.GetFileName(context.OutputPaths[context.CurrentModuleIndex]), "pdb");
|
|
context.CurrentModuleWriterOptions.PdbStream = pdb;
|
|
}
|
|
|
|
if (context.CurrentModuleWriterOptions is ModuleWriterOptions)
|
|
context.CurrentModule.Write(output, (ModuleWriterOptions)context.CurrentModuleWriterOptions);
|
|
else
|
|
context.CurrentModule.NativeWrite(output, (NativeModuleWriterOptions)context.CurrentModuleWriterOptions);
|
|
|
|
context.CurrentModuleOutput = output.ToArray();
|
|
if (context.CurrentModule.PdbState != null)
|
|
context.CurrentModuleSymbol = pdb.ToArray();
|
|
}
|
|
|
|
static void Debug(ConfuserContext context) {
|
|
context.Logger.Info("Finalizing...");
|
|
for (int i = 0; i < context.OutputModules.Count; i++) {
|
|
if (context.OutputSymbols[i] == null)
|
|
continue;
|
|
string path = Path.GetFullPath(Path.Combine(context.OutputDirectory, context.OutputPaths[i]));
|
|
string dir = Path.GetDirectoryName(path);
|
|
if (!Directory.Exists(dir))
|
|
Directory.CreateDirectory(dir);
|
|
File.WriteAllBytes(Path.ChangeExtension(path, "pdb"), context.OutputSymbols[i]);
|
|
}
|
|
}
|
|
|
|
static void Pack(ConfuserContext context) {
|
|
if (context.Packer != null) {
|
|
context.Logger.Info("Packing...");
|
|
context.Packer.Pack(context, new ProtectionParameters(context.Packer, context.Modules.OfType<IDnlibDef>().ToList()));
|
|
}
|
|
}
|
|
|
|
static void SaveModules(ConfuserContext context) {
|
|
context.Resolver.Clear();
|
|
for (int i = 0; i < context.OutputModules.Count; i++) {
|
|
string path = Path.GetFullPath(Path.Combine(context.OutputDirectory, context.OutputPaths[i]));
|
|
string dir = Path.GetDirectoryName(path);
|
|
if (!Directory.Exists(dir))
|
|
Directory.CreateDirectory(dir);
|
|
context.Logger.DebugFormat("Saving to '{0}'...", path);
|
|
File.WriteAllBytes(path, context.OutputModules[i]);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prints the copyright stuff and environment information.
|
|
/// </summary>
|
|
/// <param name="context">The working context.</param>
|
|
static void PrintInfo(ConfuserContext context) {
|
|
if (context.PackerInitiated) {
|
|
context.Logger.Info("Protecting packer stub...");
|
|
}
|
|
else {
|
|
context.Logger.InfoFormat("{0} {1}", Version, Copyright);
|
|
|
|
Type mono = Type.GetType("Mono.Runtime");
|
|
context.Logger.InfoFormat("Running on {0}, {1}, {2} bits",
|
|
Environment.OSVersion,
|
|
mono == null ?
|
|
".NET Framework v" + Environment.Version :
|
|
mono.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null),
|
|
IntPtr.Size * 8);
|
|
}
|
|
}
|
|
|
|
static IEnumerable<string> GetFrameworkVersions() {
|
|
// http://msdn.microsoft.com/en-us/library/hh925568.aspx
|
|
|
|
using (RegistryKey ndpKey =
|
|
RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
|
|
OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\")) {
|
|
foreach (string versionKeyName in ndpKey.GetSubKeyNames()) {
|
|
if (!versionKeyName.StartsWith("v"))
|
|
continue;
|
|
|
|
RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
|
|
var name = (string)versionKey.GetValue("Version", "");
|
|
string sp = versionKey.GetValue("SP", "").ToString();
|
|
string install = versionKey.GetValue("Install", "").ToString();
|
|
if (install == "" || sp != "" && install == "1")
|
|
yield return versionKeyName + " " + name;
|
|
|
|
if (name != "")
|
|
continue;
|
|
|
|
foreach (string subKeyName in versionKey.GetSubKeyNames()) {
|
|
RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
|
|
name = (string)subKey.GetValue("Version", "");
|
|
if (name != "")
|
|
sp = subKey.GetValue("SP", "").ToString();
|
|
install = subKey.GetValue("Install", "").ToString();
|
|
|
|
if (install == "")
|
|
yield return versionKeyName + " " + name;
|
|
else if (install == "1")
|
|
yield return " " + subKeyName + " " + name;
|
|
}
|
|
}
|
|
}
|
|
|
|
using (RegistryKey ndpKey =
|
|
RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
|
|
OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\")) {
|
|
if (ndpKey.GetValue("Release") == null)
|
|
yield break;
|
|
var releaseKey = (int)ndpKey.GetValue("Release");
|
|
yield return "v4.5 " + releaseKey;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prints the environment information when error occurred.
|
|
/// </summary>
|
|
/// <param name="context">The working context.</param>
|
|
static void PrintEnvironmentInfo(ConfuserContext context) {
|
|
if (context.PackerInitiated)
|
|
return;
|
|
|
|
context.Logger.Error("---BEGIN DEBUG INFO---");
|
|
|
|
context.Logger.Error("Installed Framework Versions:");
|
|
foreach (string ver in GetFrameworkVersions()) {
|
|
context.Logger.ErrorFormat(" {0}", ver.Trim());
|
|
}
|
|
context.Logger.Error("");
|
|
|
|
if (context.Resolver != null) {
|
|
context.Logger.Error("Cached assemblies:");
|
|
foreach (AssemblyDef asm in context.Resolver.GetCachedAssemblies()) {
|
|
if (string.IsNullOrEmpty(asm.ManifestModule.Location))
|
|
context.Logger.ErrorFormat(" {0}", asm.FullName);
|
|
else
|
|
context.Logger.ErrorFormat(" {0} ({1})", asm.FullName, asm.ManifestModule.Location);
|
|
foreach (var reference in asm.Modules.OfType<ModuleDefMD>().SelectMany(m => m.GetAssemblyRefs()))
|
|
context.Logger.ErrorFormat(" {0}", reference.FullName);
|
|
}
|
|
}
|
|
|
|
context.Logger.Error("---END DEBUG INFO---");
|
|
}
|
|
}
|
|
}
|