added basic anti tamper protection
This commit is contained in:
Родитель
d67c52e5b5
Коммит
e4a0f790cd
|
@ -107,7 +107,12 @@ namespace Confuser.Core
|
|||
return defValue;
|
||||
if (!objAnno.Contains(key))
|
||||
return defValue;
|
||||
return (TValue)Convert.ChangeType(objAnno[key], typeof(TValue));
|
||||
|
||||
var valueType = typeof(TValue);
|
||||
if (valueType.IsValueType)
|
||||
return (TValue)Convert.ChangeType(objAnno[key], typeof(TValue));
|
||||
else
|
||||
return (TValue)objAnno[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -133,7 +138,12 @@ namespace Confuser.Core
|
|||
return defValueFactory(key);
|
||||
if (!objAnno.Contains(key))
|
||||
return defValueFactory(key);
|
||||
return (TValue)Convert.ChangeType(objAnno[key], typeof(TValue));
|
||||
|
||||
var valueType = typeof(TValue);
|
||||
if (valueType.IsValueType)
|
||||
return (TValue)Convert.ChangeType(objAnno[key], typeof(TValue));
|
||||
else
|
||||
return (TValue)objAnno[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -159,7 +169,13 @@ namespace Confuser.Core
|
|||
objAnno = annotations[new WeakReferenceKey(obj)] = new ListDictionary();
|
||||
TValue ret;
|
||||
if (objAnno.Contains(key))
|
||||
ret = (TValue)Convert.ChangeType(objAnno[key], typeof(TValue));
|
||||
{
|
||||
var valueType = typeof(TValue);
|
||||
if (valueType.IsValueType)
|
||||
return (TValue)Convert.ChangeType(objAnno[key], typeof(TValue));
|
||||
else
|
||||
return (TValue)objAnno[key];
|
||||
}
|
||||
else
|
||||
objAnno[key] = ret = factory(key);
|
||||
return ret;
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Confuser.Core;
|
||||
using Confuser.Protections.AntiTamper;
|
||||
using dnlib.DotNet;
|
||||
|
||||
namespace Confuser.Protections
|
||||
{
|
||||
[BeforeProtection("Ki.ControlFlow"), AfterProtection("Ki.Constants")]
|
||||
class AntiTamperProtection : Protection
|
||||
{
|
||||
public const string _Id = "anti tamper";
|
||||
public const string _FullId = "Ki.AntiTamper";
|
||||
public const string _ServiceId = "Ki.AntiTamper";
|
||||
|
||||
protected override void Initialize(ConfuserContext context)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
protected override void PopulatePipeline(ProtectionPipeline pipeline)
|
||||
{
|
||||
pipeline.InsertPreStage(PipelineStage.OptimizeMethods, new InjectPhase(this));
|
||||
pipeline.InsertPreStage(PipelineStage.EndModule, new MDPhase(this));
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Anti Tamper Protection"; }
|
||||
}
|
||||
|
||||
public override string Description
|
||||
{
|
||||
get { return "This protection ensures the integrity of application."; }
|
||||
}
|
||||
|
||||
public override string Id
|
||||
{
|
||||
get { return _Id; }
|
||||
}
|
||||
|
||||
public override string FullId
|
||||
{
|
||||
get { return _FullId; }
|
||||
}
|
||||
|
||||
public override ProtectionPreset Preset
|
||||
{
|
||||
get { return ProtectionPreset.Maximum; }
|
||||
}
|
||||
|
||||
public void ExcludeMethod(ConfuserContext context, MethodDef method)
|
||||
{
|
||||
ProtectionParameters.GetParameters(context, method).Remove(this);
|
||||
}
|
||||
|
||||
static readonly object HandlerKey = new object();
|
||||
|
||||
enum Mode
|
||||
{
|
||||
Normal,
|
||||
JIT
|
||||
}
|
||||
|
||||
class InjectPhase : ProtectionPhase
|
||||
{
|
||||
public InjectPhase(AntiTamperProtection parent)
|
||||
: base(parent)
|
||||
{
|
||||
}
|
||||
|
||||
public override ProtectionTargets Targets
|
||||
{
|
||||
get { return ProtectionTargets.Modules; }
|
||||
}
|
||||
|
||||
protected override void Execute(ConfuserContext context, ProtectionParameters parameters)
|
||||
{
|
||||
Mode mode = parameters.GetParameter<Mode>(context, context.CurrentModule, "mode", Mode.Normal);
|
||||
IModeHandler modeHandler;
|
||||
switch (mode)
|
||||
{
|
||||
case Mode.Normal:
|
||||
modeHandler = new NormalMode();
|
||||
break;
|
||||
default:
|
||||
throw new UnreachableException();
|
||||
}
|
||||
modeHandler.HandleInject((AntiTamperProtection)Parent, context, parameters);
|
||||
context.Annotations.Set(context.CurrentModule, HandlerKey, modeHandler);
|
||||
}
|
||||
}
|
||||
|
||||
class MDPhase : ProtectionPhase
|
||||
{
|
||||
public MDPhase(AntiTamperProtection parent)
|
||||
: base(parent)
|
||||
{
|
||||
}
|
||||
|
||||
public override ProtectionTargets Targets
|
||||
{
|
||||
get { return ProtectionTargets.Methods; }
|
||||
}
|
||||
|
||||
protected override void Execute(ConfuserContext context, ProtectionParameters parameters)
|
||||
{
|
||||
var modeHandler = context.Annotations.Get<IModeHandler>(context.CurrentModule, HandlerKey);
|
||||
modeHandler.HandleMD((AntiTamperProtection)Parent, context, parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using dnlib.DotNet.Emit;
|
||||
using dnlib.DotNet;
|
||||
using Confuser.Core.Helpers;
|
||||
using Confuser.Core;
|
||||
using Confuser.DynCipher;
|
||||
using System.Diagnostics;
|
||||
using Confuser.DynCipher.AST;
|
||||
using Confuser.DynCipher.Generation;
|
||||
using Confuser.Core.Services;
|
||||
|
||||
namespace Confuser.Protections.AntiTamper
|
||||
{
|
||||
class DynamicDeriver : IKeyDeriver
|
||||
{
|
||||
class CodeGen : CILCodeGen
|
||||
{
|
||||
Local block;
|
||||
Local key;
|
||||
public CodeGen(Local block, Local key, MethodDef method, IList<Instruction> instrs)
|
||||
: base(method, instrs)
|
||||
{
|
||||
this.block = block;
|
||||
this.key = key;
|
||||
}
|
||||
protected override Local Var(Variable var)
|
||||
{
|
||||
if (var.Name == "{BUFFER}")
|
||||
return block;
|
||||
else if (var.Name == "{KEY}")
|
||||
return key;
|
||||
else
|
||||
return base.Var(var);
|
||||
}
|
||||
}
|
||||
|
||||
StatementBlock derivation;
|
||||
Action<uint[], uint[]> encryptFunc;
|
||||
|
||||
public void Init(ConfuserContext ctx, RandomGenerator random)
|
||||
{
|
||||
StatementBlock dummy;
|
||||
ctx.Registry.GetService<IDynCipherService>().GenerateCipherPair(random, out derivation, out dummy);
|
||||
|
||||
var dmCodeGen = new DMCodeGen(typeof(void), new[] {
|
||||
Tuple.Create("{BUFFER}", typeof(uint[])),
|
||||
Tuple.Create("{KEY}", typeof(uint[]))
|
||||
});
|
||||
dmCodeGen.GenerateCIL(derivation);
|
||||
encryptFunc = dmCodeGen.Compile<Action<uint[], uint[]>>();
|
||||
}
|
||||
|
||||
public uint[] DeriveKey(uint[] a, uint[] b)
|
||||
{
|
||||
uint[] ret = new uint[0x10];
|
||||
Buffer.BlockCopy(a, 0, ret, 0, a.Length * sizeof(uint));
|
||||
encryptFunc(ret, b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public IEnumerable<Instruction> EmitDerivation(MethodDef method, ConfuserContext ctx, Local dst, Local src)
|
||||
{
|
||||
var ret = new List<Instruction>();
|
||||
var codeGen = new CodeGen(dst, src, method, ret);
|
||||
codeGen.GenerateCIL(derivation);
|
||||
codeGen.Commit(method.Body);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using dnlib.DotNet;
|
||||
using Confuser.Core;
|
||||
using dnlib.DotNet.Emit;
|
||||
using Confuser.Core.Services;
|
||||
|
||||
namespace Confuser.Protections.AntiTamper
|
||||
{
|
||||
enum Mode
|
||||
{
|
||||
Normal,
|
||||
Dynamic
|
||||
}
|
||||
interface IKeyDeriver
|
||||
{
|
||||
void Init(ConfuserContext ctx, RandomGenerator random);
|
||||
uint[] DeriveKey(uint[] a, uint[] b);
|
||||
IEnumerable<Instruction> EmitDerivation(MethodDef method, ConfuserContext ctx, Local dst, Local src);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Confuser.Core;
|
||||
|
||||
namespace Confuser.Protections.AntiTamper
|
||||
{
|
||||
interface IModeHandler
|
||||
{
|
||||
void HandleInject(AntiTamperProtection parent, ConfuserContext context, ProtectionParameters parameters);
|
||||
void HandleMD(AntiTamperProtection parent, ConfuserContext context, ProtectionParameters parameters);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using dnlib.DotNet;
|
||||
using Confuser.Core;
|
||||
using dnlib.DotNet.Emit;
|
||||
using Confuser.Core.Services;
|
||||
|
||||
namespace Confuser.Protections.AntiTamper
|
||||
{
|
||||
class NormalDeriver : IKeyDeriver
|
||||
{
|
||||
public void Init(ConfuserContext ctx, RandomGenerator random)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public uint[] DeriveKey(uint[] a, uint[] b)
|
||||
{
|
||||
uint[] ret = new uint[0x10];
|
||||
for (int i = 0; i < 0x10; i++)
|
||||
{
|
||||
switch (i % 3)
|
||||
{
|
||||
case 0:
|
||||
ret[i] = a[i] ^ b[i];
|
||||
break;
|
||||
case 1:
|
||||
ret[i] = a[i] * b[i];
|
||||
break;
|
||||
case 2:
|
||||
ret[i] = a[i] + b[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public IEnumerable<Instruction> EmitDerivation(MethodDef method, ConfuserContext ctx, Local dst, Local src)
|
||||
{
|
||||
for (int i = 0; i < 0x10; i++)
|
||||
{
|
||||
yield return Instruction.Create(OpCodes.Ldloc, dst);
|
||||
yield return Instruction.Create(OpCodes.Ldc_I4, i);
|
||||
yield return Instruction.Create(OpCodes.Ldloc, dst);
|
||||
yield return Instruction.Create(OpCodes.Ldc_I4, i);
|
||||
yield return Instruction.Create(OpCodes.Ldelem_U4);
|
||||
yield return Instruction.Create(OpCodes.Ldloc, src);
|
||||
yield return Instruction.Create(OpCodes.Ldc_I4, i);
|
||||
yield return Instruction.Create(OpCodes.Ldelem_U4);
|
||||
switch (i % 3)
|
||||
{
|
||||
case 0:
|
||||
yield return Instruction.Create(OpCodes.Xor);
|
||||
break;
|
||||
case 1:
|
||||
yield return Instruction.Create(OpCodes.Mul);
|
||||
break;
|
||||
case 2:
|
||||
yield return Instruction.Create(OpCodes.Add);
|
||||
break;
|
||||
}
|
||||
yield return Instruction.Create(OpCodes.Stelem_I4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,260 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Confuser.Core;
|
||||
using Confuser.Core.Services;
|
||||
using Confuser.Core.Helpers;
|
||||
using dnlib.DotNet.Emit;
|
||||
using Confuser.Renamer;
|
||||
using dnlib.DotNet;
|
||||
using System.Diagnostics;
|
||||
using dnlib.DotNet.Writer;
|
||||
using System.IO;
|
||||
|
||||
namespace Confuser.Protections.AntiTamper
|
||||
{
|
||||
class NormalMode : IModeHandler
|
||||
{
|
||||
RandomGenerator random;
|
||||
uint z, x, c, v;
|
||||
uint name1, name2;
|
||||
IKeyDeriver deriver;
|
||||
|
||||
List<MethodDef> methods;
|
||||
public void HandleInject(AntiTamperProtection parent, ConfuserContext context, ProtectionParameters parameters)
|
||||
{
|
||||
random = context.Registry.GetService<IRandomService>().GetRandomGenerator(parent.FullId);
|
||||
z = random.NextUInt32();
|
||||
x = random.NextUInt32();
|
||||
c = random.NextUInt32();
|
||||
v = random.NextUInt32();
|
||||
name1 = random.NextUInt32() & 0x7f7f7f7f;
|
||||
name2 = random.NextUInt32() & 0x7f7f7f7f;
|
||||
|
||||
switch (parameters.GetParameter<Mode>(context, context.CurrentModule, "key", Mode.Normal))
|
||||
{
|
||||
case Mode.Normal:
|
||||
deriver = new NormalDeriver();
|
||||
break;
|
||||
case Mode.Dynamic:
|
||||
deriver = new DynamicDeriver();
|
||||
break;
|
||||
default:
|
||||
throw new UnreachableException();
|
||||
}
|
||||
deriver.Init(context, random);
|
||||
|
||||
var rt = context.Registry.GetService<IRuntimeService>();
|
||||
var initMethod = rt.GetRuntimeType("Confuser.Runtime.AntiTamperNormal").FindMethod("Initialize");
|
||||
initMethod = InjectHelper.Inject(initMethod, context.CurrentModule);
|
||||
context.CurrentModule.GlobalType.Methods.Add(initMethod);
|
||||
|
||||
var instrs = initMethod.Body.Instructions.ToList();
|
||||
for (int i = 0; i < instrs.Count; i++)
|
||||
{
|
||||
var instr = instrs[i];
|
||||
if (instr.OpCode == OpCodes.Ldtoken)
|
||||
{
|
||||
instr.Operand = context.CurrentModule.GlobalType;
|
||||
}
|
||||
else if (instr.OpCode == OpCodes.Call)
|
||||
{
|
||||
IMethod method = (IMethod)instr.Operand;
|
||||
if (method.DeclaringType.Name == "Mutation" &&
|
||||
method.Name == "Crypt")
|
||||
{
|
||||
Instruction ldDst = instrs[i - 2];
|
||||
Instruction ldSrc = instrs[i - 1];
|
||||
Debug.Assert(ldDst.OpCode == OpCodes.Ldloc && ldSrc.OpCode == OpCodes.Ldloc);
|
||||
instrs.RemoveAt(i);
|
||||
instrs.RemoveAt(i - 1);
|
||||
instrs.RemoveAt(i - 2);
|
||||
instrs.InsertRange(i - 2, deriver.EmitDerivation(initMethod, context, (Local)ldDst.Operand, (Local)ldSrc.Operand));
|
||||
}
|
||||
}
|
||||
}
|
||||
initMethod.Body.Instructions.Clear();
|
||||
foreach (var instr in instrs)
|
||||
initMethod.Body.Instructions.Add(instr);
|
||||
|
||||
MutationHelper.InjectKeys(initMethod,
|
||||
new int[] { 0, 1, 2, 3, 4 },
|
||||
new int[] { (int)(name1 * name2), (int)z, (int)x, (int)c, (int)v });
|
||||
|
||||
var name = context.Registry.GetService<INameService>();
|
||||
var marker = context.Registry.GetService<IMarkerService>();
|
||||
name.MarkHelper(initMethod, marker);
|
||||
|
||||
var cctor = context.CurrentModule.GlobalType.FindStaticConstructor();
|
||||
cctor.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, initMethod));
|
||||
|
||||
parent.ExcludeMethod(context, cctor);
|
||||
parent.ExcludeMethod(context, initMethod);
|
||||
}
|
||||
|
||||
public void HandleMD(AntiTamperProtection parent, ConfuserContext context, ProtectionParameters parameters)
|
||||
{
|
||||
methods = parameters.Targets.OfType<MethodDef>().ToList();
|
||||
context.CurrentModuleWriterListener.OnWriterEvent += OnWriterEvent;
|
||||
}
|
||||
|
||||
void OnWriterEvent(object sender, ModuleWriterListenerEventArgs e)
|
||||
{
|
||||
var writer = (ModuleWriter)sender;
|
||||
if (e.WriterEvent == ModuleWriterEvent.MDEndCreateTables)
|
||||
{
|
||||
CreateSections(writer);
|
||||
}
|
||||
else if (e.WriterEvent == ModuleWriterEvent.BeginStrongNameSign)
|
||||
{
|
||||
EncryptSection(writer);
|
||||
}
|
||||
}
|
||||
|
||||
void CreateSections(ModuleWriter writer)
|
||||
{
|
||||
byte[] nameBuffer = new byte[8];
|
||||
nameBuffer[0] = (byte)(name1 >> 0);
|
||||
nameBuffer[1] = (byte)(name1 >> 8);
|
||||
nameBuffer[2] = (byte)(name1 >> 16);
|
||||
nameBuffer[3] = (byte)(name1 >> 24);
|
||||
nameBuffer[4] = (byte)(name2 >> 0);
|
||||
nameBuffer[5] = (byte)(name2 >> 8);
|
||||
nameBuffer[6] = (byte)(name2 >> 16);
|
||||
nameBuffer[7] = (byte)(name2 >> 24);
|
||||
var newSection = new PESection(Encoding.ASCII.GetString(nameBuffer), 0xE0000040);
|
||||
writer.Sections.Insert(0, newSection); // insert first to ensure proper RVA
|
||||
|
||||
uint alignment;
|
||||
|
||||
alignment = writer.TextSection.Remove(writer.MetaData).Value;
|
||||
writer.TextSection.Add(writer.MetaData, alignment);
|
||||
|
||||
alignment = writer.TextSection.Remove(writer.NetResources).Value;
|
||||
writer.TextSection.Add(writer.NetResources, alignment);
|
||||
|
||||
alignment = writer.TextSection.Remove(writer.Constants).Value;
|
||||
newSection.Add(writer.Constants, alignment);
|
||||
|
||||
// move some PE parts to separate section to prevent it from being hashed
|
||||
var peSection = new PESection("", 0x60000020);
|
||||
bool moved = false;
|
||||
if (writer.StrongNameSignature != null)
|
||||
{
|
||||
alignment = writer.TextSection.Remove(writer.StrongNameSignature).Value;
|
||||
peSection.Add(writer.StrongNameSignature, alignment);
|
||||
moved = true;
|
||||
}
|
||||
if (writer.ImportAddressTable != null)
|
||||
{
|
||||
alignment = writer.TextSection.Remove(writer.ImportAddressTable).Value;
|
||||
peSection.Add(writer.ImportAddressTable, alignment);
|
||||
moved = true;
|
||||
}
|
||||
if (writer.StartupStub != null)
|
||||
{
|
||||
alignment = writer.TextSection.Remove(writer.StartupStub).Value;
|
||||
peSection.Add(writer.StartupStub, alignment);
|
||||
moved = true;
|
||||
}
|
||||
if (moved)
|
||||
writer.Sections.Add(peSection);
|
||||
|
||||
// move encrypted methods
|
||||
var encryptedChunk = new MethodBodyChunks(writer.TheOptions.ShareMethodBodies);
|
||||
newSection.Add(encryptedChunk, 4);
|
||||
foreach (var method in methods)
|
||||
{
|
||||
if (!method.HasBody)
|
||||
continue;
|
||||
var body = writer.MetaData.GetMethodBody(method);
|
||||
var ok = writer.MethodBodies.Remove(body);
|
||||
encryptedChunk.Add(body);
|
||||
}
|
||||
|
||||
// padding to prevent bad size due to shift division
|
||||
newSection.Add(new ByteArrayChunk(new byte[4]), 4);
|
||||
}
|
||||
|
||||
void EncryptSection(ModuleWriter writer)
|
||||
{
|
||||
var stream = writer.DestinationStream;
|
||||
var reader = new BinaryReader(writer.DestinationStream);
|
||||
stream.Position = 0x3C;
|
||||
stream.Position = reader.ReadUInt32();
|
||||
|
||||
stream.Position += 6;
|
||||
ushort sections = reader.ReadUInt16();
|
||||
stream.Position += 0xc;
|
||||
ushort optSize = reader.ReadUInt16();
|
||||
stream.Position += 2 + optSize;
|
||||
|
||||
uint encLoc = 0, encSize = 0;
|
||||
for (int i = 0; i < sections; i++)
|
||||
{
|
||||
uint nameHash = reader.ReadUInt32() * reader.ReadUInt32();
|
||||
stream.Position += 8;
|
||||
if (nameHash == name1 * name2)
|
||||
{
|
||||
encSize = reader.ReadUInt32();
|
||||
encLoc = reader.ReadUInt32();
|
||||
}
|
||||
else if (nameHash != 0)
|
||||
{
|
||||
uint sectSize = reader.ReadUInt32();
|
||||
uint sectLoc = reader.ReadUInt32();
|
||||
Hash(stream, reader, sectLoc, sectSize);
|
||||
}
|
||||
stream.Position += 16;
|
||||
}
|
||||
|
||||
uint[] key = DeriveKey();
|
||||
encSize >>= 2;
|
||||
stream.Position = encLoc;
|
||||
uint[] result = new uint[encSize];
|
||||
for (uint i = 0; i < encSize; i++)
|
||||
{
|
||||
uint data = reader.ReadUInt32();
|
||||
result[i] = data ^ key[i & 0xf];
|
||||
key[i & 0xf] = (key[i & 0xf] ^ data) + 0x3dbb2819;
|
||||
}
|
||||
byte[] byteResult = new byte[encSize << 2];
|
||||
Buffer.BlockCopy(result, 0, byteResult, 0, byteResult.Length);
|
||||
stream.Position = encLoc;
|
||||
stream.Write(byteResult, 0, byteResult.Length);
|
||||
}
|
||||
|
||||
void Hash(Stream stream, BinaryReader reader, uint offset, uint size)
|
||||
{
|
||||
long original = stream.Position;
|
||||
stream.Position = offset;
|
||||
size >>= 2;
|
||||
for (uint i = 0; i < size; i++)
|
||||
{
|
||||
uint data = reader.ReadUInt32();
|
||||
uint tmp = (z ^ data) + x + c * v;
|
||||
z = x;
|
||||
x = c;
|
||||
x = v;
|
||||
v = tmp;
|
||||
}
|
||||
stream.Position = original;
|
||||
}
|
||||
|
||||
uint[] DeriveKey()
|
||||
{
|
||||
uint[] dst = new uint[0x10], src = new uint[0x10];
|
||||
for (int i = 0; i < 0x10; i++)
|
||||
{
|
||||
dst[i] = v;
|
||||
src[i] = x;
|
||||
z = (x >> 5) | (x << 27);
|
||||
x = (c >> 3) | (c << 29);
|
||||
c = (v >> 7) | (v << 25);
|
||||
v = (z >> 11) | (z << 21);
|
||||
}
|
||||
return deriver.DeriveKey(dst, src);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,6 +43,12 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AntiILDasmProtection.cs" />
|
||||
<Compile Include="AntiTamper\AntiTamperProtection.cs" />
|
||||
<Compile Include="AntiTamper\DynamicDeriver.cs" />
|
||||
<Compile Include="AntiTamper\IKeyDeriver.cs" />
|
||||
<Compile Include="AntiTamper\IModeHandler.cs" />
|
||||
<Compile Include="AntiTamper\NormalDeriver.cs" />
|
||||
<Compile Include="AntiTamper\NormalMode.cs" />
|
||||
<Compile Include="Constants\CEContext.cs" />
|
||||
<Compile Include="Constants\ConstantProtection.cs">
|
||||
<SubType>Code</SubType>
|
||||
|
|
|
@ -165,30 +165,6 @@ namespace Confuser.Protections
|
|||
0x7fff7fff, (uint)ManifestResourceAttributes.Private, 0x7fff7fff, 2));
|
||||
*/
|
||||
}
|
||||
else if (e.WriterEvent == ModuleWriterEvent.BeginCalculateRvasAndFileOffsets)
|
||||
{
|
||||
foreach (var section in writer.Sections)
|
||||
section.Name = "";
|
||||
}
|
||||
else if (e.WriterEvent == ModuleWriterEvent.ChunksAddedToSections)
|
||||
{
|
||||
var newSection = new PESection("", 0xE0000040);
|
||||
writer.Sections.Insert(0, newSection);
|
||||
|
||||
uint alignment;
|
||||
|
||||
alignment = writer.TextSection.Remove(writer.MetaData).Value;
|
||||
writer.TextSection.Add(writer.MetaData, alignment);
|
||||
|
||||
alignment = writer.TextSection.Remove(writer.NetResources).Value;
|
||||
writer.TextSection.Add(writer.NetResources, alignment);
|
||||
|
||||
alignment = writer.TextSection.Remove(writer.MethodBodies).Value;
|
||||
newSection.Add(writer.MethodBodies, alignment);
|
||||
|
||||
alignment = writer.TextSection.Remove(writer.Constants).Value;
|
||||
newSection.Add(writer.Constants, alignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Confuser.Runtime
|
||||
{
|
||||
class AntiTamperNormal
|
||||
{
|
||||
unsafe static void Initialize()
|
||||
{
|
||||
var m = typeof(AntiTamperNormal).Module;
|
||||
string n = m.FullyQualifiedName;
|
||||
bool f = n.Length > 0 && n[0] == '<';
|
||||
byte* b = (byte*)Marshal.GetHINSTANCE(m);
|
||||
byte* p = b + *(uint*)(b + 0x3c);
|
||||
ushort s = *(ushort*)(p + 0x6);
|
||||
ushort o = *(ushort*)(p + 0x14);
|
||||
|
||||
uint* e = null;
|
||||
uint l = 0;
|
||||
uint* r = (uint*)(p + 0x18 + o);
|
||||
uint z = (uint)Mutation.KeyI1, x = (uint)Mutation.KeyI2, c = (uint)Mutation.KeyI3, v = (uint)Mutation.KeyI4;
|
||||
for (int i = 0; i < s; i++)
|
||||
{
|
||||
uint g = (*r++) * (*r++);
|
||||
if (g == (uint)Mutation.KeyI0)
|
||||
{
|
||||
e = (uint*)(b + (f ? *(r + 3) : *(r + 1)));
|
||||
l = (f ? *(r + 2) : *(r + 0)) >> 2;
|
||||
}
|
||||
else if (g != 0)
|
||||
{
|
||||
uint* q = (uint*)(b + (f ? *(r + 3) : *(r + 1)));
|
||||
uint j = *(r + 2) >> 2;
|
||||
for (uint k = 0; k < j; k++)
|
||||
{
|
||||
uint t = (z ^ (*q++)) + x + c * v;
|
||||
z = x;
|
||||
x = c;
|
||||
x = v;
|
||||
v = t;
|
||||
}
|
||||
}
|
||||
r += 8;
|
||||
}
|
||||
|
||||
uint[] y = new uint[0x10], d = new uint[0x10];
|
||||
for (int i = 0; i < 0x10; i++)
|
||||
{
|
||||
y[i] = v;
|
||||
d[i] = x;
|
||||
z = (x >> 5) | (x << 27);
|
||||
x = (c >> 3) | (c << 29);
|
||||
c = (v >> 7) | (v << 25);
|
||||
v = (z >> 11) | (z << 21);
|
||||
}
|
||||
Mutation.Crypt(y, d);
|
||||
|
||||
uint h = 0;
|
||||
for (uint i = 0; i < l; i++)
|
||||
{
|
||||
*e ^= y[h & 0xf];
|
||||
y[h & 0xf] = (y[h & 0xf] ^ (*e++)) + 0x3dbb2819;
|
||||
h++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -48,6 +48,7 @@
|
|||
<Compile Include="RefProxy.Strong.cs" />
|
||||
<Compile Include="AntiDebug.Safe.cs" />
|
||||
<Compile Include="Resource.cs" />
|
||||
<Compile Include="AntiTamper.Normal.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
|
|
2
dnlib
2
dnlib
|
@ -1 +1 @@
|
|||
Subproject commit c0bdc93a2763f2fbc3dc46a68c40ca1c09ab5e2d
|
||||
Subproject commit 9d2bb28baffc35278696a9319cdf2ec0afc11111
|
Загрузка…
Ссылка в новой задаче