Skip to content
This repository has been archived by the owner on Jan 27, 2019. It is now read-only.

Commit

Permalink
Add InputSymbolMap attribute to ConfuserProject to allow the map for …
Browse files Browse the repository at this point in the history
…the future runs

Sometimes it is necessary to provide a patch for obfuscated software. Having different obfuscation applied to patched version comparing with the released one effectively means the patched version cannot be deployed without replacing every obfuscated assembly.

This change makes it possible to provide a symbol map from a previous obfuscation and preserves the renames specified there.
  • Loading branch information
ivan-danilov committed Oct 17, 2018
1 parent 3c9c29d commit 332d9e0
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Confuser.Core/ConfuserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ public ServiceRegistry Registry {
/// <value>The output directory.</value>
public string OutputDirectory { get; internal set; }

/// <summary>
/// Gets the input symbol map (optional).
/// </summary>
/// <value>The input symbol map.</value>
public string InputSymbolMap { get; internal set; }

/// <summary>
/// Gets the packer.
/// </summary>
Expand Down
4 changes: 4 additions & 0 deletions Confuser.Core/ConfuserEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ static void RunInternal(ConfuserParameters parameters, CancellationToken token)
context.Resolver = asmResolver;
context.BaseDirectory = Path.Combine(Environment.CurrentDirectory, parameters.Project.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar);
context.OutputDirectory = Path.Combine(parameters.Project.BaseDirectory, parameters.Project.OutputDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar);

if (!string.IsNullOrWhiteSpace(parameters.Project.InputSymbolMap))
context.InputSymbolMap = Path.Combine(parameters.Project.BaseDirectory, parameters.Project.InputSymbolMap);

foreach (string probePath in parameters.Project.ProbePaths)
asmResolver.PostSearchPaths.Insert(0, Path.Combine(context.BaseDirectory, probePath));

Expand Down
1 change: 1 addition & 0 deletions Confuser.Core/Project/ConfuserPrj.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
</xs:sequence>
<xs:attribute name="outputDir" type="xs:string" use="required" />
<xs:attribute name="baseDir" type="xs:string" use="required" />
<xs:attribute name="inputSymbolMap" type="xs:string" use="optional" />
<xs:attribute name="seed" type="xs:string" use="optional" />
<xs:attribute name="debug" type="xs:boolean" default="false" />
</xs:complexType>
Expand Down
12 changes: 12 additions & 0 deletions Confuser.Core/Project/ConfuserProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,12 @@ public ConfuserProject() {
/// <value>The base directory.</value>
public string BaseDirectory { get; set; }

/// <summary>
/// Gets or sets the input symbol map file.
/// </summary>
/// <value>The file with input symbol map.</value>
public string InputSymbolMap { get; set; }

/// <summary>
/// Gets a list of protection rules that applies globally.
/// </summary>
Expand Down Expand Up @@ -556,6 +562,11 @@ public void Load(XmlDocument doc) {
else
Seed = null;

if (docElem.Attributes["inputSymbolMap"] != null)
InputSymbolMap = docElem.Attributes["inputSymbolMap"].Value.NullIfEmpty();
else
InputSymbolMap = null;

if (docElem.Attributes["debug"] != null)
Debug = bool.Parse(docElem.Attributes["debug"].Value);
else
Expand Down Expand Up @@ -597,6 +608,7 @@ public void Load(XmlDocument doc) {
public ConfuserProject Clone() {
var ret = new ConfuserProject();
ret.Seed = Seed;
ret.InputSymbolMap = InputSymbolMap;
ret.Debug = Debug;
ret.OutputDirectory = OutputDirectory;
ret.BaseDirectory = BaseDirectory;
Expand Down
22 changes: 21 additions & 1 deletion Confuser.Renamer/NameService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Confuser.Core;
Expand Down Expand Up @@ -58,6 +59,8 @@ internal class NameService : INameService {

public NameService(ConfuserContext context) {
this.context = context;
if (context.InputSymbolMap != null)
LoadInputSymbolMap(context.InputSymbolMap);
storage = new VTableStorage(context.Logger);
random = context.Registry.GetService<IRandomService>().GetRandomGenerator(NameProtection._FullId);
nameSeed = random.NextBytes(20);
Expand All @@ -71,6 +74,23 @@ public NameService(ConfuserContext context) {
};
}

private void LoadInputSymbolMap(string inputSymbolMapPath)
{
var lineNum = 0;
foreach (var line in File.ReadLines(inputSymbolMapPath))
{
lineNum++;
if (string.IsNullOrWhiteSpace(line)) continue;
var fields = line.Split('\t');
if (fields.Length != 2)
throw new FileFormatException(string.Format("Cannot read input symbol map {0}:{1}", inputSymbolMapPath, lineNum));
var key = fields[0];
var value = fields[1];
nameMap2.Add(key, value);
nameMap1.Add(value, key);
}
}

public IList<IRenamer> Renamers { get; private set; }

public VTableStorage GetVTables() {
Expand Down Expand Up @@ -227,7 +247,7 @@ public string ObfuscateName(string name, RenameMode mode) {
byte[] hash = Utils.Xor(Utils.SHA1(Encoding.UTF8.GetBytes(name)), nameSeed);
for (int i = 0; i < 100; i++) {
newName = ObfuscateNameInternal(hash, mode);
if (!identifiers.Contains(MakeGenericName(newName, count)))
if (!identifiers.Contains(MakeGenericName(newName, count)) && !nameMap2.ContainsKey(newName))
break;
hash = Utils.SHA1(hash);
}
Expand Down
5 changes: 5 additions & 0 deletions docs/ProjectFormat.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ The seed of the random generator in protection process.
Indicates whether the debug symbols (*.pdb) are generated.
Currently unused.

`inputSymbolMap`
Path to symbols map relative to `baseDir`.
It if is set, rename protection will respect name mappings specified there and only generate additional ones as needed. Does not make sense for non-reversible rename modes.
Symbol map file can be taken from previous obfuscation or created manually. Every non-empty line must contain exactly one tab character that separates two values: the first is obfuscated name and the second is original one. No duplications in either original or obfuscated names are allowed.

**Elements:**

`rule`:
Expand Down

0 comments on commit 332d9e0

Please sign in to comment.