Remove old cflow deobfuscator code
This commit is contained in:
parent
9063a62325
commit
2ff8a0ea7a
|
@ -112,42 +112,6 @@ namespace de4dot.blocks {
|
||||||
remove(index, 1);
|
remove(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes all instructions that do nothing, nop and eg. ldc/pop, etc.
|
|
||||||
public bool removeNops() {
|
|
||||||
bool removed = false;
|
|
||||||
|
|
||||||
bool keepLooping = true;
|
|
||||||
while (keepLooping) {
|
|
||||||
var instrsToRemove = new List<int>();
|
|
||||||
for (int i = 0; i < Instructions.Count; i++) {
|
|
||||||
var instr = Instructions[i];
|
|
||||||
if (instr.OpCode.Code == Code.Nop) {
|
|
||||||
// The nop instruction is auto created when we access LastInstr so
|
|
||||||
// make we don't get an infinite loop.
|
|
||||||
if (Instructions.Count != 1)
|
|
||||||
instrsToRemove.Add(i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (i + 1 >= Instructions.Count)
|
|
||||||
continue;
|
|
||||||
var next = Instructions[i + 1];
|
|
||||||
if (instr.isSimpleLoad() && next.isPop()) {
|
|
||||||
instrsToRemove.Add(i);
|
|
||||||
instrsToRemove.Add(i + 1);
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
keepLooping = instrsToRemove.Count != 0;
|
|
||||||
if (keepLooping) {
|
|
||||||
removed = true;
|
|
||||||
remove(instrsToRemove);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace the last instructions with a branch to target
|
// Replace the last instructions with a branch to target
|
||||||
public void replaceLastInstrsWithBranch(int numInstrs, Block target) {
|
public void replaceLastInstrsWithBranch(int numInstrs, Block target) {
|
||||||
if (numInstrs < 0 || numInstrs > instructions.Count)
|
if (numInstrs < 0 || numInstrs > instructions.Count)
|
||||||
|
|
|
@ -47,26 +47,6 @@ namespace de4dot.blocks {
|
||||||
methodBlocks = new InstructionListParser(body.Instructions, body.ExceptionHandlers).parse();
|
methodBlocks = new InstructionListParser(body.Instructions, body.ExceptionHandlers).parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deobfuscateLeaveObfuscation() {
|
|
||||||
foreach (var scopeBlock in getAllScopeBlocks(methodBlocks))
|
|
||||||
scopeBlock.deobfuscateLeaveObfuscation();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int deobfuscate() {
|
|
||||||
foreach (var scopeBlock in getAllScopeBlocks(methodBlocks))
|
|
||||||
scopeBlock.deobfuscate(this);
|
|
||||||
|
|
||||||
int numDeadBlocks = removeDeadBlocks();
|
|
||||||
|
|
||||||
foreach (var scopeBlock in getAllScopeBlocks(methodBlocks)) {
|
|
||||||
scopeBlock.mergeBlocks();
|
|
||||||
scopeBlock.repartitionBlocks();
|
|
||||||
scopeBlock.deobfuscateLeaveObfuscation();
|
|
||||||
}
|
|
||||||
|
|
||||||
return numDeadBlocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerable<ScopeBlock> getAllScopeBlocks(ScopeBlock scopeBlock) {
|
IEnumerable<ScopeBlock> getAllScopeBlocks(ScopeBlock scopeBlock) {
|
||||||
var list = new List<ScopeBlock>();
|
var list = new List<ScopeBlock>();
|
||||||
list.Add(scopeBlock);
|
list.Add(scopeBlock);
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2011 de4dot@gmail.com
|
|
||||||
|
|
||||||
This file is part of de4dot.
|
|
||||||
|
|
||||||
de4dot is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
de4dot is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Mono.Cecil.Cil;
|
|
||||||
using de4dot.blocks;
|
|
||||||
|
|
||||||
namespace de4dot.blocks {
|
|
||||||
abstract class CondBranchDeobfuscator {
|
|
||||||
ScopeBlock scopeBlock;
|
|
||||||
IEnumerable<Block> blocks;
|
|
||||||
|
|
||||||
public CondBranchDeobfuscator(ScopeBlock scopeBlock, IEnumerable<Block> blocks) {
|
|
||||||
this.scopeBlock = scopeBlock;
|
|
||||||
this.blocks = blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract bool isTaken(int value);
|
|
||||||
|
|
||||||
public bool deobfuscate() {
|
|
||||||
bool removed = false;
|
|
||||||
|
|
||||||
int value = 0;
|
|
||||||
var deadBlocks = new List<Block>();
|
|
||||||
foreach (var block in blocks) {
|
|
||||||
if (block.Instructions.Count > 1) {
|
|
||||||
if (getLdcValue(block.Instructions, block.Instructions.Count - 2, ref value)) {
|
|
||||||
removed = true;
|
|
||||||
if (isTaken(value)) {
|
|
||||||
deadBlocks.Add(block.FallThrough);
|
|
||||||
block.replaceLastInstrsWithBranch(2, block.Targets[0]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
deadBlocks.Add(block.Targets[0]);
|
|
||||||
block.replaceLastInstrsWithBranch(2, block.FallThrough);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
foreach (var source in new List<Block>(block.Sources)) {
|
|
||||||
int count = source.Instructions.Count;
|
|
||||||
if (count > 0 && getLdcValue(source.Instructions, count - 1, ref value)) {
|
|
||||||
removed = true;
|
|
||||||
if (isTaken(value))
|
|
||||||
source.replaceLastNonBranchWithBranch(1, block.Targets[0]);
|
|
||||||
else
|
|
||||||
source.replaceLastNonBranchWithBranch(1, block.FallThrough);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deadBlocks.Add(block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scopeBlock.removeDeadBlocks(deadBlocks);
|
|
||||||
|
|
||||||
return removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getLdcValue(IList<Instr> instrs, int i, ref int value) {
|
|
||||||
var instr = instrs[i];
|
|
||||||
if (instr.OpCode != OpCodes.Dup)
|
|
||||||
return scopeBlock.getLdcValue(instr, out value);
|
|
||||||
|
|
||||||
if (i == 0)
|
|
||||||
return false;
|
|
||||||
return scopeBlock.getLdcValue(instrs[i - 1], out value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class BrFalseDeobfuscator : CondBranchDeobfuscator {
|
|
||||||
public BrFalseDeobfuscator(ScopeBlock scopeBlock, IEnumerable<Block> blocks)
|
|
||||||
: base(scopeBlock, blocks) {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool isTaken(int value) {
|
|
||||||
return value == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class BrTrueDeobfuscator : CondBranchDeobfuscator {
|
|
||||||
public BrTrueDeobfuscator(ScopeBlock scopeBlock, IEnumerable<Block> blocks)
|
|
||||||
: base(scopeBlock, blocks) {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool isTaken(int value) {
|
|
||||||
return value != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -81,106 +81,6 @@ namespace de4dot.blocks {
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deobfuscateLeaveObfuscation() {
|
|
||||||
foreach (var block in findBlocks())
|
|
||||||
deobfuscateLeaveObfuscation(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
void deobfuscateLeaveObfuscation(Block block) {
|
|
||||||
var instrs = block.Instructions;
|
|
||||||
int index = instrs.Count - 1;
|
|
||||||
if (index <= 0)
|
|
||||||
return;
|
|
||||||
var lastInstr = instrs[index];
|
|
||||||
if (!lastInstr.isLeave() && lastInstr.OpCode != OpCodes.Endfinally && lastInstr.OpCode != OpCodes.Rethrow)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int end = index;
|
|
||||||
int start = end;
|
|
||||||
if (start <= 0)
|
|
||||||
return;
|
|
||||||
while (start > 0) {
|
|
||||||
var instr = instrs[--start];
|
|
||||||
|
|
||||||
bool valid = false;
|
|
||||||
switch (instr.OpCode.Code) {
|
|
||||||
case Code.Dup:
|
|
||||||
case Code.Ldarg:
|
|
||||||
case Code.Ldarg_0:
|
|
||||||
case Code.Ldarg_1:
|
|
||||||
case Code.Ldarg_2:
|
|
||||||
case Code.Ldarg_3:
|
|
||||||
case Code.Ldarga:
|
|
||||||
case Code.Ldarga_S:
|
|
||||||
case Code.Ldarg_S:
|
|
||||||
case Code.Ldc_I4:
|
|
||||||
case Code.Ldc_I4_0:
|
|
||||||
case Code.Ldc_I4_1:
|
|
||||||
case Code.Ldc_I4_2:
|
|
||||||
case Code.Ldc_I4_3:
|
|
||||||
case Code.Ldc_I4_4:
|
|
||||||
case Code.Ldc_I4_5:
|
|
||||||
case Code.Ldc_I4_6:
|
|
||||||
case Code.Ldc_I4_7:
|
|
||||||
case Code.Ldc_I4_8:
|
|
||||||
case Code.Ldc_I4_M1:
|
|
||||||
case Code.Ldc_I4_S:
|
|
||||||
case Code.Ldc_I8:
|
|
||||||
case Code.Ldc_R4:
|
|
||||||
case Code.Ldc_R8:
|
|
||||||
case Code.Ldftn:
|
|
||||||
case Code.Ldloc:
|
|
||||||
case Code.Ldloc_0:
|
|
||||||
case Code.Ldloc_1:
|
|
||||||
case Code.Ldloc_2:
|
|
||||||
case Code.Ldloc_3:
|
|
||||||
case Code.Ldloca:
|
|
||||||
case Code.Ldloca_S:
|
|
||||||
case Code.Ldloc_S:
|
|
||||||
case Code.Ldnull:
|
|
||||||
case Code.Ldsfld:
|
|
||||||
case Code.Ldsflda:
|
|
||||||
case Code.Ldstr:
|
|
||||||
case Code.Ldtoken:
|
|
||||||
case Code.Nop:
|
|
||||||
valid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!valid) {
|
|
||||||
start++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int num = end - start;
|
|
||||||
if (num > 0)
|
|
||||||
block.remove(start, num);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deobfuscate(Blocks blocks) {
|
|
||||||
while (true) {
|
|
||||||
mergeBlocks();
|
|
||||||
|
|
||||||
bool removed = false;
|
|
||||||
removed |= removeNops();
|
|
||||||
removed |= deobfuscateConditionalBranches();
|
|
||||||
if (!removed)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var switchDeobfuscator = new SwitchControlFlowDeobfuscator(blocks);
|
|
||||||
switchDeobfuscator.deobfuscate(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool removeNops() {
|
|
||||||
bool removed = false;
|
|
||||||
|
|
||||||
foreach (var block in findBlocks())
|
|
||||||
removed |= block.removeNops();
|
|
||||||
|
|
||||||
return removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal bool getLdcValue(Instr instr, out int value) {
|
internal bool getLdcValue(Instr instr, out int value) {
|
||||||
if (Code.Ldc_I4_0 <= instr.OpCode.Code && instr.OpCode.Code <= Code.Ldc_I4_8)
|
if (Code.Ldc_I4_0 <= instr.OpCode.Code && instr.OpCode.Code <= Code.Ldc_I4_8)
|
||||||
value = instr.OpCode.Code - Code.Ldc_I4_0;
|
value = instr.OpCode.Code - Code.Ldc_I4_0;
|
||||||
|
@ -197,13 +97,6 @@ namespace de4dot.blocks {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool deobfuscateConditionalBranches() {
|
|
||||||
bool removed = false;
|
|
||||||
removed |= new BrFalseDeobfuscator(this, findBlocks((block) => block.LastInstr.isBrfalse())).deobfuscate();
|
|
||||||
removed |= new BrTrueDeobfuscator(this, findBlocks((block) => block.LastInstr.isBrtrue())).deobfuscate();
|
|
||||||
return removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the block if it's a dead block. If it has refs to other dead blocks, those
|
// Remove the block if it's a dead block. If it has refs to other dead blocks, those
|
||||||
// are also removed.
|
// are also removed.
|
||||||
public void removeDeadBlock(Block block) {
|
public void removeDeadBlock(Block block) {
|
||||||
|
|
|
@ -1,143 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2011 de4dot@gmail.com
|
|
||||||
|
|
||||||
This file is part of de4dot.
|
|
||||||
|
|
||||||
de4dot is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
de4dot is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Mono.Cecil.Cil;
|
|
||||||
|
|
||||||
namespace de4dot.blocks {
|
|
||||||
class SwitchControlFlowDeobfuscator {
|
|
||||||
Blocks blocks;
|
|
||||||
Dictionary<Block, bool> foundBlocks = new Dictionary<Block, bool>();
|
|
||||||
|
|
||||||
class SwitchObfuscationInfo {
|
|
||||||
public Block switchBlock;
|
|
||||||
public VariableDefinition stateVar;
|
|
||||||
Func<Instr, VariableDefinition> getLocalVar;
|
|
||||||
Dictionary<Block, bool> switchTargetBlocks = new Dictionary<Block, bool>();
|
|
||||||
|
|
||||||
public IEnumerable<Block> SwitchTargetBlocks {
|
|
||||||
get { return switchTargetBlocks.Keys; }
|
|
||||||
}
|
|
||||||
|
|
||||||
internal SwitchObfuscationInfo(Func<Instr, VariableDefinition> getLocalVar) {
|
|
||||||
this.getLocalVar = getLocalVar;
|
|
||||||
}
|
|
||||||
|
|
||||||
void findAllSwitchTargetBlocks() {
|
|
||||||
addSwitchTargetBlock(switchBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void addSwitchTargetBlock(Block block) {
|
|
||||||
if (switchTargetBlocks.ContainsKey(block))
|
|
||||||
return;
|
|
||||||
switchTargetBlocks[block] = true;
|
|
||||||
foreach (var source in block.Sources) {
|
|
||||||
if (isNopBlock(source))
|
|
||||||
addSwitchTargetBlock(source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isNopBlock(Block block) {
|
|
||||||
foreach (var instr in block.Instructions) {
|
|
||||||
if (instr.OpCode.Code != Code.Nop && instr.OpCode.Code != Code.Br && instr.OpCode.Code != Code.Br_S)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fixSwitchBranches(ScopeBlock scopeBlock) {
|
|
||||||
findAllSwitchTargetBlocks();
|
|
||||||
foreach (var switchTargetBlock in new List<Block>(switchTargetBlocks.Keys)) {
|
|
||||||
foreach (var block in new List<Block>(switchTargetBlock.Sources)) {
|
|
||||||
int numInstrs;
|
|
||||||
Block switchTarget;
|
|
||||||
if (getSwitchIndex(block, out numInstrs, out switchTarget))
|
|
||||||
block.replaceLastInstrsWithBranch(numInstrs, switchTarget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getSwitchIndex(Block block, out int numInstrs, out Block switchTarget) {
|
|
||||||
numInstrs = -1;
|
|
||||||
switchTarget = null;
|
|
||||||
|
|
||||||
if (block.Instructions.Count < 2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int count = block.Instructions.Count;
|
|
||||||
if (!block.Instructions[count - 2].isLdcI4())
|
|
||||||
return false;
|
|
||||||
if (!block.Instructions[count - 1].isStloc() || getLocalVar(block.Instructions[count - 1]) != stateVar)
|
|
||||||
return false;
|
|
||||||
if (!block.isFallThrough() || !switchTargetBlocks.ContainsKey(block.FallThrough))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int switchIndex = (int)block.Instructions[count - 2].getLdcI4Value();
|
|
||||||
if (switchIndex < 0 || switchIndex >= switchBlock.Targets.Count)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
numInstrs = 2;
|
|
||||||
switchTarget = switchBlock.Targets[switchIndex];
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SwitchControlFlowDeobfuscator(Blocks blocks) {
|
|
||||||
this.blocks = blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deobfuscate(ScopeBlock scopeBlock) {
|
|
||||||
while (true) {
|
|
||||||
var switchObfuscationInfo = new SwitchObfuscationInfo((instr) => getLocalVar(instr));
|
|
||||||
if (!findSwitchObfuscation(scopeBlock, switchObfuscationInfo))
|
|
||||||
break;
|
|
||||||
switchObfuscationInfo.fixSwitchBranches(scopeBlock);
|
|
||||||
scopeBlock.removeDeadBlocks(new List<Block>(switchObfuscationInfo.SwitchTargetBlocks));
|
|
||||||
scopeBlock.mergeBlocks();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VariableDefinition getLocalVar(Instr instr) {
|
|
||||||
return Instr.getLocalVar(blocks.Locals, instr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool findSwitchObfuscation(ScopeBlock scopeBlock, SwitchObfuscationInfo switchObfuscationInfo) {
|
|
||||||
foreach (var bb in scopeBlock.getBaseBlocks()) {
|
|
||||||
var block = bb as Block;
|
|
||||||
if (block == null || foundBlocks.ContainsKey(block))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (block.Instructions.Count != 2 || !block.Instructions[0].isLdloc() || block.Instructions[1].OpCode != OpCodes.Switch)
|
|
||||||
continue;
|
|
||||||
switchObfuscationInfo.switchBlock = block;
|
|
||||||
switchObfuscationInfo.stateVar = getLocalVar(block.Instructions[0]);
|
|
||||||
var typeName = switchObfuscationInfo.stateVar.VariableType.FullName;
|
|
||||||
if (typeName != "System.Int32" && typeName != "System.UInt32")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
foundBlocks[block] = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -48,7 +48,6 @@
|
||||||
<Compile Include="cflow\Value.cs" />
|
<Compile Include="cflow\Value.cs" />
|
||||||
<Compile Include="cflow\ValueStack.cs" />
|
<Compile Include="cflow\ValueStack.cs" />
|
||||||
<Compile Include="CodeGenerator.cs" />
|
<Compile Include="CodeGenerator.cs" />
|
||||||
<Compile Include="CondBranchDeobfuscator.cs" />
|
|
||||||
<Compile Include="cflow\BlocksCflowDeobfuscator.cs" />
|
<Compile Include="cflow\BlocksCflowDeobfuscator.cs" />
|
||||||
<Compile Include="DeadBlocksRemover.cs" />
|
<Compile Include="DeadBlocksRemover.cs" />
|
||||||
<Compile Include="DotNetUtils.cs" />
|
<Compile Include="DotNetUtils.cs" />
|
||||||
|
@ -62,7 +61,6 @@
|
||||||
<Compile Include="MethodBlocks.cs" />
|
<Compile Include="MethodBlocks.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="ScopeBlock.cs" />
|
<Compile Include="ScopeBlock.cs" />
|
||||||
<Compile Include="SwitchControlFlowDeobfuscator.cs" />
|
|
||||||
<Compile Include="TryBlock.cs" />
|
<Compile Include="TryBlock.cs" />
|
||||||
<Compile Include="TryHandlerBlock.cs" />
|
<Compile Include="TryHandlerBlock.cs" />
|
||||||
<Compile Include="Utils.cs" />
|
<Compile Include="Utils.cs" />
|
||||||
|
|
|
@ -464,8 +464,6 @@ namespace de4dot {
|
||||||
}
|
}
|
||||||
deobfuscateStrings(blocks);
|
deobfuscateStrings(blocks);
|
||||||
deob.deobfuscateMethodEnd(blocks);
|
deob.deobfuscateMethodEnd(blocks);
|
||||||
if (options.ControlFlowDeobfuscation)
|
|
||||||
blocks.deobfuscateLeaveObfuscation();
|
|
||||||
|
|
||||||
IList<Instruction> allInstructions;
|
IList<Instruction> allInstructions;
|
||||||
IList<ExceptionHandler> allExceptionHandlers;
|
IList<ExceptionHandler> allExceptionHandlers;
|
||||||
|
@ -737,7 +735,11 @@ namespace de4dot {
|
||||||
if (check(method, SimpleDeobFlags.HasDeobfuscated))
|
if (check(method, SimpleDeobFlags.HasDeobfuscated))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
deobfuscate(method, "Deobfuscating control flow", (blocks) => blocks.deobfuscate());
|
deobfuscate(method, "Deobfuscating control flow", (blocks) => {
|
||||||
|
var cflowDeobfuscator = new BlocksCflowDeobfuscator();
|
||||||
|
cflowDeobfuscator.init(blocks);
|
||||||
|
cflowDeobfuscator.deobfuscate();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISimpleDeobfuscator.decryptStrings(MethodDefinition method, IDeobfuscator theDeob) {
|
void ISimpleDeobfuscator.decryptStrings(MethodDefinition method, IDeobfuscator theDeob) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user