Skip to content

Commit 7c944b2

Browse files
authored
Merge e9632e3 into 9b8615e
2 parents 9b8615e + e9632e3 commit 7c944b2

File tree

13 files changed

+236
-138
lines changed

13 files changed

+236
-138
lines changed

Confuser.Core/CoreComponent.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.IO;
23
using Confuser.Core.API;
34
using Confuser.Core.Services;
45

@@ -37,6 +38,9 @@ public class CoreComponent : ConfuserComponent {
3738
/// </summary>
3839
public const string _APIStoreId = "Confuser.APIStore";
3940

41+
public const string SymbolsFileName = "symbols.map";
42+
public const string SeedFileName = "seed";
43+
4044
readonly Marker marker;
4145
readonly ConfuserContext _context;
4246

@@ -72,7 +76,15 @@ public override string FullId {
7276

7377
/// <inheritdoc />
7478
protected internal override void Initialize(ConfuserContext context) {
75-
context.Registry.RegisterService(_RandomServiceId, typeof(IRandomService), new RandomService(_context.Project.Seed));
79+
var projectSeed = _context.Project.Seed;
80+
string actualSeed = projectSeed ?? Guid.NewGuid().ToString();
81+
string dir = context.OutputDirectory;
82+
string path = Path.GetFullPath(Path.Combine(dir, SeedFileName));
83+
if (!Directory.Exists(dir))
84+
Directory.CreateDirectory(dir);
85+
File.WriteAllText(path, actualSeed);
86+
87+
context.Registry.RegisterService(_RandomServiceId, typeof(IRandomService), new RandomService(actualSeed));
7688
context.Registry.RegisterService(_MarkerServiceId, typeof(IMarkerService), new MarkerService(context, marker));
7789
context.Registry.RegisterService(_TraceServiceId, typeof(ITraceService), new TraceService());
7890
context.Registry.RegisterService(_RuntimeServiceId, typeof(IRuntimeService), new RuntimeService());

Confuser.Core/Services/RandomService.cs

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,8 @@ internal RandomGenerator(byte[] seed) {
3535
/// </summary>
3636
/// <param name="seed">The seed data.</param>
3737
/// <returns>The seed buffer.</returns>
38-
internal static byte[] Seed(string seed) {
39-
byte[] ret;
40-
if (!string.IsNullOrEmpty(seed))
41-
ret = Utils.SHA256(Encoding.UTF8.GetBytes(seed));
42-
else
43-
ret = Utils.SHA256(Guid.NewGuid().ToByteArray());
44-
45-
for (int i = 0; i < 32; i++) {
46-
ret[i] *= primes[i % primes.Length];
47-
ret = Utils.SHA256(ret);
48-
}
49-
return ret;
50-
}
38+
internal static byte[] Seed(string seed) =>
39+
Utils.SHA256(seed != null ? Encoding.UTF8.GetBytes(seed) : Guid.NewGuid().ToByteArray());
5140

5241
/// <summary>
5342
/// Refills the state buffer.
@@ -224,23 +213,22 @@ public void Shuffle<T>(MDTable<T> table) where T : struct {
224213
internal class RandomService : IRandomService {
225214
readonly byte[] seed; //32 bytes
226215

216+
public string SeedString { get; }
217+
227218
/// <summary>
228219
/// Initializes a new instance of the <see cref="RandomService" /> class.
229220
/// </summary>
230221
/// <param name="seed">The project seed.</param>
231222
public RandomService(string seed) {
223+
SeedString = seed;
232224
this.seed = RandomGenerator.Seed(seed);
233225
}
234226

235227
/// <inheritdoc />
236228
public RandomGenerator GetRandomGenerator(string id) {
237229
if (string.IsNullOrEmpty(id))
238230
throw new ArgumentNullException("id");
239-
byte[] newSeed = seed;
240-
byte[] idHash = Utils.SHA256(Encoding.UTF8.GetBytes(id));
241-
for (int i = 0; i < 32; i++)
242-
newSeed[i] ^= idHash[i];
243-
return new RandomGenerator(Utils.SHA256(newSeed));
231+
return new RandomGenerator(Utils.SHA256(Encoding.UTF8.GetBytes($"{SeedString}-{id}")));
244232
}
245233
}
246234

@@ -255,5 +243,7 @@ public interface IRandomService {
255243
/// <returns>The requested RNG.</returns>
256244
/// <exception cref="System.ArgumentNullException"><paramref name="id" /> is <c>null</c>.</exception>
257245
RandomGenerator GetRandomGenerator(string id);
246+
247+
string SeedString { get; }
258248
}
259249
}

Confuser.Renamer/AnalyzePhase.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections.Generic;
22
using System.Linq;
33
using Confuser.Core;
4+
using Confuser.Core.Services;
45
using Confuser.Renamer.Analyzers;
56
using dnlib.DotNet;
67

@@ -147,9 +148,12 @@ internal void Analyze(NameService service, ConfuserContext context, ProtectionPa
147148
else if (def is EventDef)
148149
Analyze(service, context, parameters, (EventDef)def);
149150
else if (def is ModuleDef) {
150-
var pass = parameters.GetParameter<string>(context, def, "password", null);
151-
if (pass != null)
152-
service.reversibleRenamer = new ReversibleRenamer(pass);
151+
var password = parameters.GetParameter<string>(context, def, "password");
152+
if (password != null) {
153+
var randomService = context.Registry.GetService<IRandomService>();
154+
service.reversibleRenamer = new ReversibleRenamer(password, randomService.SeedString);
155+
}
156+
153157
service.SetCanRename(def, false);
154158
}
155159

Confuser.Renamer/MessageDeobfuscator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public static MessageDeobfuscator Load(string symbolMapFileName) {
3232

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

35-
public MessageDeobfuscator(string password) => _renamer = new ReversibleRenamer(password);
35+
public MessageDeobfuscator(string password, string seed) => _renamer = new ReversibleRenamer(password, seed);
3636

3737
public string DeobfuscateMessage(string message) {
3838
if (_symbolMap != null) {

Confuser.Renamer/NameProtection.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.IO;
1+
using System.IO;
32
using Confuser.Core;
43

54
namespace Confuser.Renamer {
@@ -61,8 +60,8 @@ protected override void Execute(ConfuserContext context, ProtectionParameters pa
6160
if (map.Count == 0)
6261
return;
6362

64-
string path = Path.GetFullPath(Path.Combine(context.OutputDirectory, "symbols.map"));
65-
string dir = Path.GetDirectoryName(path);
63+
string dir = context.OutputDirectory;
64+
string path = Path.GetFullPath(Path.Combine(dir, CoreComponent.SymbolsFileName));
6665
if (!Directory.Exists(dir))
6766
Directory.CreateDirectory(dir);
6867

Confuser.Renamer/ReversibleRenamer.cs

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,25 @@
44
using System.Text;
55

66
namespace Confuser.Renamer {
7-
public class ReversibleRenamer {
8-
readonly RijndaelManaged cipher;
9-
readonly byte[] key;
10-
11-
public ReversibleRenamer(string password) {
12-
cipher = new RijndaelManaged();
13-
using (var sha = SHA256.Create())
14-
cipher.Key = key = sha.ComputeHash(Encoding.UTF8.GetBytes(password));
7+
public class ReversibleRenamer : IDisposable {
8+
readonly Aes cipher;
9+
readonly byte seedBytesHash;
10+
11+
public ReversibleRenamer(string password, string seed) {
12+
cipher = Aes.Create();
13+
using (var sha = SHA256.Create()) {
14+
cipher.Key = sha.ComputeHash(Encoding.UTF8.GetBytes(password + seed));
15+
seedBytesHash = GetDataHash(seed);
16+
}
1517
}
1618

1719
public string Encrypt(string name) {
18-
byte ivId = GetIVId(name);
19-
cipher.IV = GetIV(ivId);
20-
var buf = Encoding.UTF8.GetBytes(name);
21-
2220
using (var ms = new MemoryStream()) {
21+
byte ivId = GetDataHash(name);
2322
ms.WriteByte(ivId);
23+
cipher.IV = GenerateIV(ivId);
24+
25+
var buf = Encoding.UTF8.GetBytes(name);
2426
using (var stream = new CryptoStream(ms, cipher.CreateEncryptor(), CryptoStreamMode.Write)) {
2527
stream.Write(buf, 0, buf.Length);
2628
stream.FlushFinalBlock();
@@ -29,10 +31,10 @@ public string Encrypt(string name) {
2931
}
3032
}
3133

32-
public string Decrypt(string name) {
33-
using (var ms = new MemoryStream(Base64Decode(name))) {
34+
public string Decrypt(string encrypted) {
35+
using (var ms = new MemoryStream(Base64Decode(encrypted))) {
3436
byte ivId = (byte)ms.ReadByte();
35-
cipher.IV = GetIV(ivId);
37+
cipher.IV = GenerateIV(ivId);
3638

3739
using (var result = new MemoryStream()) {
3840
using (var stream = new CryptoStream(ms, cipher.CreateDecryptor(), CryptoStreamMode.Read))
@@ -42,20 +44,24 @@ public string Decrypt(string name) {
4244
}
4345
}
4446

45-
byte[] GetIV(byte ivId) {
47+
byte GetDataHash(string str) {
48+
byte hash = 0;
49+
if (str.Length > 0) {
50+
hash = (byte)str[0];
51+
for (int i = 1; i < str.Length; i++)
52+
hash = (byte)(hash * 3 + (byte)str[i]);
53+
}
54+
55+
return (byte)(hash ^ seedBytesHash);
56+
}
57+
58+
byte[] GenerateIV(byte dataHash) {
4659
byte[] iv = new byte[cipher.BlockSize / 8];
4760
for (int i = 0; i < iv.Length; i++)
48-
iv[i] = (byte)(ivId ^ key[i]);
61+
iv[i] = dataHash;
4962
return iv;
5063
}
5164

52-
byte GetIVId(string str) {
53-
byte x = (byte)str[0];
54-
for (int i = 1; i < str.Length; i++)
55-
x = (byte)(x * 3 + (byte)str[i]);
56-
return x;
57-
}
58-
5965
static string Base64Encode(byte[] buffer, int length) {
6066
int inputUnpaddedLength = 4 * length / 3;
6167
var outArray = new char[(inputUnpaddedLength + 3) & ~3];
@@ -99,5 +105,7 @@ static byte[] Base64Decode(string str) {
99105

100106
return Convert.FromBase64CharArray(inArray, 0, inArray.Length);
101107
}
108+
109+
public void Dispose() => cipher?.Dispose();
102110
}
103111
}

ConfuserEx/StackTraceDecoder.xaml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,20 @@
3030
<TextBox x:Name="PathBox" Grid.Row="1" Grid.Column="1" Margin="5" VerticalContentAlignment="Center"
3131
local:FileDragDrop.Command="{x:Static local:FileDragDrop.FileCmd}" />
3232
</DockPanel>
33-
<DockPanel Grid.Row="0" Grid.Column="1" Visibility="{Binding IsChecked, ElementName=optPass, Converter={x:Static local:BoolToVisibilityConverter.Instance}}">
34-
<Label DockPanel.Dock="Left" VerticalAlignment="Center" HorizontalAlignment="Right">Password:</Label>
35-
<PasswordBox x:Name="PassBox" Margin="5" VerticalContentAlignment="Center"/>
36-
</DockPanel>
33+
<Grid Grid.Row="0" Grid.Column="1" Visibility="{Binding IsChecked, ElementName=optPass, Converter={x:Static local:BoolToVisibilityConverter.Instance}}">
34+
<Grid.ColumnDefinitions>
35+
<ColumnDefinition Width="*"/>
36+
<ColumnDefinition Width="*"/>
37+
</Grid.ColumnDefinitions>
38+
<DockPanel Grid.Column="0" >
39+
<Label DockPanel.Dock="Left" VerticalAlignment="Center" HorizontalAlignment="Right">Password:</Label>
40+
<PasswordBox x:Name="PassBox" Margin="5" VerticalContentAlignment="Center" HorizontalAlignment="Stretch" />
41+
</DockPanel>
42+
<DockPanel Grid.Column="1">
43+
<Label DockPanel.Dock="Left" VerticalAlignment="Center" HorizontalAlignment="Right">Seed:</Label>
44+
<TextBox x:Name="SeedBox" Margin="5" VerticalContentAlignment="Center" HorizontalAlignment="Stretch" />
45+
</DockPanel>
46+
</Grid>
3747
<DockPanel Grid.Row="1" Grid.Column="1">
3848
<Button DockPanel.Dock="Right" Margin="5" Padding="10,0,10,0" Click="Decode_Click" IsDefault="True">Decode!</Button>
3949
<Label x:Name="status" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5,2,10,2" />

ConfuserEx/StackTraceDecoder.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ void Decode_Click(object sender, RoutedEventArgs e) {
3737
}
3838
}
3939
else {
40-
_messageDeobfuscator = new MessageDeobfuscator(PassBox.Password);
40+
_messageDeobfuscator = new MessageDeobfuscator(PassBox.Password, SeedBox.Text);
4141
}
4242

4343
if (!error) {

ConfuserEx/ViewModel/Project/ProjectVM.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Collections.ObjectModel;
44
using System.Reflection;
5+
using System.Windows;
56
using Confuser.Core;
67
using Confuser.Core.Project;
78

@@ -47,9 +48,20 @@ public bool IsModified {
4748
set { SetProperty(ref modified, value, "IsModified"); }
4849
}
4950

51+
public bool IsRandomSeed {
52+
get => proj.Seed == null;
53+
set {
54+
Seed = value ? null : "";
55+
OnPropertyChanged(nameof(IsSeedEnabled));
56+
OnPropertyChanged(nameof(IsRandomSeed));
57+
}
58+
}
59+
60+
public Visibility IsSeedEnabled => proj.Seed != null ? Visibility.Visible : Visibility.Collapsed;
61+
5062
public string Seed {
51-
get { return proj.Seed; }
52-
set { SetProperty(proj.Seed != value, val => proj.Seed = val, value, "Seed"); }
63+
get => proj.Seed;
64+
set => SetProperty(proj.Seed != value, val => proj.Seed = val, value, "Seed");
5365
}
5466

5567
public bool Debug {

ConfuserEx/Views/ProjectTabView.xaml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,18 @@
4040
<Grid Grid.Row="2" Grid.ColumnSpan="3">
4141
<Grid.ColumnDefinitions>
4242
<ColumnDefinition Width="150px" />
43+
<ColumnDefinition Width="Auto" />
4344
<ColumnDefinition Width="*" />
4445
<ColumnDefinition Width="Auto" />
4546
</Grid.ColumnDefinitions>
4647
<Label Content="Seed : " Grid.Column="0" HorizontalContentAlignment="Right"
4748
VerticalContentAlignment="Center" />
48-
<TextBox Grid.Column="1" Margin="5" VerticalContentAlignment="Center"
49+
<CheckBox Grid.Column="1" Name="isRandomSeed" Content="Random" VerticalAlignment="Center" Margin="5"
50+
IsChecked="{Binding App.Project.IsRandomSeed, Mode=TwoWay}"/>
51+
<TextBox Grid.Column="2" Margin="5" VerticalContentAlignment="Center"
4952
Text="{Binding App.Project.Seed, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
50-
local:Skin.EmptyPrompt="Leave blank for random seed" />
51-
<CheckBox Grid.Column="2" Content="Generate Debug Symbols" VerticalAlignment="Center" Margin="5"
53+
Visibility="{Binding App.Project.IsSeedEnabled}" />
54+
<CheckBox Grid.Column="3" Content="Generate Debug Symbols" VerticalAlignment="Center" Margin="5"
5255
IsChecked="{Binding App.Project.Debug, Mode=TwoWay}" />
5356
</Grid>
5457

@@ -61,8 +64,8 @@
6164
<DataTemplate DataType="{x:Type vm:ProjectModuleVM}">
6265
<Grid>
6366
<Grid.InputBindings>
64-
<MouseBinding Gesture="LeftDoubleClick"
65-
Command="{Binding DataContext.Edit, ElementName=PART_ProjectTabGrid}"
67+
<MouseBinding Gesture="LeftDoubleClick"
68+
Command="{Binding DataContext.Edit, ElementName=PART_ProjectTabGrid}"
6669
CommandParameter="{Binding}" />
6770
</Grid.InputBindings>
6871
<Grid.ColumnDefinitions>

0 commit comments

Comments
 (0)