using System;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace ReflexilDemo
{
static class Cecil
// Retrouve une définition de méthode suivant un type owner, un nom et un nombre de paramètres
// Note: Méthode de démo uniquement car il n'est pas rigoureux de seulement compter les paramètres
static MethodDefinition GetMethodDefinition(AssemblyDefinition adef,
string owner,
string name,
int paramcount)
// On récupère la définition du type
TypeDefinition tdef = adef.MainModule.Types[owner];
foreach (MethodDefinition mdef in tdef.Methods)
// Si le nom et le nombre de paramètres correspondent, c'est bon!
if ((mdef.Name == name) && (paramcount == mdef.Parameters.Count)) return mdef;
}
throw new ArgumentException("Unable to find this method!");
public static void DoPatch()
// Chargement de l'assembly à patcher
AssemblyDefinition targetasmdef = AssemblyFactory.GetAssembly("ReflexilDemo.exe");
// On retrouve la définition de ComputeAndDisplay
MethodDefinition computedefinition = GetMethodDefinition(targetasmdef,
"ReflexilDemo.DemoForm",
"ComputeAndDisplay",
2);
// On ajoute une instruction pour charger la chaîne sur la pile
CilWorker worker = computedefinition.Body.CilWorker;
Instruction insld = worker.Create(OpCodes.Ldstr, "The result is!");
worker.InsertBefore(computedefinition.Body.Instructions[11], insld);
// On récupère l'instruction d'appel à MessageBox.Show
Instruction insshow = computedefinition.Body.Instructions[12];
// Et en particulier la référence à MessageBox.Show
MethodReference oldshowref = insshow.Operand as MethodReference;
// Puis on charge l'assemblage qui déclare MessageBox.Show (System.Windows.Forms)
AssemblyNameReference scope = oldshowref.DeclaringType.Scope as AssemblyNameReference;
// On utilise le resolver car l'assemblage n'est pas dans le répertoire courant
DefaultAssemblyResolver resolver = new DefaultAssemblyResolver();
AssemblyDefinition sourceasmdef = resolver.Resolve(scope);
// On récupère la définition de l'overload qui nous interesse de MessageBox.Show
MethodDefinition newshowref = GetMethodDefinition(sourceasmdef,
"System.Windows.Forms.MessageBox",
"Show",
// On importe une référence de cet overload dans l'assemblage de travail
insshow.Operand = computedefinition.DeclaringType.Module.Import(newshowref);
// On sauvegarde!
AssemblyFactory.SaveAssembly(targetasmdef, "Reflexil.Manualy.Patched.exe");