Skip to content

Commit

Permalink
Merge 8e86cfd into ab35e5c
Browse files Browse the repository at this point in the history
  • Loading branch information
KvanTTT authored Feb 22, 2021
2 parents ab35e5c + 8e86cfd commit 6afa9c6
Show file tree
Hide file tree
Showing 21 changed files with 651 additions and 283 deletions.
45 changes: 9 additions & 36 deletions Confuser.Core/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,47 +145,15 @@ public static string EncodeString(byte[] buff, char[] charset) {
for (int i = 1; i < buff.Length; i++) {
current = (current << 8) + buff[i];
while (current >= charset.Length) {
ret.Append(charset[current % charset.Length]);
current /= charset.Length;
current = Math.DivRem(current, charset.Length, out int remainder);
ret.Append(charset[remainder]);
}
}
if (current != 0)
ret.Append(charset[current % charset.Length]);
return ret.ToString();
}

/// <summary>
/// Returns a new string in which all occurrences of a specified string in
/// <paramref name="str" /> are replaced with another specified string.
/// </summary>
/// <returns>
/// A <see cref="string" /> equivalent to <paramref name="str" /> but with all instances of
/// <paramref name="oldValue" />
/// replaced with <paramref name="newValue" />.
/// </returns>
/// <param name="str">A string to do the replace in. </param>
/// <param name="oldValue">A string to be replaced. </param>
/// <param name="newValue">A string to replace all occurrences of <paramref name="oldValue" />. </param>
/// <param name="comparison">One of the <see cref="StringComparison" /> values. </param>
/// <remarks>Adopted from http://stackoverflow.com/a/244933 </remarks>
public static string Replace(this string str, string oldValue, string newValue, StringComparison comparison) {
StringBuilder sb = new StringBuilder();

int previousIndex = 0;
int index = str.IndexOf(oldValue, comparison);
while (index != -1) {
sb.Append(str.Substring(previousIndex, index - previousIndex));
sb.Append(newValue);
index += oldValue.Length;
previousIndex = index;
index = str.IndexOf(oldValue, index, comparison);
}
sb.Append(str.Substring(previousIndex));

return sb.ToString();
}


/// <summary>
/// Encode the buffer to a hexadecimal string.
/// </summary>
Expand All @@ -208,12 +176,17 @@ public static string ToHexString(byte[] buff) {
/// <param name="self">The list to remove from.</param>
/// <param name="match">The predicate that defines the conditions of the elements to remove.</param>
/// <returns><paramref name="self" /> for method chaining.</returns>
public static IList<T> RemoveWhere<T>(this IList<T> self, Predicate<T> match) {
public static void RemoveWhere<T>(this IList<T> self, Predicate<T> match) {
if (self is List<T> list) {
list.RemoveAll(match);
return;
}

// Switch to slow algorithm
for (int i = self.Count - 1; i >= 0; i--) {
if (match(self[i]))
self.RemoveAt(i);
}
return self;
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Confuser.Protections/AntiDebugProtection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ protected override void Execute(ConfuserContext context, ProtectionParameters pa
}
}
if (ren) {
member.Name = name.ObfuscateName(member.Name, RenameMode.Unicode);
member.Name = name.ObfuscateName(member, RenameMode.Unicode);
name.SetCanRename(member, false);
}
}
Expand Down
14 changes: 6 additions & 8 deletions Confuser.Renamer/AnalyzePhase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,15 @@ protected override void Execute(ConfuserContext context, ProtectionParameters pa
foreach (IDnlibDef def in parameters.Targets.WithProgress(context.Logger)) {
ParseParameters(def, context, service, parameters);

if (def is ModuleDef) {
var module = (ModuleDef)def;
foreach (Resource res in module.Resources)
service.SetOriginalName(res, res.Name);
if (def is ModuleDef module) {
foreach (var res in module.Resources)
service.AddReservedIdentifier(res.Name);
}
else
service.SetOriginalName(def, def.Name);
service.SetOriginalName(def);

if (def is TypeDef) {
service.GetVTables().GetVTable((TypeDef)def);
service.SetOriginalNamespace(def, ((TypeDef)def).Namespace);
if (def is TypeDef typeDef) {
service.GetVTables().GetVTable(typeDef);
}
context.CheckCancellation();
}
Expand Down
21 changes: 16 additions & 5 deletions Confuser.Renamer/Analyzers/VTableAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ public static void Analyze(INameService service, ICollection<ModuleDefMD> module
// derived type. If the base type/interface is not in our control, we should
// not rename the methods.
bool baseUnderCtrl = modules.Contains(slot.MethodDef.DeclaringType.Module as ModuleDefMD);
bool ifaceUnderCtrl = modules.Contains(slot.Overrides.MethodDef.DeclaringType.Module as ModuleDefMD);
if ((!baseUnderCtrl && ifaceUnderCtrl) || !service.CanRename(slot.MethodDef)) {
bool interfaceUnderCtrl = modules.Contains(slot.Overrides.MethodDef.DeclaringType.Module as ModuleDefMD);
if (!baseUnderCtrl && interfaceUnderCtrl || !service.CanRename(slot.MethodDef)) {
service.SetCanRename(slot.Overrides.MethodDef, false);
}
else if (baseUnderCtrl && !ifaceUnderCtrl || !service.CanRename(slot.Overrides.MethodDef)) {
else if ((baseUnderCtrl && !interfaceUnderCtrl) || (!service.CanRename(slot.Overrides.MethodDef))) {
service.SetCanRename(slot.MethodDef, false);
}

Expand All @@ -48,6 +48,17 @@ public static void Analyze(INameService service, ICollection<ModuleDefMD> module
SetupOverwriteReferences(service, modules, slot, type);
//CreateOverrideReference(service, slot.MethodDef, slot.Overrides.MethodDef);
}

// For the case when method in base type implements an interface method for a derived type
// do not consider method parameters to make method name the same in base type, derived type and interface
var methodDef = slot.MethodDef;
var typeDef = type.BaseType?.ResolveTypeDef();
var baseMethod = typeDef?.FindMethod(methodDef.Name, methodDef.Signature as MethodSig);
if (baseMethod != null) {
string unifiedName = service.GetOriginalFullName(slot.Overrides.MethodDef);
service.SetOriginalName(slot.MethodDef, unifiedName);
service.SetOriginalName(baseMethod, unifiedName);
}
}
}
}
Expand Down Expand Up @@ -215,7 +226,7 @@ private static IEnumerable<MethodDef> FindBaseDeclarations(INameService service,
unprocessed.Enqueue(slot.Overrides.MethodDef);
slotsExists = true;
}

if (!slotsExists && method != currentMethod)
yield return currentMethod;
}
Expand Down Expand Up @@ -320,7 +331,7 @@ private static bool IsMatchingOverride(MethodOverride methodOverride, IMethodDef

var targetMethodSig = targetMethod.MethodSig;
var overrideMethodSig = methodOverride.MethodDeclaration.MethodSig;

targetMethodSig = ResolveGenericSignature(targetMethod, targetMethodSig);
overrideMethodSig = ResolveGenericSignature(methodOverride.MethodDeclaration, overrideMethodSig);

Expand Down
62 changes: 62 additions & 0 deletions Confuser.Renamer/MessageDeobfuscator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

namespace Confuser.Renamer {
public class MessageDeobfuscator {
static readonly Regex MapSymbolMatcher = new Regex("_[a-zA-Z0-9]+");
static readonly Regex PasswordSymbolMatcher = new Regex("[a-zA-Z0-9_$]{23,}");

readonly Dictionary<string, string> _symbolMap;
readonly ReversibleRenamer _renamer;

public static MessageDeobfuscator Load(string symbolMapFileName) {
if (symbolMapFileName is null)
throw new ArgumentNullException(nameof(symbolMapFileName));

var symbolMap = new Dictionary<string, string>();
using (var reader = new StreamReader(File.OpenRead(symbolMapFileName))) {
var line = reader.ReadLine();
while (line != null) {
int tabIndex = line.IndexOf('\t');
if (tabIndex == -1)
throw new FileFormatException();
symbolMap.Add(line.Substring(0, tabIndex), line.Substring(tabIndex + 1));
line = reader.ReadLine();
}
}

return new MessageDeobfuscator(symbolMap);
}

public MessageDeobfuscator(Dictionary<string, string> map) => _symbolMap = map ?? throw new ArgumentNullException(nameof(map));

public MessageDeobfuscator(string password) => _renamer = new ReversibleRenamer(password);

public string Deobfuscate(string obfuscatedMessage) {
if (_symbolMap != null) {
return MapSymbolMatcher.Replace(obfuscatedMessage, DecodeSymbolMap);
}

return PasswordSymbolMatcher.Replace(obfuscatedMessage, DecodeSymbolPassword);
}

string DecodeSymbolMap(Match match) {
var symbol = match.Value;
if (_symbolMap.TryGetValue(symbol, out string result))
return NameService.ExtractShortName(result, false);
return NameService.ExtractShortName(symbol, false);
}

string DecodeSymbolPassword(Match match) {
var sym = match.Value;
try {
return NameService.ExtractShortName(_renamer.Decrypt(sym), false);
}
catch {
return sym;
}
}
}
}
4 changes: 2 additions & 2 deletions Confuser.Renamer/NameProtection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ protected override void Execute(ConfuserContext context, ProtectionParameters pa
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);

using (var writer = new StreamWriter(File.OpenWrite(path))) {
using (var writer = new StreamWriter(File.Create(path))) {
foreach (var entry in map)
writer.WriteLine("{0}\t{1}", entry.Key, entry.Value);
}
}
}
}
}
}
Loading

0 comments on commit 6afa9c6

Please sign in to comment.