public void OnType(TypeDefinition type) { if (type.IsInterface) { return; } foreach (var method in type.Methods) { try { string fieldName; MethodReference methodR; #region Get required info or continue if (method.Name.StartsWith("add_")) { fieldName = method.Name.Substring("add_".Length); methodR = combineR; } else if (method.Name.StartsWith("remove_")) { fieldName = method.Name.Substring("remove_".Length); methodR = removeR; } else { continue; } #endregion var newI = new List <Instruction>(); var processor = method.Body.GetILProcessor(); bool foundCompExch = false; foreach (var existingInstruction in processor.Body.Instructions) { if (existingInstruction.OpCode == OpCodes.Call) { var meth = existingInstruction.Operand as MethodReference; if (meth != null) { if (meth.Name == "CompareExchange") { if (Verbosity > 7) { Console.WriteLine(" Found CompareExchange"); } foundCompExch = true; break; } } } } if (!foundCompExch) { if (Verbosity >= Verbosities.SkippingVerbose) { Console.WriteLine(" . ignoring body with no CompareExchange: " + type.Name + "." + method.Name); } skipped++; continue; } FieldReference field; if (type.HasGenericParameters) { var giType = new GenericInstanceType(type); // var // string x = type.FullName; //giType. field = type.Fields.Where(f => f.Name == fieldName).FirstOrDefault(); Console.WriteLine("==== GENERICTYPE: " + type + " (" + type.GenericParameters.Count + ") " + giType.ToString() + ", Field: " + field.FullName); foreach (var genPar in type.GenericParameters) { Console.WriteLine(" ==> " + genPar.FullName); } } else { field = type.Fields.Where(f => f.Name == fieldName).FirstOrDefault(); } if (field == null) { throw new Exception("Could not find field: " + fieldName + " in type " + type.FullName); } if (method.IsStatic) { // IL_0000: ldfld class MyNamespace.ActionBool MyNamespace.EnableableBase::myHandler newI.Add(processor.Create(OpCodes.Ldsfld, field)); // IL_0005: ldarg.0 newI.Add(processor.Create(OpCodes.Ldarg_0)); // IL_0006: call class [mscorlib]System.Delegate class [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate) newI.Add(processor.Create(OpCodes.Call, methodR)); // IL_000b: castclass MyNamespace.ActionBool newI.Add(processor.Create(OpCodes.Castclass, field.FieldType)); // IL_0010: stfld class MyNamespace.ActionBool MyNamespace.EnableableBase::myHandler newI.Add(processor.Create(OpCodes.Stsfld, field)); // IL_0015: ret newI.Add(processor.Create(OpCodes.Ret)); } else { // IL_0000: ldarg.0 newI.Add(processor.Create(OpCodes.Ldarg_0)); // IL_0001: ldarg.0 newI.Add(processor.Create(OpCodes.Ldarg_0)); // IL_0002: ldfld class MyNamespace.ActionBool MyNamespace.EnableableBase::myHandler newI.Add(processor.Create(OpCodes.Ldfld, field)); // IL_0007: ldarg.1 newI.Add(processor.Create(OpCodes.Ldarg_1)); // IL_0008: call class [mscorlib]System.Delegate class [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate) newI.Add(processor.Create(OpCodes.Call, methodR)); // IL_000d: castclass MyNamespace.ActionBool newI.Add(processor.Create(OpCodes.Castclass, field.FieldType)); // IL_0012: stfld class MyNamespace.ActionBool MyNamespace.EnableableBase::myHandler newI.Add(processor.Create(OpCodes.Stfld, field)); // IL_0017: ret newI.Add(processor.Create(OpCodes.Ret)); } #region Replace the instructions replaced++; processor.Body.Instructions.Clear(); foreach (var i in newI) { processor.Body.Instructions.Add(i); } if (Verbosity >= Verbosities.Success) { Console.WriteLine(" - replaced method: " + type.Name + "." + method.Name); } #endregion } catch (Exception ex) { Console.WriteLine("Exception for method: " + type.FullName + "." + method.Name + ": " + ex); } } }