Skip to content

Commit 322c518

Browse files
author
RandomCrocodile
committed
feature: randomize compressor library-seed hash constants per run (#69)
The rolling hash that derives each embedded library's decryption seed from its name used fixed constants 0x6fff61 (init) and 0x5e3f1f (multiplier) in both PackModules and the injected runtime Resolve method — another de4dot signature. Generate a random init and a random odd multiplier per pack, use them in PackModules, and rewrite the literals in the runtime Resolve IL so the seed derivation stays in sync. Validated by CompressorWithResx.Test, whose 'de' satellite assembly is resolved+decrypted through this exact path at runtime (asserts 'Test (deutsch)' across all 12 cases).
1 parent 7d747ca commit 322c518

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

Confuser.Protections/Compress/Compressor.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ void PackModules(ConfuserContext context, CompressorContext compCtx, ModuleDef s
160160
for (int i = 0; i < name.Length; i++)
161161
name[i] *= key[i + 4];
162162

163-
uint state = 0x6fff61;
163+
uint state = compCtx.LcgInit;
164164
foreach (byte chr in name)
165-
state = state * 0x5e3f1f + chr;
165+
state = state * compCtx.LcgMultiplier + chr;
166166
byte[] encrypted = compCtx.Encrypt(comp, entry.Value, state, progress => {
167167
progress = (progress + moduleIndex) / modules.Count;
168168
context.ProgressReporter.Progress((int)(progress * 10000), 10000);
@@ -247,6 +247,12 @@ void InjectStub(ConfuserContext context, CompressorContext compCtx, ProtectionPa
247247
// the runtime Decrypt method below so encrypt/decrypt stay in sync.
248248
compCtx.Feedback = random.NextUInt32();
249249

250+
// Randomize the rolling-hash used to derive each library's seed from its name
251+
// (baked-in 0x6fff61 / 0x5e3f1f). The multiplier is kept odd for good distribution.
252+
// The same values are injected into the runtime Resolve method below.
253+
compCtx.LcgInit = random.NextUInt32();
254+
compCtx.LcgMultiplier = random.NextUInt32() | 1;
255+
250256
uint seed = random.NextUInt32();
251257
compCtx.OriginModule = context.OutputModules[compCtx.ModuleIndex];
252258

@@ -295,6 +301,18 @@ void InjectStub(ConfuserContext context, CompressorContext compCtx, ProtectionPa
295301
foreach (Instruction instr in instrs)
296302
decrypter.Body.Instructions.Add(instr);
297303

304+
// Resolve — sync the runtime rolling-hash constants with the values used when
305+
// deriving each library's seed from its name (see PackModules).
306+
MethodDef resolver = defs.OfType<MethodDef>().Single(method => method.Name == "Resolve");
307+
foreach (Instruction instr in resolver.Body.Instructions) {
308+
if (instr.OpCode != OpCodes.Ldc_I4)
309+
continue;
310+
if ((int)instr.Operand == 0x6fff61)
311+
instr.Operand = (int)compCtx.LcgInit;
312+
else if ((int)instr.Operand == 0x5e3f1f)
313+
instr.Operand = (int)compCtx.LcgMultiplier;
314+
}
315+
298316
// Pack modules
299317
PackModules(context, compCtx, stubModule, comp, random);
300318
}

Confuser.Protections/Compress/CompressorContext.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ internal class CompressorContext {
2020
public ModuleDef OriginModuleDef;
2121
public bool CompatMode;
2222
public uint Feedback;
23+
public uint LcgInit;
24+
public uint LcgMultiplier;
2325

2426
public byte[] Encrypt(ICompressionService compress, byte[] data, uint seed, Action<double> progressFunc) {
2527
data = (byte[])data.Clone();

0 commit comments

Comments
 (0)