The service to trace the parameters of methods got improved to properly find the actual sources of the parameters. Special consideration was given to the behaviour of the "dup" opcode.
This commit is contained in:
Martin Karing 2019-04-28 11:15:46 +02:00
Родитель 92cc1f2f01
Коммит af847d7dda
2 изменённых файлов: 21 добавлений и 15 удалений

Просмотреть файл

@ -74,7 +74,7 @@ namespace Confuser.Core {
protected internal override void Initialize(ConfuserContext context) {
context.Registry.RegisterService(_RandomServiceId, typeof(IRandomService), new RandomService(parameters.Project.Seed));
context.Registry.RegisterService(_MarkerServiceId, typeof(IMarkerService), new MarkerService(context, marker));
context.Registry.RegisterService(_TraceServiceId, typeof(ITraceService), new TraceService(context));
context.Registry.RegisterService(_TraceServiceId, typeof(ITraceService), new TraceService());
context.Registry.RegisterService(_RuntimeServiceId, typeof(IRuntimeService), new RuntimeService());
context.Registry.RegisterService(_CompressionServiceId, typeof(ICompressionService), new CompressionService(context));
context.Registry.RegisterService(_APIStoreId, typeof(IAPIStore), new APIStore(context));
@ -85,4 +85,4 @@ namespace Confuser.Core {
//
}
}
}
}

Просмотреть файл

@ -6,16 +6,14 @@ using dnlib.DotNet;
using dnlib.DotNet.Emit;
namespace Confuser.Core.Services {
internal class TraceService : ITraceService {
public sealed class TraceService : ITraceService {
readonly Dictionary<MethodDef, MethodTrace> cache = new Dictionary<MethodDef, MethodTrace>();
ConfuserContext context;
/// <summary>
/// Initializes a new instance of the <see cref="TraceService" /> class.
/// </summary>
/// <param name="context">The working context.</param>
public TraceService(ConfuserContext context) {
this.context = context;
public TraceService() {
}
@ -246,6 +244,9 @@ namespace Confuser.Core.Services {
return null;
}
while (method.Body.Instructions[beginInstrIndex].OpCode.Code == Code.Dup)
beginInstrIndex--;
// Trace the index of arguments
seen.Clear();
var working2 = new Queue<Tuple<int, Stack<int>>>();
@ -260,17 +261,22 @@ namespace Confuser.Core.Services {
while (index != instrIndex && index < method.Body.Instructions.Count) {
Instruction currentInstr = Instructions[index];
currentInstr.CalculateStackUsage(out push, out pop);
int stackUsage = pop - push;
if (stackUsage < 0) {
Debug.Assert(stackUsage == -1); // i.e. push
evalStack.Push(index);
if (currentInstr.OpCode.Code == Code.Dup) {
// Special case duplicate. This causes the current value on the stack to be duplicated.
// To show this behaviour, we'll fetch the last object on the eval stack and add it back twice.
Debug.Assert(pop == 1 && push == 2 && evalStack.Count > 0);
var lastIdx = evalStack.Pop();
evalStack.Push(lastIdx);
evalStack.Push(lastIdx);
}
else {
if (evalStack.Count < stackUsage)
return null;
for (int i = 0; i < stackUsage; i++)
for (var i = 0; i < pop; i++) {
evalStack.Pop();
}
Debug.Assert(push <= 1); // Instructions shouldn't put more than one value on the stack.
for (var i = 0; i < push; i++) {
evalStack.Push(index);
}
}
object instrOperand = currentInstr.Operand;
@ -306,4 +312,4 @@ namespace Confuser.Core.Services {
return ret;
}
}
}
}