优化 MethodControlFlowCalculator生成的指令有可能违反IL控制流规则的问题
parent
ddb144eac8
commit
c596b58d3e
|
@ -330,7 +330,8 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
group.basicBlocks.Insert(group.basicBlocks.IndexOf(to), saveLocalBasicBlock);
|
group.basicBlocks.Insert(group.basicBlocks.IndexOf(to), saveLocalBasicBlock);
|
||||||
group.switchMachineCases.Add(new SwitchMachineCase { index = -1, prepareBlock = saveLocalBasicBlock, targetBlock = to});
|
group.switchMachineCases.Add(new SwitchMachineCase { index = -1, prepareBlock = saveLocalBasicBlock, targetBlock = to});
|
||||||
saveLocalBasicBlock.instructions.Add(Instruction.Create(OpCodes.Ldsfld, (FieldDef)null));
|
saveLocalBasicBlock.instructions.Add(Instruction.Create(OpCodes.Ldsfld, (FieldDef)null));
|
||||||
saveLocalBasicBlock.instructions.Add(Instruction.Create(OpCodes.Br, group.switchMachineInst));
|
saveLocalBasicBlock.instructions.Add(Instruction.Create(OpCodes.Stloc, GlobalSwitchIndexLocal));
|
||||||
|
saveLocalBasicBlock.instructions.Add(Instruction.Create(OpCodes.Br, group.switchMachineEntryInst));
|
||||||
|
|
||||||
|
|
||||||
return saveLocalBasicBlock;
|
return saveLocalBasicBlock;
|
||||||
|
@ -426,6 +427,21 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Local _globalSwitchIndexLocal;
|
||||||
|
|
||||||
|
Local GlobalSwitchIndexLocal
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_globalSwitchIndexLocal == null)
|
||||||
|
{
|
||||||
|
_globalSwitchIndexLocal = new Local(_method.Module.CorLibTypes.Int32);
|
||||||
|
_method.Body.Variables.Add(_globalSwitchIndexLocal);
|
||||||
|
}
|
||||||
|
return _globalSwitchIndexLocal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void InsertSwitchMachineBasicBlockForGroup(BlockGroup group, Dictionary<Instruction, BasicBlockInfo> inst2bb)
|
private void InsertSwitchMachineBasicBlockForGroup(BlockGroup group, Dictionary<Instruction, BasicBlockInfo> inst2bb)
|
||||||
{
|
{
|
||||||
if (group.subGroups != null && group.subGroups.Count > 0)
|
if (group.subGroups != null && group.subGroups.Count > 0)
|
||||||
|
@ -449,6 +465,8 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
var instructions = new List<Instruction>()
|
var instructions = new List<Instruction>()
|
||||||
{
|
{
|
||||||
Instruction.Create(OpCodes.Ldsfld, (FieldDef)null),
|
Instruction.Create(OpCodes.Ldsfld, (FieldDef)null),
|
||||||
|
Instruction.Create(OpCodes.Stloc, GlobalSwitchIndexLocal),
|
||||||
|
group.switchMachineEntryInst,
|
||||||
group.switchMachineInst,
|
group.switchMachineInst,
|
||||||
Instruction.Create(OpCodes.Br, firstCase.targetBlock.FirstInstruction),
|
Instruction.Create(OpCodes.Br, firstCase.targetBlock.FirstInstruction),
|
||||||
};
|
};
|
||||||
|
@ -456,7 +474,7 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
{
|
{
|
||||||
instructions.Insert(0, Instruction.Create(OpCodes.Br, firstBlock.FirstInstruction));
|
instructions.Insert(0, Instruction.Create(OpCodes.Br, firstBlock.FirstInstruction));
|
||||||
}
|
}
|
||||||
|
|
||||||
var switchMachineBb = new BasicBlockInfo()
|
var switchMachineBb = new BasicBlockInfo()
|
||||||
{
|
{
|
||||||
group = group,
|
group = group,
|
||||||
|
@ -480,7 +498,7 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
switchMachineCase.index = i;
|
switchMachineCase.index = i;
|
||||||
List<Instruction> prepareBlockInstructions = switchMachineCase.prepareBlock.instructions;
|
List<Instruction> prepareBlockInstructions = switchMachineCase.prepareBlock.instructions;
|
||||||
|
|
||||||
Instruction setBranchIndexInst = prepareBlockInstructions[prepareBlockInstructions.Count - 2];
|
Instruction setBranchIndexInst = prepareBlockInstructions[prepareBlockInstructions.Count - 3];
|
||||||
Assert.AreEqual(setBranchIndexInst.OpCode, OpCodes.Ldsfld, "first instruction of prepareBlock should be Ldsfld");
|
Assert.AreEqual(setBranchIndexInst.OpCode, OpCodes.Ldsfld, "first instruction of prepareBlock should be Ldsfld");
|
||||||
//setBranchIndexInst.Operand = i;
|
//setBranchIndexInst.Operand = i;
|
||||||
var indexField = _constFieldAllocator.Allocate(i);
|
var indexField = _constFieldAllocator.Allocate(i);
|
||||||
|
@ -489,9 +507,10 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
}
|
}
|
||||||
|
|
||||||
// after shuffle
|
// after shuffle
|
||||||
Assert.IsTrue(instructions.Count == 3 || instructions.Count == 4, "Switch machine basic block should contain 3 or 4 instructions");
|
//Assert.IsTrue(instructions.Count == 4 || instructions.Count == 5, "Switch machine basic block should contain 4 or 5 instructions");
|
||||||
Assert.AreEqual(Code.Ldsfld, instructions[instructions.Count - 3].OpCode.Code, "First instruction should be Ldsfld");
|
Instruction loadFirstIndex = instructions[instructions.Count - 5];
|
||||||
instructions[instructions.Count - 3].Operand = _constFieldAllocator.Allocate(firstCase.index);
|
Assert.AreEqual(Code.Ldsfld, loadFirstIndex.OpCode.Code, "First instruction should be Ldsfld");
|
||||||
|
loadFirstIndex.Operand = _constFieldAllocator.Allocate(firstCase.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,6 +572,7 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
|
|
||||||
public List<BasicBlockInfo> basicBlocks;
|
public List<BasicBlockInfo> basicBlocks;
|
||||||
|
|
||||||
|
public Instruction switchMachineEntryInst;
|
||||||
public Instruction switchMachineInst;
|
public Instruction switchMachineInst;
|
||||||
public List<SwitchMachineCase> switchMachineCases;
|
public List<SwitchMachineCase> switchMachineCases;
|
||||||
|
|
||||||
|
@ -663,7 +683,7 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
this.subGroups = finalGroupList;
|
this.subGroups = finalGroupList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ComputeBasicBlocks(Dictionary<Instruction, BasicBlockInfo> inst2bb)
|
public void ComputeBasicBlocks(Dictionary<Instruction, BasicBlockInfo> inst2bb, Func<Local> switchIndexLocalGetter)
|
||||||
{
|
{
|
||||||
if (subGroups == null || subGroups.Count == 0)
|
if (subGroups == null || subGroups.Count == 0)
|
||||||
{
|
{
|
||||||
|
@ -684,13 +704,14 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
basicBlocks.Add(block);
|
basicBlocks.Add(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
switchMachineEntryInst = Instruction.Create(OpCodes.Ldloc, switchIndexLocalGetter());
|
||||||
switchMachineInst = Instruction.Create(OpCodes.Switch, new List<Instruction>());
|
switchMachineInst = Instruction.Create(OpCodes.Switch, new List<Instruction>());
|
||||||
switchMachineCases = new List<SwitchMachineCase>();
|
switchMachineCases = new List<SwitchMachineCase>();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
foreach (var subGroup in subGroups)
|
foreach (var subGroup in subGroups)
|
||||||
{
|
{
|
||||||
subGroup.ComputeBasicBlocks(inst2bb);
|
subGroup.ComputeBasicBlocks(inst2bb, switchIndexLocalGetter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -799,7 +820,7 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
var rootGroup = new BlockGroup(new List<Instruction>(instructions), inst2blockGroup);
|
var rootGroup = new BlockGroup(new List<Instruction>(instructions), inst2blockGroup);
|
||||||
rootGroup.SplitInstructionsNotInAnySubGroupsToIndividualGroups(inst2blockGroup);
|
rootGroup.SplitInstructionsNotInAnySubGroupsToIndividualGroups(inst2blockGroup);
|
||||||
|
|
||||||
rootGroup.ComputeBasicBlocks(BuildInstructionToBasicBlockInfoDic());
|
rootGroup.ComputeBasicBlocks(BuildInstructionToBasicBlockInfoDic(), () => GlobalSwitchIndexLocal);
|
||||||
return rootGroup;
|
return rootGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue