Skip to content

Commit f40d3cc

Browse files
committed
Debug readable obfuscation scheme
1 parent ac38150 commit f40d3cc

5 files changed

Lines changed: 49 additions & 32 deletions

File tree

Obfuscar/Helpers/TypeReferenceExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ public static string GetGenericName(this TypeReference type)
6868
for (int i = 0; i < type.GenericParameters.Count; i++)
6969
{
7070
GenericParameter genericName = type.GenericParameters[i];
71-
genericName.Name = nameMaker.UniqueName(i);
71+
genericName.Name = nameMaker.UniqueName(i, null, genericName.Name);
7272
}
7373

74-
type.GetElementType().Name = nameMaker.UniqueName(type.GenericParameters.Count);
74+
type.GetElementType().Name = nameMaker.UniqueName(type.GenericParameters.Count, null, type.Name);
7575
return type.Name;
7676
}
7777
}

Obfuscar/NameGroup.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ class NameGroup : IEnumerable<string>
3737

3838
HashSet<string> names = new HashSet<string>();
3939

40-
public string GetNext()
40+
public string GetNext(string originalName)
4141
{
4242
int index = _random.Next(20);
4343
string name;
4444
for (;;)
4545
{
46-
name = NameMaker.Instance.UniqueName(index++);
46+
name = NameMaker.Instance.UniqueName(index++, null, originalName);
4747
if (!names.Contains(name))
4848
return name;
4949
}
@@ -72,14 +72,14 @@ public void Remove(string name)
7272
names.Remove(name);
7373
}
7474

75-
public static string GetNext(IEnumerable<NameGroup> groups)
75+
public static string GetNext(IEnumerable<NameGroup> groups, string originalName)
7676
{
7777
int index = 0;
7878

7979
string name;
8080
for (;;)
8181
{
82-
name = NameMaker.Instance.UniqueName(index++);
82+
name = NameMaker.Instance.UniqueName(index++, null, originalName);
8383

8484
bool contained = false;
8585
foreach (NameGroup group in groups)

Obfuscar/NameMaker.cs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
using System;
2828
using System.Collections.Generic;
29+
using System.Linq;
2930
using System.Text;
3031

3132
namespace Obfuscar
@@ -74,6 +75,9 @@ internal NameMaker()
7475
koreanChars = new string(chars.ToArray());
7576

7677
UseKoreanChars = false;
78+
79+
// inherit global debug model obfuscation settings
80+
UseDebugVersionNames = Instance?.UseDebugVersionNames ?? false; // null possible when we create first Instance
7781
}
7882

7983
private void ShuffleArray<T>(IList<T> list, Random rnd)
@@ -117,16 +121,20 @@ public bool UseKoreanChars
117121
}
118122
}
119123

120-
public string UniqueName(int index)
121-
{
122-
return UniqueName(index, null);
123-
}
124+
/// <summary>
125+
/// Try to keep it readable for debug purposes (obfuscate/rename it but keep names similar to what was before obfuscation)
126+
/// </summary>
127+
public bool UseDebugVersionNames { get; set; }
124128

125-
public string UniqueName(int index, string sep)
129+
public string UniqueName(int index, string sep, string originalName)
126130
{
131+
var postfix = string.IsNullOrEmpty(originalName) || !UseDebugVersionNames
132+
? string.Empty
133+
: "_" + originalName.Split('.', '>').Last();
134+
127135
// optimization for simple case
128136
if (index < numUniqueChars)
129-
return uniqueChars[index].ToString();
137+
return uniqueChars[index].ToString() + postfix;
130138

131139
Stack<char> stack = new Stack<char>();
132140

@@ -147,22 +155,22 @@ public string UniqueName(int index, string sep)
147155
builder.Append(stack.Pop());
148156
}
149157

150-
return builder.ToString();
158+
return builder.ToString() + postfix;
151159
}
152160

153-
public string UniqueNestedTypeName(int index)
161+
public string UniqueNestedTypeName(int index, string originalName)
154162
{
155-
return UniqueName(index, null);
163+
return UniqueName(index, null, originalName);
156164
}
157165

158-
public string UniqueTypeName(int index)
166+
public string UniqueTypeName(int index, string originalName)
159167
{
160-
return UniqueName(index % numUniqueChars, ".");
168+
return UniqueName(index % numUniqueChars, ".", originalName);
161169
}
162170

163-
public string UniqueNamespace(int index)
171+
public string UniqueNamespace(int index, string originalName)
164172
{
165-
return UniqueName(index / numUniqueChars, ".");
173+
return UniqueName(index / numUniqueChars, ".", originalName);
166174
}
167175
}
168176
}

Obfuscar/Obfuscator.cs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ private void LoadFromReader(XDocument reader, string projectFileDirectory)
252252
NameMaker.Instance.UseUnicodeChars = true;
253253
if (Project.Settings.UseKoreanNames)
254254
NameMaker.Instance.UseKoreanChars = true;
255+
if (Project.Settings.UseDebugVersionNames)
256+
NameMaker.Instance.UseDebugVersionNames = true;
255257

256258
LogOutput("Loading assemblies...");
257259
LogOutput("Extra framework folders: ");
@@ -521,8 +523,8 @@ private void ProcessField(FieldDefinition field, TypeKey typeKey, Dictionary<str
521523
}
522524

523525
var newName = Project.Settings.ReuseNames
524-
? nameGroup.GetNext()
525-
: NameMaker.Instance.UniqueName(_uniqueMemberNameIndex++);
526+
? nameGroup.GetNext(field.Name)
527+
: NameMaker.Instance.UniqueName(_uniqueMemberNameIndex++, null, field.Name);
526528

527529
RenameField(info, fieldKey, field, newName);
528530
nameGroup.Add(newName);
@@ -582,7 +584,7 @@ public void RenameParams()
582584

583585
int index = 0;
584586
foreach (GenericParameter param in type.GenericParameters)
585-
param.Name = NameMaker.Instance.UniqueName(index++);
587+
param.Name = NameMaker.Instance.UniqueName(index++, null, param.Name);
586588
}
587589
}
588590
}
@@ -601,7 +603,7 @@ private void RenameParams(MethodDefinition method, AssemblyInfo info)
601603
int index = 0;
602604
foreach (GenericParameter param in method.GenericParameters)
603605
if (param.CustomAttributes.Count == 0)
604-
param.Name = NameMaker.Instance.UniqueName(index++);
606+
param.Name = NameMaker.Instance.UniqueName(index++, null, param.Name);
605607
}
606608

607609
/// <summary>
@@ -689,19 +691,19 @@ public void RenameTypes(HashSet<string> namesInXaml)
689691
if (type.IsNested)
690692
{
691693
ns = "";
692-
name = NameMaker.Instance.UniqueNestedTypeName(type.DeclaringType.NestedTypes.IndexOf(type));
694+
name = NameMaker.Instance.UniqueNestedTypeName(type.DeclaringType.NestedTypes.IndexOf(type), type.Name);
693695
}
694696
else
695697
{
696698
if (Project.Settings.ReuseNames)
697699
{
698-
name = NameMaker.Instance.UniqueTypeName(typeIndex);
699-
ns = NameMaker.Instance.UniqueNamespace(typeIndex);
700+
name = NameMaker.Instance.UniqueTypeName(typeIndex, type.Name);
701+
ns = NameMaker.Instance.UniqueNamespace(typeIndex, type.Name);
700702
}
701703
else
702704
{
703-
name = NameMaker.Instance.UniqueName(_uniqueTypeNameIndex);
704-
ns = NameMaker.Instance.UniqueNamespace(_uniqueTypeNameIndex);
705+
name = NameMaker.Instance.UniqueName(_uniqueTypeNameIndex, null, type.Name);
706+
ns = NameMaker.Instance.UniqueNamespace(_uniqueTypeNameIndex, type.Name);
705707
_uniqueTypeNameIndex++;
706708
}
707709
}
@@ -1002,7 +1004,8 @@ private int ProcessProperty(TypeKey typeKey, PropertyDefinition prop, AssemblyIn
10021004
else if (prop.CustomAttributes.Count > 0)
10031005
{
10041006
// If a property has custom attributes we don't remove the property but rename it instead.
1005-
var newName = NameMaker.Instance.UniqueName(Project.Settings.ReuseNames ? index++ : _uniqueMemberNameIndex++);
1007+
var newName = NameMaker.Instance.UniqueName(Project.Settings.ReuseNames ? index++ : _uniqueMemberNameIndex++,
1008+
null, prop.Name);
10061009
RenameProperty(info, propKey, prop, newName);
10071010
}
10081011
else
@@ -1301,7 +1304,7 @@ private void RenameVirtualMethod(Dictionary<TypeKey, Dictionary<ParamSig, NameGr
13011304
NameGroup[] nameGroups = GetNameGroups(baseSigNames, @group.Methods, sig);
13021305

13031306
// for an internal group, get next unused name
1304-
groupName = NameGroup.GetNext(nameGroups);
1307+
groupName = NameGroup.GetNext(nameGroups, method.Name);
13051308
@group.Name = groupName;
13061309

13071310
// set up methods to be renamed
@@ -1415,7 +1418,7 @@ private string GetNewName(Dictionary<ParamSig, NameGroup> sigNames, MethodDefini
14151418

14161419
NameGroup nameGroup = GetNameGroup(sigNames, sig);
14171420

1418-
string newName = nameGroup.GetNext();
1421+
string newName = nameGroup.GetNext(method.Name);
14191422

14201423
// make sure the name groups is updated
14211424
nameGroup.Add(newName);
@@ -1821,7 +1824,7 @@ public void ProcessStrings(MethodDefinition method,
18211824
MethodDefinition individualStringMethodDefinition;
18221825
if (!_methodByString.TryGetValue(str, out individualStringMethodDefinition))
18231826
{
1824-
string methodName = NameMaker.Instance.UniqueName(_nameIndex++);
1827+
string methodName = NameMaker.Instance.UniqueName(_nameIndex++, null, "StringReplacedWithCall");
18251828

18261829
// Add the string to the data array
18271830
byte[] stringBytes = Encoding.UTF8.GetBytes(str);

Obfuscar/Settings.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public Settings(Variables vars)
4646
ReuseNames = XmlConvert.ToBoolean(vars.GetValue("ReuseNames", "true"));
4747
UseUnicodeNames = XmlConvert.ToBoolean(vars.GetValue("UseUnicodeNames", "false"));
4848
UseKoreanNames = XmlConvert.ToBoolean(vars.GetValue("UseKoreanNames", "false"));
49+
UseDebugVersionNames = XmlConvert.ToBoolean(vars.GetValue("UseDebugVersionNames", "false"));
4950
HideStrings = XmlConvert.ToBoolean(vars.GetValue("HideStrings", "true"));
5051
Optimize = XmlConvert.ToBoolean(vars.GetValue("OptimizeMethods", "true"));
5152
SuppressIldasm = XmlConvert.ToBoolean(vars.GetValue("SuppressIldasm", "true"));
@@ -98,6 +99,11 @@ public Settings(Variables vars)
9899

99100
public bool UseKoreanNames { get; }
100101

102+
/// <summary>
103+
/// Try to keep it readable for debug purposes (obfuscate/rename it but keep names similar to what was before obfuscation)
104+
/// </summary>
105+
public bool UseDebugVersionNames { get; }
106+
101107
public bool AbortOnInconsistentState { get; }
102108

103109
public bool LogRecoveredInconsistentState { get; }

0 commit comments

Comments
 (0)