Improved self-protection of Confuser runtime
This commit is contained in:
Родитель
56558b54f9
Коммит
7dd2eb75c3
|
@ -535,8 +535,9 @@ namespace Confuser.Core {
|
|||
targetBody.Variables.Add(local.Value);
|
||||
|
||||
// Nop the call
|
||||
int index = targetBody.Instructions.IndexOf(callInstruction);
|
||||
targetBody.Instructions[index++].OpCode = OpCodes.Nop;
|
||||
int index = targetBody.Instructions.IndexOf(callInstruction) + 1;
|
||||
callInstruction.OpCode = OpCodes.Nop;
|
||||
callInstruction.Operand = null;
|
||||
var afterIndex = targetBody.Instructions[index];
|
||||
|
||||
// Find Exception handler index
|
||||
|
|
|
@ -155,7 +155,7 @@ namespace Confuser.Core {
|
|||
|
||||
/// <summary>
|
||||
/// Returns a new string in which all occurrences of a specified string in
|
||||
/// <paramref name="str" /><paramref name="str" /> are replaced with another specified string.
|
||||
/// <paramref name="str" /> are replaced with another specified string.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string" /> equivalent to <paramref name="str" /> but with all instances of
|
||||
|
@ -233,4 +233,4 @@ namespace Confuser.Core {
|
|||
logger.EndProgress();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Confuser.Core;
|
||||
|
||||
namespace Confuser.Protections {
|
||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global", Justification = "Instantiated by reflection.")]
|
||||
internal sealed class HardeningComponent : ConfuserComponent {
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Protection Hardening";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Description => "This component improves the protection code, making it harder to circumvent it.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => "harden";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string FullId => "Cx.Harden";
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Initialize(ConfuserContext context) { }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void PopulatePipeline(ProtectionPipeline pipeline) =>
|
||||
pipeline.InsertPreStage(PipelineStage.OptimizeMethods, new HardeningPhase(this));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Confuser.Core;
|
||||
using Confuser.Core.Services;
|
||||
using dnlib.DotNet;
|
||||
using dnlib.DotNet.Emit;
|
||||
|
||||
namespace Confuser.Protections {
|
||||
internal sealed class HardeningPhase : ProtectionPhase {
|
||||
//private new HardeningComponent Parent => (HardeningComponent)base.Parent;
|
||||
|
||||
/// <inheritdoc />
|
||||
[SuppressMessage("ReSharper", "SuggestBaseTypeForParameter")]
|
||||
public HardeningPhase(HardeningComponent parent) : base(parent) { }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ProtectionTargets Targets => ProtectionTargets.Modules;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Hardening Phase";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool ProcessAll => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Execute(ConfuserContext context, ProtectionParameters parameters) {
|
||||
foreach (var module in parameters.Targets.OfType<ModuleDef>())
|
||||
HardenMethod(context, module);
|
||||
}
|
||||
|
||||
private static void HardenMethod(ConfuserContext context, ModuleDef module) {
|
||||
var cctor = module.GlobalType.FindStaticConstructor();
|
||||
if (cctor == null) {
|
||||
context.Logger.Debug("No .cctor containing protection code found. Nothing to do.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cctor.HasBody || !cctor.Body.HasInstructions) return;
|
||||
|
||||
var marker = context.Registry.GetService<IMarkerService>();
|
||||
var instructions = cctor.Body.Instructions;
|
||||
for (var i = instructions.Count - 1; i >= 0; i--) {
|
||||
if (instructions[i].OpCode.Code != Code.Call) continue;
|
||||
if (!(instructions[i].Operand is MethodDef targetMethod)) continue;
|
||||
if (!targetMethod.IsStatic || targetMethod.DeclaringType != module.GlobalType) continue;
|
||||
if (!marker.IsMarked(targetMethod) || !(marker.GetHelperParent(targetMethod) is Protection protection)) continue;
|
||||
|
||||
// Resource protection needs to rewrite the method during the write phase. Not compatible!
|
||||
if (protection.FullId.Equals(ResourceProtection._FullId)) continue;
|
||||
|
||||
cctor.Body.MergeCall(instructions[i]);
|
||||
targetMethod.DeclaringType.Methods.Remove(targetMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче