Skip to content

Commit b35774a

Browse files
authored
Merge 4a5ab07 into 34d5e3b
2 parents 34d5e3b + 4a5ab07 commit b35774a

File tree

21 files changed

+561
-266
lines changed

21 files changed

+561
-266
lines changed

Confuser.Core/Utils.cs

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -145,47 +145,15 @@ public static string EncodeString(byte[] buff, char[] charset) {
145145
for (int i = 1; i < buff.Length; i++) {
146146
current = (current << 8) + buff[i];
147147
while (current >= charset.Length) {
148-
ret.Append(charset[current % charset.Length]);
149-
current /= charset.Length;
148+
current = Math.DivRem(current, charset.Length, out int remainder);
149+
ret.Append(charset[remainder]);
150150
}
151151
}
152152
if (current != 0)
153153
ret.Append(charset[current % charset.Length]);
154154
return ret.ToString();
155155
}
156156

157-
/// <summary>
158-
/// Returns a new string in which all occurrences of a specified string in
159-
/// <paramref name="str" /> are replaced with another specified string.
160-
/// </summary>
161-
/// <returns>
162-
/// A <see cref="string" /> equivalent to <paramref name="str" /> but with all instances of
163-
/// <paramref name="oldValue" />
164-
/// replaced with <paramref name="newValue" />.
165-
/// </returns>
166-
/// <param name="str">A string to do the replace in. </param>
167-
/// <param name="oldValue">A string to be replaced. </param>
168-
/// <param name="newValue">A string to replace all occurrences of <paramref name="oldValue" />. </param>
169-
/// <param name="comparison">One of the <see cref="StringComparison" /> values. </param>
170-
/// <remarks>Adopted from http://stackoverflow.com/a/244933 </remarks>
171-
public static string Replace(this string str, string oldValue, string newValue, StringComparison comparison) {
172-
StringBuilder sb = new StringBuilder();
173-
174-
int previousIndex = 0;
175-
int index = str.IndexOf(oldValue, comparison);
176-
while (index != -1) {
177-
sb.Append(str.Substring(previousIndex, index - previousIndex));
178-
sb.Append(newValue);
179-
index += oldValue.Length;
180-
previousIndex = index;
181-
index = str.IndexOf(oldValue, index, comparison);
182-
}
183-
sb.Append(str.Substring(previousIndex));
184-
185-
return sb.ToString();
186-
}
187-
188-
189157
/// <summary>
190158
/// Encode the buffer to a hexadecimal string.
191159
/// </summary>
@@ -208,12 +176,17 @@ public static string ToHexString(byte[] buff) {
208176
/// <param name="self">The list to remove from.</param>
209177
/// <param name="match">The predicate that defines the conditions of the elements to remove.</param>
210178
/// <returns><paramref name="self" /> for method chaining.</returns>
211-
public static IList<T> RemoveWhere<T>(this IList<T> self, Predicate<T> match) {
179+
public static void RemoveWhere<T>(this IList<T> self, Predicate<T> match) {
180+
if (self is List<T> list) {
181+
list.RemoveAll(match);
182+
return;
183+
}
184+
185+
// Switch to slow algorithm
212186
for (int i = self.Count - 1; i >= 0; i--) {
213187
if (match(self[i]))
214188
self.RemoveAt(i);
215189
}
216-
return self;
217190
}
218191

219192
/// <summary>

Confuser.Protections/AntiDebugProtection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ protected override void Execute(ConfuserContext context, ProtectionParameters pa
121121
}
122122
}
123123
if (ren) {
124-
member.Name = name.ObfuscateName(member.Name, RenameMode.Unicode);
124+
member.Name = name.ObfuscateName(member, RenameMode.Unicode);
125125
name.SetCanRename(member, false);
126126
}
127127
}

