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(); } }
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; }