public static string ReplaceRegion(string existingCode, string regionName, string newCode) { var syntaxTree = CSharpSyntaxTree.ParseText(existingCode); var region = CodeMutator.GetRegion(syntaxTree, regionName); if (region == null) { throw new Exception($"Cannot find region named {regionName}"); } return (existingCode .Substring(0, region.Begin.FullSpan.End) + newCode + Environment.NewLine + existingCode .Substring(region.End.FullSpan.Start)); }
static RegionInfo GetRegion(SyntaxTree syntaxTree, string regionName) => CodeMutator.GetRegions(syntaxTree) .FirstOrDefault(x => x.Name == regionName);
// Mutates all blocks in the given method CFG. private void mutateBlocks(MethodCfg methodCfg) { var manipulator = new CfgManipulator(this.module, this.host, this.logger, methodCfg); var codeMutator = new CodeMutator(this.module, this.host, this.logger, this.prng, methodCfg, manipulator, this.debugging); codeMutator.mutateBlocks(methodCfg.basicBlocks); }
// Searches semantically equivalent blocks in the given method CFG and obfuscates them. private void obfuscateSemanticallyEquivalentBlocks(MethodCfg methodCfg) { // Group all blocks with same semantic ID. var semanticGroups = new Dictionary<int, List<BasicBlock>>(); foreach(var block in methodCfg.basicBlocks) { List<BasicBlock> blockList = null; if(!semanticGroups.TryGetValue(block.semanticId, out blockList)) { blockList = new List<BasicBlock>(); semanticGroups[block.semanticId] = blockList; } if(block.semanticId != -1) { semanticGroups[block.semanticId].Add(block); } } // Mutate equivalent blocks. var manipulator = new CfgManipulator(this.module, this.host, this.logger, methodCfg); var codeMutator = new CodeMutator(this.module, this.host, this.logger, this.prng, methodCfg, manipulator, this.debugging); foreach(var blockList in semanticGroups.Values) { codeMutator.mutateSemanticallyEquivalentBlocks(blockList); } }