refs #39 Improved tracing service
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:
Родитель
92cc1f2f01
Коммит
af847d7dda
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче