/// <summary> /// Processes the instructions replacing all strings being loaded with an encrypted version. /// </summary> /// <param name="assemblyDef">The assembly definition.</param> /// <param name="body">The body.</param> /// <param name="decryptMethod">The decrypt method.</param> private void ProcessInstructions(AssemblyDefinition assemblyDef, MethodBody body, MethodReference decryptMethod) { var instructions = body.Instructions; var il = body.GetILProcessor(); List<Instruction> instructionsToExpand = new List<Instruction>(); List<int> offsets = new List<int>(); foreach (Instruction instruction in instructions) { //Find the call statement switch (instruction.OpCode.Name) { case "ldstr": //We've found a string load message - we need to replace this instruction if (instruction.Operand is string) //Only do the direct strings for now instructionsToExpand.Add(instruction); break; } } //Fix each ldstr instruction found foreach (Instruction instruction in instructionsToExpand) { //What we do is replace the ldstr "bla" with: //ldstr bytearray encrypted_array //ldc.i4 random_integer //call string class Decrypt(string, int32) //First get the original value string originalValue = instruction.Operand.ToString(); offsets.Add(instruction.Offset); //Secondly generate a random integer as a salt int salt = random.Next(5000, 10000); //Now we need to work out what the encrypted value is and set the operand OutputHelper.WriteLine("Encrypting string \"{0}\"", originalValue); string byteArray = EncryptString(originalValue, salt); Instruction loadString = il.Create(OpCodes.Ldstr, byteArray); il.Replace(instruction, loadString); //Now load the salt Instruction loadSalt = il.Create(OpCodes.Ldc_I4, salt); il.InsertAfter(loadString, loadSalt); //Process the decryption Instruction call = il.Create(OpCodes.Call, decryptMethod); il.InsertAfter(loadSalt, call); } //Unfortunately one thing Mono.Cecil doesn't do is adjust instruction offsets for branch statements //and exception handling start points. We need to fix these manually if (offsets.Count == 0) return; //Do the adjustments il.AdjustOffsets(body, offsets, 6 + assemblyDef.GetAddressSize()); }