Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Confuser.Core/ConfuserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ public NativeModuleWriterOptions RequestNative() {
newOptions.ModuleKind = CurrentModuleWriterOptions.ModuleKind;
newOptions.PEHeadersOptions = CurrentModuleWriterOptions.PEHeadersOptions;
newOptions.ShareMethodBodies = CurrentModuleWriterOptions.ShareMethodBodies;
newOptions.DelaySign = CurrentModuleWriterOptions.DelaySign;
newOptions.StrongNameKey = CurrentModuleWriterOptions.StrongNameKey;
newOptions.StrongNamePublicKey = CurrentModuleWriterOptions.StrongNamePublicKey;
newOptions.Win32Resources = CurrentModuleWriterOptions.Win32Resources;
Expand Down
55 changes: 44 additions & 11 deletions Confuser.Core/ConfuserEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,8 @@ static void Inspection(ConfuserContext context) {
}

context.Logger.Debug("Checking Strong Name...");
foreach (ModuleDefMD module in context.Modules) {
var snKey = context.Annotations.Get<StrongNameKey>(module, Marker.SNKey);
if (snKey == null && module.IsStrongNameSigned)
context.Logger.WarnFormat("[{0}] SN Key is not provided for a signed module, the output may not be working.", module.Name);
else if (snKey != null && !module.IsStrongNameSigned)
context.Logger.WarnFormat("[{0}] SN Key is provided for an unsigned module, the output may not be working.", module.Name);
else if (snKey != null && module.IsStrongNameSigned &&
!module.Assembly.PublicKey.Data.SequenceEqual(snKey.PublicKey))
context.Logger.WarnFormat("[{0}] Provided SN Key and signed module's public key do not match, the output may not be working.", module.Name);
foreach (var module in context.Modules) {
CheckStrongName(context, module);
}

var marker = context.Registry.GetService<IMarkerService>();
Expand All @@ -300,6 +293,28 @@ static void Inspection(ConfuserContext context) {
}
}

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;
Expand All @@ -322,8 +337,26 @@ static void BeginModule(ConfuserContext context) {
if (!context.CurrentModule.IsILOnly || context.CurrentModule.VTableFixups != null)
context.RequestNative();

var snKey = context.Annotations.Get<StrongNameKey>(context.CurrentModule, Marker.SNKey);
context.CurrentModuleWriterOptions.InitializeStrongNameSigning(context.CurrentModule, snKey);
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) {
Expand Down
97 changes: 67 additions & 30 deletions Confuser.Core/Marker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,52 @@
using dnlib.DotNet;

namespace Confuser.Core {
using Rules = Dictionary<Rule, PatternExpression>;

using Rules = Dictionary<Rule, PatternExpression>;
/// <summary>
/// Resolves and marks the modules with protection settings according to the rules.
/// </summary>
public class Marker {
public class Marker {
/// <summary>
/// Annotation key of Strong Name Key.
/// </summary>
public static readonly object SNKey = new object();

public static readonly object SNKey = new object();

/// <summary>
/// Annotation key of Strong Name Public Key.
/// </summary>
public static readonly object SNPubKey = new object();

/// <summary>
/// Annotation key of Strong Name delay signing.
/// </summary>
public static readonly object SNDelaySig = new object();

/// <summary>
/// Annotation key of Strong Name Signature Key.
/// </summary>
public static readonly object SNSigKey = new object();

/// <summary>
/// Annotation key of Strong Name Public Signature Key.
/// </summary>
public static readonly object SNSigPubKey = new object();

/// <summary>
/// Annotation key of rules.
/// </summary>
public static readonly object RulesKey = new object();

public static readonly object RulesKey = new object();
/// <summary>
/// The packers available to use.
/// </summary>
protected Dictionary<string, Packer> packers;

protected Dictionary<string, Packer> packers;
/// <summary>
/// The protections available to use.
/// </summary>
protected Dictionary<string, Protection> protections;

protected Dictionary<string, Protection> protections;
/// <summary>
/// Initalizes the Marker with specified protections and packers.
/// </summary>
Expand All @@ -43,8 +63,8 @@ public class Marker {
public virtual void Initalize(IList<Protection> protections, IList<Packer> packers) {
this.protections = protections.ToDictionary(prot => prot.Id, prot => prot, StringComparer.OrdinalIgnoreCase);
this.packers = packers.ToDictionary(packer => packer.Id, packer => packer, StringComparer.OrdinalIgnoreCase);
}

}
/// <summary>
/// Fills the protection settings with the specified preset.
/// </summary>
Expand All @@ -54,8 +74,20 @@ void FillPreset(ProtectionPreset preset, ProtectionSettings settings) {
foreach (Protection prot in protections.Values)
if (prot.Preset != ProtectionPreset.None && prot.Preset <= preset && !settings.ContainsKey(prot))
settings.Add(prot, new Dictionary<string, string>());
}

}

public static StrongNamePublicKey LoadSNPubKey(ConfuserContext context, string path) {
if (path == null) return null;

try {
return new StrongNamePublicKey(path);
}
catch (Exception ex) {
context.Logger.ErrorException("Cannot load the Strong Name Public Key located at: " + path, ex);
throw new ConfuserException(ex);
}
}

/// <summary>
/// Loads the Strong Name Key at the specified path with a optional password.
/// </summary>
Expand All @@ -70,9 +102,9 @@ public static StrongNameKey LoadSNKey(ConfuserContext context, string path, stri
if (path == null) return null;

try {
if (pass != null) //pfx
{
// http://stackoverflow.com/a/12196742/462805
if (pass != null) //pfx
{
// http://stackoverflow.com/a/12196742/462805
var cert = new X509Certificate2();
cert.Import(path, pass, X509KeyStorageFlags.Exportable);

Expand All @@ -88,8 +120,8 @@ public static StrongNameKey LoadSNKey(ConfuserContext context, string path, stri
context.Logger.ErrorException("Cannot load the Strong Name Key located at: " + path, ex);
throw new ConfuserException(ex);
}
}

}
/// <summary>
/// Loads the assembly and marks the project.
/// </summary>
Expand Down Expand Up @@ -135,20 +167,25 @@ protected internal virtual MarkerResult MarkProject(ConfuserProject proj, Confus
Rules rules = ParseRules(proj, module.Item1, context);

context.Annotations.Set(module.Item2, SNKey, LoadSNKey(context, module.Item1.SNKeyPath == null ? null : Path.Combine(proj.BaseDirectory, module.Item1.SNKeyPath), module.Item1.SNKeyPassword));
context.Annotations.Set(module.Item2, SNSigKey, LoadSNKey(context, module.Item1.SNSigKeyPath == null ? null : Path.Combine(proj.BaseDirectory, module.Item1.SNSigKeyPath), module.Item1.SNKeyPassword));
context.Annotations.Set(module.Item2, SNPubKey, LoadSNPubKey(context, module.Item1.SNPubKeyPath == null ? null : Path.Combine(proj.BaseDirectory, module.Item1.SNPubKeyPath)));
context.Annotations.Set(module.Item2, SNSigPubKey, LoadSNPubKey(context, module.Item1.SNPubSigKeyPath == null ? null : Path.Combine(proj.BaseDirectory, module.Item1.SNPubSigKeyPath)));
context.Annotations.Set(module.Item2, SNDelaySig, module.Item1.SNDelaySig);

context.Annotations.Set(module.Item2, RulesKey, rules);

foreach (IDnlibDef def in module.Item2.FindDefinitions()) {
ApplyRules(context, def, rules);
context.CheckCancellation();
}

// Packer parameters are stored in modules
}
// Packer parameters are stored in modules
if (packerParams != null)
ProtectionParameters.GetParameters(context, module.Item2)[packer] = packerParams;
}
return new MarkerResult(modules.Select(module => module.Item2).ToList(), packer, extModules);
}

}
/// <summary>
/// Marks the member definition.
/// </summary>
Expand All @@ -158,8 +195,8 @@ protected internal virtual void MarkMember(IDnlibDef member, ConfuserContext con
ModuleDef module = ((IMemberRef)member).Module;
var rules = context.Annotations.Get<Rules>(module, RulesKey);
ApplyRules(context, member, rules);
}

}
/// <summary>
/// Parses the rules' patterns.
/// </summary>
Expand Down Expand Up @@ -189,8 +226,8 @@ protected Rules ParseRules(ConfuserProject proj, ProjectModule module, ConfuserC
}
}
return ret;
}

}
/// <summary>
/// Applies the rules to the target definition.
/// </summary>
Expand Down Expand Up @@ -218,4 +255,4 @@ protected void ApplyRules(ConfuserContext context, IDnlibDef target, Rules rules
ProtectionParameters.SetParameters(context, target, ret);
}
}
}
}
22 changes: 21 additions & 1 deletion Confuser.Core/ObfAttrMarker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,11 @@ ProtectionSettingsInfo AddRule(ObfuscationAttributeInfo attr, List<ProtectionSet

void MarkModule(ProjectModule projModule, ModuleDefMD module, Rules rules, bool isMain) {
string snKeyPath = projModule.SNKeyPath, snKeyPass = projModule.SNKeyPassword;
string snPubKeyPath = projModule.SNPubKeyPath;
bool snDelaySig = projModule.SNDelaySig;
string snSigKeyPath = projModule.SNSigKeyPath;
string snPubSigKeyPath = projModule.SNPubSigKeyPath;

var stack = new ProtectionSettingsStack(context, protections);

var layer = new List<ProtectionSettingsInfo>();
Expand Down Expand Up @@ -425,8 +430,23 @@ void MarkModule(ProjectModule projModule, ModuleDefMD module, Rules rules, bool
}

snKeyPath = snKeyPath == null ? null : Path.Combine(project.BaseDirectory, snKeyPath);
snPubKeyPath = snPubKeyPath == null ? null : Path.Combine(project.BaseDirectory, snPubKeyPath);
snSigKeyPath = snSigKeyPath == null ? null : Path.Combine(project.BaseDirectory, snSigKeyPath);
snPubSigKeyPath = snPubSigKeyPath == null ? null : Path.Combine(project.BaseDirectory, snPubSigKeyPath);

var snKey = LoadSNKey(context, snKeyPath, snKeyPass);
context.Annotations.Set(module, SNKey, snKey);
context.Annotations.Set(module, SNKey, snKey);

var snPubKey = LoadSNPubKey(context, snPubKeyPath);
context.Annotations.Set(module, SNPubKey, snPubKey);

context.Annotations.Set(module, SNDelaySig, snDelaySig);

var snSigKey = LoadSNKey(context, snSigKeyPath, snKeyPass);
context.Annotations.Set(module, SNSigKey, snSigKey);

var snSigPubKey = LoadSNPubKey(context, snPubSigKeyPath);
context.Annotations.Set(module, SNSigPubKey, snSigPubKey);

using (stack.Apply(module, layer))
ProcessModule(module, stack);
Expand Down
23 changes: 18 additions & 5 deletions Confuser.Core/Packer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public abstract class Packer : ConfuserComponent {
/// <param name="module">The stub module.</param>
/// <param name="snKey">The strong name key.</param>
/// <param name="prot">The packer protection that applies to the stub.</param>
protected void ProtectStub(ConfuserContext context, string fileName, byte[] module, StrongNameKey snKey, Protection prot = null) {
protected void ProtectStub(ConfuserContext context, string fileName, byte[] module, StrongNameKey snKey, StrongNamePublicKey snPubKey, StrongNameKey snSigKey, StrongNamePublicKey snPubSigKey, bool snDelaySig, Protection prot = null) {
string tmpDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
try {
string outDir = Path.Combine(tmpDir, Path.GetRandomFileName());
Expand Down Expand Up @@ -75,7 +75,7 @@ protected void ProtectStub(ConfuserContext context, string fileName, byte[] modu
new ConfuserParameters {
Logger = new PackerLogger(context.Logger),
PluginDiscovery = discovery,
Marker = new PackerMarker(snKey),
Marker = new PackerMarker(snKey, snPubKey, snDelaySig, snSigKey, snPubSigKey),
Project = proj,
PackerInitiated = true
}, context.token).Wait();
Expand Down Expand Up @@ -165,15 +165,28 @@ public void Finish(bool successful) {

internal class PackerMarker : Marker {
readonly StrongNameKey snKey;
readonly StrongNamePublicKey snPubKey;
readonly bool snDelaySig;
readonly StrongNameKey snSigKey;
readonly StrongNamePublicKey snPubSigKey;

public PackerMarker(StrongNameKey snKey) {
public PackerMarker(StrongNameKey snKey, StrongNamePublicKey snPubKey, bool snDelaySig, StrongNameKey snSigKey, StrongNamePublicKey snPubSigKey) {
this.snKey = snKey;
this.snPubKey = snPubKey;
this.snDelaySig = snDelaySig;
this.snSigKey = snSigKey;
this.snPubSigKey = snPubSigKey;
}

protected internal override MarkerResult MarkProject(ConfuserProject proj, ConfuserContext context) {
MarkerResult result = base.MarkProject(proj, context);
foreach (ModuleDefMD module in result.Modules)
context.Annotations.Set(module, SNKey, snKey);
foreach (ModuleDefMD module in result.Modules) {
context.Annotations.Set(module, SNKey, snKey);
context.Annotations.Set(module, SNPubKey, snPubKey);
context.Annotations.Set(module, SNDelaySig, snDelaySig);
context.Annotations.Set(module, SNSigKey, snSigKey);
context.Annotations.Set(module, SNSigPubKey, snPubSigKey);
}
return result;
}
}
Expand Down
6 changes: 5 additions & 1 deletion Confuser.Core/Project/ConfuserPrj.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@
<xs:attribute name="path" type="xs:string" use="required" />
<xs:attribute name="external" type="xs:boolean" default="false" />
<xs:attribute name="snKey" type="xs:string" use="optional" />
<xs:attribute name="snPubKey" type="xs:string" use="optional" />
<xs:attribute name="snSigKey" type="xs:string" use="optional" />
<xs:attribute name="snPubSigKey" type="xs:string" use="optional" />
<xs:attribute name="snKeyPass" type="xs:string" use="optional" />
<xs:attribute name="snDelaySig" type="xs:boolean" default="false" />
</xs:complexType>


Expand All @@ -72,4 +76,4 @@
<xs:attribute name="debug" type="xs:boolean" default="false" />
</xs:complexType>
</xs:element>
</xs:schema>
</xs:schema>
Loading