Skip to content

Commit e79b8ab

Browse files
committed
Obfuscating assemblies with missing dependencies
ConfuserEx is now able to obfuscate assemblies without all the dependencies. It makes some worst case assumptions for missing dependencies.
1 parent b4a67cb commit e79b8ab

File tree

8 files changed

+110
-109
lines changed

8 files changed

+110
-109
lines changed

Confuser.Core/Confuser.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<ItemGroup Label="Nuget Dependencies">
1818
<PackageReference Include="Microsoft.Win32.Registry" Version="4.*" />
1919
<PackageReference Include="System.Threading" Version="4.*" />
20+
<PackageReference Include="System.ValueTuple" Version="4.*" />
2021
</ItemGroup>
2122

2223
<ItemGroup Label="Project Dependencies">

Confuser.Core/ConfuserEngine.cs

Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
using MethodImplAttributes = dnlib.DotNet.MethodImplAttributes;
1919
using TypeAttributes = dnlib.DotNet.TypeAttributes;
2020

21-
namespace Confuser.Core {
21+
namespace Confuser.Core {
2222
/// <summary>
2323
/// The processing engine of ConfuserEx.
2424
/// </summary>
25-
public static class ConfuserEngine {
25+
public static class ConfuserEngine {
2626
/// <summary>
2727
/// The version of ConfuserEx.
2828
/// </summary>
@@ -50,8 +50,8 @@ static ConfuserEngine() {
5050
return null;
5151
}
5252
};
53-
}
54-
53+
}
54+
5555
/// <summary>
5656
/// Runs the engine with the specified parameters.
5757
/// </summary>
@@ -67,15 +67,15 @@ public static Task Run(ConfuserParameters parameters, CancellationToken? token =
6767
if (token == null)
6868
token = new CancellationTokenSource().Token;
6969
return Task.Factory.StartNew(() => RunInternal(parameters, token.Value), token.Value);
70-
}
71-
70+
}
71+
7272
/// <summary>
7373
/// Runs the engine.
7474
/// </summary>
7575
/// <param name="parameters">The parameters.</param>
7676
/// <param name="token">The cancellation token.</param>
77-
static void RunInternal(ConfuserParameters parameters, CancellationToken token) {
78-
// 1. Setup context
77+
static void RunInternal(ConfuserParameters parameters, CancellationToken token) {
78+
// 1. Setup context
7979
var context = new ConfuserContext();
8080
context.Logger = parameters.GetLogger();
8181
context.Project = parameters.Project.Clone();
@@ -85,8 +85,8 @@ static void RunInternal(ConfuserParameters parameters, CancellationToken token)
8585
PrintInfo(context);
8686

8787
bool ok = false;
88-
try {
89-
// Enable watermarking by default
88+
try {
89+
// Enable watermarking by default
9090
context.Project.Rules.Insert(0, new Rule {
9191
new SettingItem<Protection>(WatermarkingProtection._Id),
9292
new SettingItem<Protection>("harden")
@@ -103,9 +103,9 @@ static void RunInternal(ConfuserParameters parameters, CancellationToken token)
103103

104104
context.CheckCancellation();
105105

106-
Marker marker = parameters.GetMarker();
107-
108-
// 2. Discover plugins
106+
Marker marker = parameters.GetMarker();
107+
108+
// 2. Discover plugins
109109
context.Logger.Debug("Discovering plugins...");
110110

111111
IList<Protection> prots;
@@ -115,9 +115,9 @@ static void RunInternal(ConfuserParameters parameters, CancellationToken token)
115115

116116
context.Logger.InfoFormat("Discovered {0} protections, {1} packers.", prots.Count, packers.Count);
117117

118-
context.CheckCancellation();
119-
120-
// 3. Resolve dependency
118+
context.CheckCancellation();
119+
120+
// 3. Resolve dependency
121121
context.Logger.Debug("Resolving component dependency...");
122122
try {
123123
var resolver = new DependencyResolver(prots);
@@ -134,9 +134,9 @@ static void RunInternal(ConfuserParameters parameters, CancellationToken token)
134134
foreach (Packer packer in packers)
135135
components.Add(packer);
136136

137-
context.CheckCancellation();
138-
139-
// 4. Load modules
137+
context.CheckCancellation();
138+
139+
// 4. Load modules
140140
context.Logger.Info("Loading input modules...");
141141
marker.Initalize(prots, packers);
142142
MarkerResult markings = marker.MarkProject(parameters.Project, context);
@@ -149,9 +149,9 @@ static void RunInternal(ConfuserParameters parameters, CancellationToken token)
149149
context.Packer = markings.Packer;
150150
context.ExternalModules = markings.ExternalModules;
151151

152-
context.CheckCancellation();
153-
154-
// 5. Initialize components
152+
context.CheckCancellation();
153+
154+
// 5. Initialize components
155155
context.Logger.Info("Initializing...");
156156
foreach (ConfuserComponent comp in components) {
157157
try {
@@ -164,19 +164,19 @@ static void RunInternal(ConfuserParameters parameters, CancellationToken token)
164164
context.CheckCancellation();
165165
}
166166

167-
context.CheckCancellation();
168-
169-
// 6. Build pipeline
167+
context.CheckCancellation();
168+
169+
// 6. Build pipeline
170170
context.Logger.Debug("Building pipeline...");
171171
var pipeline = new ProtectionPipeline();
172172
context.Pipeline = pipeline;
173173
foreach (ConfuserComponent comp in components) {
174174
comp.PopulatePipeline(pipeline);
175175
}
176176

177-
context.CheckCancellation();
178-
179-
//7. Run pipeline
177+
context.CheckCancellation();
178+
179+
//7. Run pipeline
180180
RunPipeline(pipeline, context);
181181

182182
ok = true;
@@ -199,8 +199,8 @@ static void RunInternal(ConfuserParameters parameters, CancellationToken token)
199199
catch (OperationCanceledException) {
200200
context.Logger.Error("Operation cancelled.");
201201
}
202-
catch (ConfuserException) {
203-
// Exception is already handled/logged, so just ignore and report failure
202+
catch (ConfuserException) {
203+
// Exception is already handled/logged, so just ignore and report failure
204204
}
205205
catch (Exception ex) {
206206
context.Logger.ErrorException("Unknown error occurred.", ex);
@@ -210,8 +210,8 @@ static void RunInternal(ConfuserParameters parameters, CancellationToken token)
210210
context.Resolver.Clear();
211211
context.Logger.Finish(ok);
212212
}
213-
}
214-
213+
}
214+
215215
/// <summary>
216216
/// Runs the protection pipeline.
217217
/// </summary>
@@ -264,14 +264,10 @@ static void RunPipeline(ProtectionPipeline pipeline, ConfuserContext context) {
264264
static void Inspection(ConfuserContext context) {
265265
context.Logger.Info("Resolving dependencies...");
266266
foreach (var dependency in context.Modules
267-
.SelectMany(module => module.GetAssemblyRefs().Select(asmRef => Tuple.Create(asmRef, module)))) {
268-
try {
269-
AssemblyDef assembly = context.Resolver.ResolveThrow(dependency.Item1, dependency.Item2);
270-
}
271-
catch (AssemblyResolveException ex) {
272-
context.Logger.ErrorException("Failed to resolve dependency of '" + dependency.Item2.Name + "'.", ex);
273-
throw new ConfuserException(ex);
274-
}
267+
.SelectMany(module => module.GetAssemblyRefs().Select(asmRef => (asmRef, module)))) {
268+
var assembly = context.Resolver.Resolve(dependency.asmRef, dependency.module);
269+
if (assembly is null)
270+
context.Logger.Warn("Failed to resolve dependency '" + dependency.asmRef.FullName + "'.");
275271
}
276272

277273
context.Logger.Debug("Checking Strong Name...");
@@ -312,8 +308,8 @@ static void CheckStrongName(ConfuserContext context, ModuleDef module) {
312308
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);
313309
else if (isKeyProvided && !moduleIsSignedOrDelayedSigned)
314310
context.Logger.WarnFormat("[{0}] SN Key or SN public Key is provided for an unsigned module, the output may not be working.", module.Name);
315-
else if (snPubKeyBytes != null && moduleIsSignedOrDelayedSigned &&
316-
!module.Assembly.PublicKey.Data.SequenceEqual(snPubKeyBytes))
311+
else if (snPubKeyBytes != null && moduleIsSignedOrDelayedSigned &&
312+
!module.Assembly.PublicKey.Data.SequenceEqual(snPubKeyBytes))
317313
context.Logger.WarnFormat("[{0}] Provided SN public Key and signed module's public key do not match, the output may not be working.",
318314
module.Name);
319315
}
@@ -444,8 +440,8 @@ static void SaveModules(ConfuserContext context) {
444440
context.Logger.DebugFormat("Saving to '{0}'...", path);
445441
File.WriteAllBytes(path, context.OutputModules[i]);
446442
}
447-
}
448-
443+
}
444+
449445
/// <summary>
450446
/// Prints the copyright stuff and environment information.
451447
/// </summary>
@@ -467,9 +463,9 @@ static void PrintInfo(ConfuserContext context) {
467463
}
468464
}
469465

470-
static IEnumerable<string> GetFrameworkVersions() {
471-
// http://msdn.microsoft.com/en-us/library/hh925568.aspx
472-
466+
static IEnumerable<string> GetFrameworkVersions() {
467+
// http://msdn.microsoft.com/en-us/library/hh925568.aspx
468+
473469
using (RegistryKey ndpKey =
474470
RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
475471
OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\")) {
@@ -510,8 +506,8 @@ static IEnumerable<string> GetFrameworkVersions() {
510506
var releaseKey = (int)ndpKey.GetValue("Release");
511507
yield return "v4.5 " + releaseKey;
512508
}
513-
}
514-
509+
}
510+
515511
/// <summary>
516512
/// Prints the environment information when error occurred.
517513
/// </summary>
@@ -530,7 +526,7 @@ static void PrintEnvironmentInfo(ConfuserContext context) {
530526

531527
if (context.Resolver != null) {
532528
context.Logger.Error("Cached assemblies:");
533-
foreach (AssemblyDef asm in context.Resolver.GetCachedAssemblies()) {
529+
foreach (var asm in context.Resolver.GetCachedAssemblies().Where(a => !(a is null))) {
534530
if (string.IsNullOrEmpty(asm.ManifestModule.Location))
535531
context.Logger.ErrorFormat(" {0}", asm.FullName);
536532
else

Confuser.Core/DnlibUtils.cs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -208,16 +208,14 @@ public static bool IsDelegate(this TypeDef type) {
208208
/// <param name="type">The type.</param>
209209
/// <param name="baseType">The full name of base type.</param>
210210
/// <returns><c>true</c> if the specified type is inherited from a base type; otherwise, <c>false</c>.</returns>
211-
public static bool InheritsFromCorlib(this TypeDef type, string baseType) {
212-
if (type.BaseType == null)
213-
return false;
214-
215-
TypeDef bas = type;
216-
do {
217-
bas = bas.BaseType.ResolveTypeDefThrow();
211+
public static bool InheritsFromCorLib(this TypeDef type, string baseType) {
212+
var bas = type.GetBaseType();
213+
while (!(bas is null) && bas.DefinitionAssembly.IsCorLib()) {
218214
if (bas.ReflectionFullName == baseType)
219215
return true;
220-
} while (bas.BaseType != null && bas.BaseType.DefinitionAssembly.IsCorLib());
216+
217+
bas = bas.GetBaseType();
218+
}
221219
return false;
222220
}
223221

@@ -228,15 +226,13 @@ public static bool InheritsFromCorlib(this TypeDef type, string baseType) {
228226
/// <param name="baseType">The full name of base type.</param>
229227
/// <returns><c>true</c> if the specified type is inherited from a base type; otherwise, <c>false</c>.</returns>
230228
public static bool InheritsFrom(this TypeDef type, string baseType) {
231-
if (type.BaseType == null)
232-
return false;
233-
234-
TypeDef bas = type;
235-
do {
236-
bas = bas.BaseType.ResolveTypeDefThrow();
229+
var bas = type.GetBaseType();;
230+
while (!(bas is null)) {
237231
if (bas.ReflectionFullName == baseType)
238232
return true;
239-
} while (bas.BaseType != null);
233+
234+
bas = bas.GetBaseType();
235+
}
240236
return false;
241237
}
242238

@@ -248,17 +244,14 @@ public static bool InheritsFrom(this TypeDef type, string baseType) {
248244
/// <returns><c>true</c> if the specified type implements the interface; otherwise, <c>false</c>.</returns>
249245
public static bool Implements(this TypeDef type, string fullName) {
250246
do {
251-
foreach (InterfaceImpl iface in type.Interfaces) {
252-
if (iface.Interface.ReflectionFullName == fullName)
253-
return true;
247+
if (type.Interfaces.Any(iFace => iFace.Interface.ReflectionFullName == fullName)) {
248+
return true;
254249
}
255250

256-
if (type.BaseType == null)
257-
return false;
258-
259-
type = type.BaseType.ResolveTypeDefThrow();
251+
type = type.GetBaseType() as TypeDef;
260252
} while (type != null);
261-
throw new UnreachableException();
253+
254+
return false;
262255
}
263256

264257
/// <summary>

Confuser.Renamer/AnalyzePhase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ void Analyze(NameService service, ConfuserContext context, ProtectionParameters
179179
if (parameters.GetParameter(context, type, "forceRen", false))
180180
return;
181181

182-
if (type.InheritsFromCorlib("System.Attribute")) {
182+
if (type.InheritsFromCorLib("System.Attribute")) {
183183
service.ReduceRenameMode(type, RenameMode.ASCII);
184184
}
185185

Confuser.Renamer/Analyzers/InterReferenceAnalyzer.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ public void Analyze(ConfuserContext context, INameService service, ProtectionPar
3535
for (uint i = 1; i <= len; i++) {
3636
TypeRef typeRef = module.ResolveTypeRef(i);
3737

38-
TypeDef typeDef = typeRef.ResolveTypeDefThrow();
38+
TypeDef typeDef = typeRef.ResolveTypeDef();
39+
if (typeDef is null) continue;
40+
3941
if (typeDef.Module != module && context.Modules.Contains((ModuleDefMD)typeDef.Module)) {
4042
service.AddReference(typeDef, new TypeRefReference(typeRef, typeDef));
4143
}
@@ -51,7 +53,9 @@ void ProcessMemberRef(ConfuserContext context, INameService service, ModuleDefMD
5153
if (memberRef.DeclaringType.TryGetArraySig() != null)
5254
return;
5355

54-
TypeDef declType = memberRef.DeclaringType.ResolveTypeDefThrow();
56+
TypeDef declType = memberRef.DeclaringType.ResolveTypeDef();
57+
if (declType is null) return;
58+
5559
if (declType.Module != module && context.Modules.Contains((ModuleDefMD)declType.Module)) {
5660
var memberDef = (IDnlibDef)declType.ResolveThrow(memberRef);
5761
service.AddReference(memberDef, new MemberRefReference(memberRef, memberDef));

Confuser.Renamer/Analyzers/LdtokenEnumAnalyzer.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ public void Analyze(ConfuserContext context, INameService service, ProtectionPar
3838
}
3939
else if (instr.Operand is ITypeDefOrRef) {
4040
if (!(instr.Operand is TypeSpec)) {
41-
TypeDef type = ((ITypeDefOrRef)instr.Operand).ResolveTypeDefThrow();
42-
if (context.Modules.Contains((ModuleDefMD)type.Module) &&
43-
HandleTypeOf(context, service, method, i)) {
41+
var type = ((ITypeDefOrRef)instr.Operand).ResolveTypeDef();
42+
if (!(type is null) && context.Modules.Contains((ModuleDefMD)type.Module) &&
43+
HandleTypeOf(context, service, method, i)) {
4444
var t = type;
4545
do {
4646
DisableRename(service, t, false);
@@ -108,11 +108,11 @@ void HandleEnum(ConfuserContext context, INameService service, MethodDef method,
108108
else
109109
return;
110110

111-
ITypeDefOrRef targetTypeRef = targetType.ToBasicTypeDefOrRef();
111+
var targetTypeRef = targetType.ToBasicTypeDefOrRef();
112112
if (targetTypeRef == null)
113113
return;
114114

115-
TypeDef targetTypeDef = targetTypeRef.ResolveTypeDefThrow();
115+
var targetTypeDef = targetTypeRef.ResolveTypeDef();
116116
if (targetTypeDef != null && targetTypeDef.IsEnum && context.Modules.Contains((ModuleDefMD)targetTypeDef.Module))
117117
DisableRename(service, targetTypeDef);
118118
}
@@ -183,4 +183,4 @@ void DisableRename(INameService service, TypeDef typeDef, bool memberOnly = true
183183
DisableRename(service, nested, false);
184184
}
185185
}
186-
}
186+
}

Confuser.Renamer/Analyzers/TypeBlobAnalyzer.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ public static void Analyze(INameService service, ICollection<ModuleDefMD> module
6868
foreach (CANamedArgument arg in attr.Properties)
6969
AnalyzeCAArgument(modules, service, arg.Argument);
7070

71-
TypeDef attrType = attr.AttributeType.ResolveTypeDefThrow();
72-
if (!modules.Contains((ModuleDefMD)attrType.Module))
71+
TypeDef attrType = attr.AttributeType.ResolveTypeDef();
72+
if (attrType is null || !modules.Contains((ModuleDefMD)attrType.Module))
7373
continue;
7474

7575
foreach (var arg in attr.NamedArguments) {
@@ -159,8 +159,8 @@ private static void AnalyzeMemberRef(ICollection<ModuleDefMD> modules, INameServ
159159
if (sig is GenericInstSig) {
160160
var inst = (GenericInstSig)sig;
161161
Debug.Assert(!(inst.GenericType.TypeDefOrRef is TypeSpec));
162-
TypeDef openType = inst.GenericType.TypeDefOrRef.ResolveTypeDefThrow();
163-
if (!modules.Contains((ModuleDefMD)openType.Module) ||
162+
TypeDef openType = inst.GenericType.TypeDefOrRef.ResolveTypeDef();
163+
if (openType is null || !modules.Contains((ModuleDefMD)openType.Module) ||
164164
memberRef.IsArrayAccessors())
165165
return;
166166

0 commit comments

Comments
 (0)