Confuser.Renamer/AnalyzePhase.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,15 @@ protected override void Execute(ConfuserContext context, ProtectionParameters pa
3434
foreach (IDnlibDef def in parameters.Targets.WithProgress(context.Logger)) {
3535
ParseParameters(def, context, service, parameters);
3636

37-
if (def is ModuleDef) {
38-
var module = (ModuleDef)def;
39-
foreach (Resource res in module.Resources)
40-
service.SetOriginalName(res, res.Name);
37+
if (def is ModuleDef module) {
38+
foreach (var res in module.Resources)
39+
service.AddReservedIdentifier(res.Name);
4140
}
4241
else
43-
service.SetOriginalName(def, def.Name);
42+
service.SetOriginalName(def);
4443

45-
if (def is TypeDef) {
46-
service.GetVTables().GetVTable((TypeDef)def);
47-
service.SetOriginalNamespace(def, ((TypeDef)def).Namespace);
44+
if (def is TypeDef typeDef) {
45+
service.GetVTables().GetVTable(typeDef);
4846
}
4947
context.CheckCancellation();
5048
}

Confuser.Renamer/Analyzers/VTableAnalyzer.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,24 @@ public static void Analyze(INameService service, ICollection<ModuleDefMD> module
3333
// derived type. If the base type/interface is not in our control, we should
3434
// not rename the methods.
3535
bool baseUnderCtrl = modules.Contains(slot.MethodDef.DeclaringType.Module as ModuleDefMD);
36-
bool ifaceUnderCtrl = modules.Contains(slot.Overrides.MethodDef.DeclaringType.Module as ModuleDefMD);
37-
if ((!baseUnderCtrl && ifaceUnderCtrl) || !service.CanRename(slot.MethodDef)) {
36+
bool interfaceUnderCtrl = modules.Contains(slot.Overrides.MethodDef.DeclaringType.Module as ModuleDefMD);
37+
if (!baseUnderCtrl && interfaceUnderCtrl || !service.CanRename(slot.MethodDef)) {
3838
service.SetCanRename(slot.Overrides.MethodDef, false);
3939
}
40-
else if (baseUnderCtrl && !ifaceUnderCtrl || !service.CanRename(slot.Overrides.MethodDef)) {
40+
else if (baseUnderCtrl && !interfaceUnderCtrl || !service.CanRename(slot.Overrides.MethodDef)) {
4141
service.SetCanRename(slot.MethodDef, false);
4242
}
43+
44+
// For the case when method in base type implements an interface method for a derived type
45+
// do not consider method parameters to make method name the same in base type, derived type and interface
46+
var methodDef = slot.MethodDef;
47+
var typeDef = type.BaseType?.ResolveTypeDef();
48+
var baseMethod = typeDef?.FindMethod(methodDef.Name, methodDef.Signature as MethodSig);
49+
if (baseMethod != null) {
50+
string unifiedName = service.GetOriginalFullName(slot.Overrides.MethodDef);
51+
service.SetOriginalName(slot.MethodDef, unifiedName);
52+
service.SetOriginalName(baseMethod, unifiedName);
53+
}
4354
}
4455
}
4556
}
@@ -207,7 +218,7 @@ private static IEnumerable<MethodDef> FindBaseDeclarations(INameService service,
207218
unprocessed.Enqueue(slot.Overrides.MethodDef);
208219
slotsExists = true;
209220
}
210-
221+
211222
if (!slotsExists && method != currentMethod)
212223
yield return currentMethod;
213224
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Text.RegularExpressions;
5+
6+
namespace Confuser.Renamer {
7+
public class MessageDeobfuscator {
8+
static readonly Regex MapSymbolMatcher = new Regex("_[a-zA-Z0-9]+");
9+
static readonly Regex PasswordSymbolMatcher = new Regex("[a-zA-Z0-9_$]{23,}");
10+
11+
readonly Dictionary<string, string> _symbolMap;
12+
readonly ReversibleRenamer _renamer;
13+
14+
public static MessageDeobfuscator Load(string symbolMapFileName) {
15+
if (symbolMapFileName is null)
16+
throw new ArgumentNullException(nameof(symbolMapFileName));
17+
18+
var symbolMap = new Dictionary<string, string>();
19+
using (var reader = new StreamReader(File.OpenRead(symbolMapFileName))) {
20+
var line = reader.ReadLine();
21+
while (line != null) {
22+
int tabIndex = line.IndexOf('\t');
23+
if (tabIndex == -1)
24+
throw new FileFormatException();
25+
symbolMap.Add(line.Substring(0, tabIndex), line.Substring(tabIndex + 1));
26+
line = reader.ReadLine();
27+
}
28+
}
29+
30+
return new MessageDeobfuscator(symbolMap);
31+
}
32+
33+
public MessageDeobfuscator(Dictionary<string, string> map) => _symbolMap = map ?? throw new ArgumentNullException(nameof(map));
34+
35+
public MessageDeobfuscator(string password) => _renamer = new ReversibleRenamer(password);
36+
37+
public string Deobfuscate(string obfuscatedMessage) {
38+
if (_symbolMap != null) {
39+
return MapSymbolMatcher.Replace(obfuscatedMessage, DecodeSymbolMap);
40+
}
41+
42+
return PasswordSymbolMatcher.Replace(obfuscatedMessage, DecodeSymbolPassword);
43+
}
44+
45+
string DecodeSymbolMap(Match match) {
46+
var symbol = match.Value;
47+
if (_symbolMap.TryGetValue(symbol, out string result))
48+
return NameService.ExtractShortName(result, false);
49+
return NameService.ExtractShortName(symbol, false);
50+
}
51+
52+
string DecodeSymbolPassword(Match match) {
53+
var sym = match.Value;
54+
try {
55+
return NameService.ExtractShortName(_renamer.Decrypt(sym), false);
56+
}
57+
catch {
58+
return sym;
59+
}
60+
}
61+
}
62+
}

Confuser.Renamer/NameProtection.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ protected override void Execute(ConfuserContext context, ProtectionParameters pa
6666
if (!Directory.Exists(dir))
6767
Directory.CreateDirectory(dir);
6868

69-
using (var writer = new StreamWriter(File.OpenWrite(path))) {
69+
using (var writer = new StreamWriter(File.Create(path))) {
7070
foreach (var entry in map)
7171
writer.WriteLine("{0}\t{1}", entry.Key, entry.Value);
7272
}
7373
}
7474
}
7575
}
76-
}
76+
}

0 commit comments

Comments
 (0)