public static HBlock ObfuscateHBlock(HBlock HB, bool isHBlock) { List<BBlock> bBlocks = new List<BBlock>(); List<Instruction> instructions = HB.instructions; Instruction firstBr = Instruction.Create(OpCodes.Br, instructions[0]); BBlock mainBlock = new BBlock() { instructions = new List<Instruction>(), fakeBranches = new List<Instruction>(), branchOrRet = new List<Instruction>() }; int stack = 0; int push, pop; for (int i = 0; i < instructions.Count; i++) { Instruction instr = instructions[i]; instr.CalculateStackUsage(out push, out pop); stack += (push - pop); if (instr.OpCode == OpCodes.Ret) { mainBlock.branchOrRet.Add(instr); bBlocks.Add((BBlock)mainBlock.Clone()); mainBlock.Clear(); } else if (stack == 0 && instr.OpCode.OpCodeType != OpCodeType.Prefix) { MethodDef obfMethod = obfMethods.Keys.ToArray()[rand.Next(0, 4)]; mainBlock.instructions.Add(instr); if (rand.Next(0,2) == 0) { mainBlock.branchOrRet.Add(Instruction.CreateLdcI4(obfMethods[obfMethod].Item2[rand.Next(0, 4)])); mainBlock.branchOrRet.Add(Instruction.Create(OpCodes.Call, obfMethod)); mainBlock.branchOrRet.Add(Instruction.Create(OpCodes.Brfalse, instructions[i + 1])); } else { mainBlock.branchOrRet.Add(Instruction.CreateLdcI4(obfMethods[obfMethod].Item1[rand.Next(0, 4)])); mainBlock.branchOrRet.Add(Instruction.Create(OpCodes.Call, obfMethod)); mainBlock.branchOrRet.Add(Instruction.Create(OpCodes.Brtrue, instructions[i + 1])); } bBlocks.Add((BBlock)mainBlock.Clone()); mainBlock.Clear(); } else mainBlock.instructions.Add(instr); } /*if (instructions.Count != bBlocks.Sum(a => a.instructions.Count) + 1) { throw new Exception("Did you delete any instruction?"); }*/ int[] position; bBlocks = GeneralUtils.Shuffle<BBlock>(bBlocks, out position); int index = Array.IndexOf(position, position.Length - 1); BBlock lastB = bBlocks[position.Length - 1]; BBlock tempB; tempB = bBlocks[index]; bBlocks[index] = lastB; bBlocks[position.Length - 1] = tempB; if (isHBlock) { int index2 = Array.IndexOf(position, 0); BBlock firstB = bBlocks[0]; BBlock tempB2; tempB2 = bBlocks[index2]; bBlocks[index2] = firstB; bBlocks[0] = tempB2; } foreach (BBlock block in bBlocks) { if (block.branchOrRet[0].OpCode != OpCodes.Ret) { MethodDef obfMethod = obfMethods.Keys.ToArray()[rand.Next(0, 4)]; int rr = rand.Next(0, bBlocks.Count); while (bBlocks[rr].instructions.Count == 0) rr = rand.Next(0, bBlocks.Count); if (rand.Next(0,2) == 0) { block.fakeBranches.Add(Instruction.CreateLdcI4(obfMethods[obfMethod].Item1[rand.Next(0, 4)])); block.fakeBranches.Add(Instruction.Create(OpCodes.Call, obfMethod)); block.fakeBranches.Add(Instruction.Create(OpCodes.Brfalse, bBlocks[rr].instructions[0])); } else { block.fakeBranches.Add(Instruction.CreateLdcI4(obfMethods[obfMethod].Item2[rand.Next(0,4)])); block.fakeBranches.Add(Instruction.Create(OpCodes.Call, obfMethod)); block.fakeBranches.Add(Instruction.Create(OpCodes.Brtrue, bBlocks[rr].instructions[0])); } } } List<Instruction> bInstrs = new List<Instruction>(); foreach (BBlock B in bBlocks) { bInstrs.AddRange(B.instructions); if (rand.Next(0, 2) == 0) { if (B.branchOrRet.Count != 0) bInstrs.AddRange(B.branchOrRet); if (B.fakeBranches.Count != 0) bInstrs.AddRange(B.fakeBranches); } else { if (B.fakeBranches.Count != 0) bInstrs.AddRange(B.fakeBranches); if (B.branchOrRet.Count != 0) bInstrs.AddRange(B.branchOrRet); } if (B.afterInstr != null) bInstrs.Add(B.afterInstr); } if (!isHBlock) bInstrs.Insert(0, firstBr); return new HBlock() { instructions = bInstrs }; }
public static HBlock ObfuscateHBlock(HBlock HB, bool isHBlock) { List <BBlock> bBlocks = new List <BBlock>(); List <Instruction> instructions = HB.instructions; Instruction firstBr = Instruction.Create(OpCodes.Br, instructions[0]); BBlock mainBlock = new BBlock() { instructions = new List <Instruction>(), fakeBranches = new List <Instruction>(), branchOrRet = new List <Instruction>() }; int stack = 0; int push, pop; for (int i = 0; i < instructions.Count; i++) { Instruction instr = instructions[i]; instr.CalculateStackUsage(out push, out pop); stack += (push - pop); if (instr.OpCode == OpCodes.Ret) { mainBlock.branchOrRet.Add(instr); bBlocks.Add((BBlock)mainBlock.Clone()); mainBlock.Clear(); } else if (stack == 0 && instr.OpCode.OpCodeType != OpCodeType.Prefix) { MethodDef obfMethod = obfMethods.Keys.ToArray()[rand.Next(0, 4)]; mainBlock.instructions.Add(instr); if (rand.Next(0, 2) == 0) { mainBlock.branchOrRet.Add(Instruction.CreateLdcI4(obfMethods[obfMethod].Item2[rand.Next(0, 4)])); mainBlock.branchOrRet.Add(Instruction.Create(OpCodes.Call, obfMethod)); mainBlock.branchOrRet.Add(Instruction.Create(OpCodes.Brfalse, instructions[i + 1])); } else { mainBlock.branchOrRet.Add(Instruction.CreateLdcI4(obfMethods[obfMethod].Item1[rand.Next(0, 4)])); mainBlock.branchOrRet.Add(Instruction.Create(OpCodes.Call, obfMethod)); mainBlock.branchOrRet.Add(Instruction.Create(OpCodes.Brtrue, instructions[i + 1])); } bBlocks.Add((BBlock)mainBlock.Clone()); mainBlock.Clear(); } else { mainBlock.instructions.Add(instr); } } /*if (instructions.Count != bBlocks.Sum(a => a.instructions.Count) + 1) * { * throw new Exception("Did you delete any instruction?"); * }*/ int[] position; bBlocks = GeneralUtils.Shuffle <BBlock>(bBlocks, out position); int index = Array.IndexOf(position, position.Length - 1); BBlock lastB = bBlocks[position.Length - 1]; BBlock tempB; tempB = bBlocks[index]; bBlocks[index] = lastB; bBlocks[position.Length - 1] = tempB; if (isHBlock) { int index2 = Array.IndexOf(position, 0); BBlock firstB = bBlocks[0]; BBlock tempB2; tempB2 = bBlocks[index2]; bBlocks[index2] = firstB; bBlocks[0] = tempB2; } foreach (BBlock block in bBlocks) { if (block.branchOrRet[0].OpCode != OpCodes.Ret) { MethodDef obfMethod = obfMethods.Keys.ToArray()[rand.Next(0, 4)]; int rr = rand.Next(0, bBlocks.Count); while (bBlocks[rr].instructions.Count == 0) { rr = rand.Next(0, bBlocks.Count); } if (rand.Next(0, 2) == 0) { block.fakeBranches.Add(Instruction.CreateLdcI4(obfMethods[obfMethod].Item1[rand.Next(0, 4)])); block.fakeBranches.Add(Instruction.Create(OpCodes.Call, obfMethod)); block.fakeBranches.Add(Instruction.Create(OpCodes.Brfalse, bBlocks[rr].instructions[0])); } else { block.fakeBranches.Add(Instruction.CreateLdcI4(obfMethods[obfMethod].Item2[rand.Next(0, 4)])); block.fakeBranches.Add(Instruction.Create(OpCodes.Call, obfMethod)); block.fakeBranches.Add(Instruction.Create(OpCodes.Brtrue, bBlocks[rr].instructions[0])); } } } List <Instruction> bInstrs = new List <Instruction>(); foreach (BBlock B in bBlocks) { bInstrs.AddRange(B.instructions); if (rand.Next(0, 2) == 0) { if (B.branchOrRet.Count != 0) { bInstrs.AddRange(B.branchOrRet); } if (B.fakeBranches.Count != 0) { bInstrs.AddRange(B.fakeBranches); } } else { if (B.fakeBranches.Count != 0) { bInstrs.AddRange(B.fakeBranches); } if (B.branchOrRet.Count != 0) { bInstrs.AddRange(B.branchOrRet); } } if (B.afterInstr != null) { bInstrs.Add(B.afterInstr); } } if (!isHBlock) { bInstrs.Insert(0, firstBr); } return(new HBlock() { instructions = bInstrs }); }