Go Back   UnKnoWnCheaTs - Multiplayer Game Hacking and Cheats

  • C# Loader Hooking With Mono.Cecil
    sponsored advertisements
    Reply
     
    Thread Tools

    C# Loader Hooking With Mono.Cecil
    Old 5th March 2012, 08:11 PM   #1
    atom0s
    Supreme H4x0|2

    atom0s's Avatar

    Join Date: Dec 2011
    Posts: 590
    Reputation: 5557
    Rep Power: 313
    atom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATS
    Points: 17,859, Level: 18
    Points: 17,859, Level: 18 Points: 17,859, Level: 18 Points: 17,859, Level: 18
    Level up: 4%, 1,441 Points needed
    Level up: 4% Level up: 4% Level up: 4%
    Activity: 0%
    Activity: 0% Activity: 0% Activity: 0%
    Last Achievements C# Loader Hooking With Mono.CecilC# Loader Hooking With Mono.CecilC# Loader Hooking With Mono.Cecil
    C# Loader Hooking With Mono.Cecil

    About This Tutorial
    This tutorial will cover how to implement function alterations to a managed target using Mono.Cecil. As far as I know Mono.Cecil only works for recreating a binary before it is loaded. I am not sure if it will allow runtime reconstruction, nor have I tried to get it to so. So if you know if it can please do let me know. This tutorial will cover hooking onto an XNA application.


    Legal Bullshit No One Reads
    This is a tutorial for research purposes only. I am not responsible for what you do with this material. You agree that by reading this that you take full responsibility of your actions. I am not responsible for what you do with this information!


    Tools Needed



    Getting Started
    To start, we'll be working on attaching onto XNA's main functions for a normal game. Since Terraria is written in C# using XNA we can see that it inherits 'Game' in its main class.


    If we use a .NET object browser we can see what Game contains. For the sake of this tutorial you can find the members here:
    Game Members

    So we are mainly interested in:
    • Initialize
    • LoadContent
    • Update
    • Draw


    Like most hacks we will want pre/post hooks for each of these functions. This will allow us to handle things before and after the actual call occurs.


    Preparing Our Project
    We'll start by making a new XNA game, it is easier to do this since it will add all the XNA references for us even though we don't need any of the actual game code it makes. So start by opening VS2010 and going to:
    File -> New -> Project -> C# -> XNA Game Studio 4.0 -> Windows Game (4.0)

    Next, we'll remove the Content project because its useless to us (unless you plan to add custom content). So right-click the Content project and remove it. You will also need to remove the content reference in the main project's Content References if it wasn't removed automatically.

    Next, we'll delete Game1.cs since we don't need it.

    Create a new class, call it whatever you want. In this case I'm calling it Hooks.cs


    Preparing Our Hooks Class
    To start we will need four main class variables, one for the loaded assembly definition, one for the main module definition, one for the complete assembly, and one for the assemblies main class type. So we will add:

    Code:
      
            private AssemblyDefinition m_vAsmDefinition = null;
            private ModuleDefinition m_vModDefinition = null;
            private Assembly m_vAssembly = null;
            private Type m_vMainType = null;
    Next we will write an initialize function to load our target into our assembly definition and obtain its main module for the module definition:
    Code:
      
            public bool Initialize()
            {
                try
                {
                    this.m_vAsmDefinition = AssemblyDefinition.ReadAssembly("Terraria.exe");
                    this.m_vModDefinition = this.m_vAsmDefinition.MainModule;
                    return true;
                }
                catch { return false; }
            }
    Next we'll write the finalization function to finish up our modifications and prepare the new assembly for usage:
    Code:
      
            public bool Finialize()
            {
                try
                {
                    // Validate we've loaded the main executable first..
                    if (this.m_vAsmDefinition == null)
                        return false;
    
                    using (MemoryStream mStream = new MemoryStream())
                    {
                        // Write the edited data to the memory stream..
                        this.m_vAsmDefinition.Write(mStream);
    
                        // Load the new assembly from the memory stream buffer..
                        this.m_vAssembly = Assembly.Load(mStream.GetBuffer());
                        return true;
                    }
                }
                catch { return false; }
            }
    Next, we need to create a call to run the new assembly rather then using the one on the disk. Since we have the assembly written in memory we can load it in memory as well, so we'll write our Run function like this:
    Code:
      
            public bool Run()
            {
                try
                {
                    if (this.m_vAssembly == null)
                        return false;
    
                    // Get the main class type..
                    this.m_vMainType = this.m_vAssembly.GetType("Terraria.Main");
    
                    // Create the constructor call..
                    var constructor = this.m_vMainType.GetConstructor(new Type[] { }).Invoke(null);
    
                    // Obtain the main run method and invoke it..
                    var method = this.m_vMainType.GetMethod("Run", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
                    method.Invoke(constructor, null);
    
                    return true;
                }
                catch { return false; }
            }
    Now that we have our base done, we can setup the program to run this new instance of the assembly.
    Inside of Program.cs, inside of Main() replace everything with:

    Code:
      
            static void Main(string[] args)
            {
                var hooks = new Hooks();
                hooks.Initialize();
                hooks.Finialize();
                hooks.Run();
            }
    Now you can test if the base hooking works by running your wrapper etc. to make sure its working as expected.


    Hooking Onto Our Functions..
    Next we want to hook onto the functions. Simple enough, Pre* hooks just get called at the start of the function, while Post* at the end.
    (Please see the note below at the end of this tutorial, you may need to do more work in some cases for some hooks to work properly!)

    We'll start with Initialize. Inside our Hooks class lets add two functions PreInitialize and PostInitialize following the same method definition from MSDN for Initialize. For now we'll out some console outputs to determine if they get called. (Be sure that these are marked public and static or you will get runtime errors!)

    Code:
      
            public static void PreInitialize()
            {
                System.Diagnostics.Debug.WriteLine("Custom PreInitialize was called!");
            }
            public static void PostInitialize()
            {
                System.Diagnostics.Debug.WriteLine("Custom PostInitialize was called!");
            }
    Our next step involves digging into Mono.Cecil's abilities. We'll make a new function to apply our hooks. So lets call that ApplyHooks for now. To start, we need to locate the method inside our main type. I wrote wrappers for making these parts easier. These are the wrappers I wrote for these next steps:
    Code:
      
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //
        // Object Reflection From New Terraria Objects
        //
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
            /// <summary>
            /// Gets a method definition from the new Terraria executable.
            /// </summary>
            /// <param name="t"></param>
            /// <param name="methodName"></param>
            /// <returns></returns>
            public MethodDefinition GetMethodDefinition(TypeDefinition t, String methodName)
            {
                return (from MethodDefinition m in t.Methods
                        where m.Name == methodName
                        select m).FirstOrDefault();
            }
    
            /// <summary>
            /// Gets a field definition from the new Terraria executable.
            /// </summary>
            /// <param name="t"></param>
            /// <param name="fieldName"></param>
            /// <returns></returns>
            public FieldDefinition GetFieldDefinition(TypeDefinition t, String fieldName)
            {
                return (from FieldDefinition f in t.Fields
                        where f.Name == fieldName
                        select f).FirstOrDefault();
            }
    
            /// <summary>
            /// Gets a property definition from the new Terraria executable.
            /// </summary>
            /// <param name="t"></param>
            /// <param name="propName"></param>
            /// <returns></returns>
            public PropertyDefinition GetPropertyDefinition(TypeDefinition t, String propName)
            {
                return (from PropertyDefinition p in t.Properties
                        where p.Name == propName
                        select p).FirstOrDefault();
            }
    
            /// <summary>
            /// Gets a type definition from the new Terraria executable.
            /// </summary>
            /// <param name="typeName"></param>
            /// <returns></returns>
            public TypeDefinition GetTypeDefinition(String typeName)
            {
                return (from TypeDefinition t in this.m_vModDefinition.Types
                        where t.Name == typeName
                        select t).FirstOrDefault();
            }
    
            /// <summary>
            /// Gets a type from within the new Terraria executable.
            /// </summary>
            /// <param name="typeName"></param>
            /// <returns></returns>
            public Type GetType(String typeName)
            {
                return (from Type t in this.m_vAssembly.GetTypes()
                        where t.Name == typeName
                        select t).FirstOrDefault();
            }
    
            /// <summary>
            /// Gets a method from within Terraria.Main.
            /// </summary>
            /// <param name="methodName"></param>
            /// <returns></returns>
            public MethodInfo GetMethod(String methodName)
            {
                return (from MethodInfo m in this.m_vMainType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
                        where m.Name == methodName
                        select m).FirstOrDefault();
            }
    
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //
        // Object Reflection From New Terraria.Main Object
        //
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
            /// <summary>
            /// Gets the value of a field within Terraria.Main.
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="fieldName"></param>
            /// <returns></returns>
            public T GetMainField<T>(String fieldName)
            {
                var field = (from FieldInfo f in this.m_vMainType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
                             where f.Name == fieldName
                             select f).FirstOrDefault();
    
                if (field == null)
                    return default(T);
    
                return (T)field.GetValue(this.m_vMainType);
            }
    
            /// <summary>
            /// Sets the value of a field within Terraria.Main.
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="fieldName"></param>
            /// <param name="objValue"></param>
            public void SetMainField<T>(String fieldName, T objValue)
            {
                var field = (from FieldInfo f in this.m_vMainType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
                             where f.Name == fieldName
                             select f).FirstOrDefault();
    
                if (field == null) 
                    return;
    
                field.SetValue(this.m_vMainType, objValue);
            }
    So now we can easily locate the method for Initialize using:
    Code:
      MethodDefinition initMethod = GetMethodDefinition(GetTypeDefinition("Main"), "Initialize");
    Next we want to inject our 'PreInitialize' call to the start of this method. We can do that by using:
    Code:
      
                MethodDefinition initMethod = GetMethodDefinition(GetTypeDefinition("Main"), "Initialize");
                var initProc = initMethod.Body.GetILProcessor();
                initProc.InsertBefore(initMethod.Body.Instructions[0], initProc.Create(OpCodes.Call,
                    this.m_vModDefinition.Import(typeof(Hooks).GetMethod("PreInitialize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                    ));
    We can run the test app again and see if it gets called, in the output window you should see:
    Custom PreInitialize was called!

    Great now we want to add our PostInitialize call to the end of the function. If we look at the all in a IL decoder (such as ILSpy) we can see the Initialize call ends with:
    Code:
          IL_1e8f: ret
    So we need to inject before this return:
    Code:
      
                initProc.InsertBefore(initMethod.Body.Instructions[initMethod.Body.Instructions.Count - 2], initProc.Create(OpCodes.Call,
                    this.m_vModDefinition.Import(typeof(Hooks).GetMethod("PostInitialize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                    ));
    So now we have in total for our Initialize hooks:
    Code:
      
            public void ApplyHooks()
            {
                MethodDefinition initMethod = GetMethodDefinition(GetTypeDefinition("Main"), "Initialize");
                var initProc = initMethod.Body.GetILProcessor();
                initProc.InsertBefore(initMethod.Body.Instructions[0], initProc.Create(OpCodes.Call,
                    this.m_vModDefinition.Import(typeof(Hooks).GetMethod("PreInitialize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                    ));
                initProc.InsertBefore(initMethod.Body.Instructions[initMethod.Body.Instructions.Count - 2], initProc.Create(OpCodes.Call,
                    this.m_vModDefinition.Import(typeof(Hooks).GetMethod("PostInitialize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                    ));
            }
    Next we'll do the same for LoadContent, add the Pre and Post methods:
    Code:
      
            public static void PreLoadContent()
            {
                System.Diagnostics.Debug.WriteLine("Custom PreLoadContent was called!");
            }
            public static void PostLoadContent()
            {
                System.Diagnostics.Debug.WriteLine("Custom PostLoadContent was called!");
            }
    And then for our hook it will be similar to Initializes hook:
    Code:
      
                MethodDefinition contMethod = GetMethodDefinition(GetTypeDefinition("Main"), "LoadContent");
                var contProc = contMethod.Body.GetILProcessor();
                contProc.InsertBefore(contMethod.Body.Instructions[0], contProc.Create(OpCodes.Call,
                    this.m_vModDefinition.Import(typeof(Hooks).GetMethod("PreLoadContent", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                    ));
                contProc.InsertBefore(contMethod.Body.Instructions[contMethod.Body.Instructions.Count - 2], contProc.Create(OpCodes.Call,
                    this.m_vModDefinition.Import(typeof(Hooks).GetMethod("PostLoadContent", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                    ));
    Hooking Onto Update and Draw
    Next, we want to hook onto Update and Draw. The difference here is that we now have functions that take arguments. In this case a 'GameTime' object which holds the time of the current XNA game. Looking at some of the function in a diassembler we'll see that using the GameTime object will look like this:
    Code:
     
        IL_1922: ldarg.0
        IL_1923: ldarg.1
        IL_1924: call instance void [Microsoft.Xna.Framework.Game]Microsoft.Xna.Framework.Game::Update(class [Microsoft.Xna.Framework.Game]Microsoft.Xna.Framework.GameTime)
        IL_1929: ret
    We see that two arguments are being pushed to Update. That's because this is a class method so ldarg.0 is the base Game object, and ldarg.1 is the GameTime object. So let's add our handlers first for Update:

    Code:
     
            public static void PreUpdate(GameTime gameTime)
            {
            }
            public static void PostUpdate(GameTime gameTime)
            {
            }
    Next we'll do the similar stuff to get the function. But we will add an extra opcode to push the gameTime argument:

    Code:
     
                MethodDefinition updateMethod = GetMethodDefinition(GetTypeDefinition("Main"), "Update");
                var updateProc = updateMethod.Body.GetILProcessor();
                var updateInst = updateMethod.Body.Instructions[0];
                updateProc.InsertBefore(updateInst, updateProc.Create(OpCodes.Ldarg_1)); // push gameTime
                updateProc.InsertBefore(updateInst, updateProc.Create(OpCodes.Call,
                    this.m_vModDefinition.Import(typeof(Hooks).GetMethod("PreUpdate", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                    ));
    Now, if you wish you could push Ldarg_0 as well to your function, but you will need to add the param for the Game object.

    Next we want to inject our PostUpdate call. The above IL code I posted about the Update function is the end of the function, so we know it ends with a Ret. We want to push our code, again, before the return.

    Code:
     
                updateProc.InsertBefore(updateMethod.Body.Instructions[updateMethod.Body.Instructions.Count - 1], updateProc.Create(OpCodes.Ldarg_1)); // push gameTime
                updateProc.InsertBefore(updateMethod.Body.Instructions[updateMethod.Body.Instructions.Count - 1], updateProc.Create(OpCodes.Call,
                    this.m_vModDefinition.Import(typeof(Hooks).GetMethod("PostUpdate", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                    ));
    For draw, we'll do the same thing. Add the two methods calls:

    Code:
     
            public static void PreDraw(GameTime gameTime)
            {
            }
            public static void PostDraw(GameTime gameTime)
            {
            }
    Then we'll add our hook code the same way as Update:

    Code:
     
                MethodDefinition drawMethod = GetMethodDefinition(GetTypeDefinition("Main"), "Draw");
                var drawProc = drawMethod.Body.GetILProcessor();
                var drawInst = drawMethod.Body.Instructions[0];
                drawProc.InsertBefore(drawInst, drawProc.Create(OpCodes.Ldarg_1)); // push gameTime
                drawProc.InsertBefore(drawInst, drawProc.Create(OpCodes.Call,
                    this.m_vModDefinition.Import(typeof(Hooks).GetMethod("PreDraw", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                    ));
    
                drawProc.InsertBefore(drawMethod.Body.Instructions[drawMethod.Body.Instructions.Count - 1], drawProc.Create(OpCodes.Ldarg_1));
                drawProc.InsertBefore(drawMethod.Body.Instructions[drawMethod.Body.Instructions.Count - 1], drawProc.Create(OpCodes.Call,
                    this.m_vModDefinition.Import(typeof(Hooks).GetMethod("PostDraw", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                    ));
    There we have it, all of the main XNA calls are now hooked as we wanted.


    Hooking Other Methods
    So now that we have hooked all the XNA methods, lets hook something else. In this case I will be using the collectors edition method CheckBunny. This method determines if you have the Collectors Edition of the game by looking in your Registry for a specific key. The IL of this code looks like:

    Code:
     
        .try
        {
            IL_0000: ldsfld class [mscorlib]Microsoft.Win32.RegistryKey [mscorlib]Microsoft.Win32.Registry::CurrentUser
            IL_0005: stloc.0
            IL_0006: ldloc.0
            IL_0007: ldstr "Software\\Terraria"
            IL_000c: callvirt instance class [mscorlib]Microsoft.Win32.RegistryKey [mscorlib]Microsoft.Win32.RegistryKey::CreateSubKey(string)
            IL_0011: stloc.0
            IL_0012: ldloc.0
            IL_0013: brfalse.s IL_0044
    
            IL_0015: ldloc.0
            IL_0016: ldstr "Bunny"
            IL_001b: callvirt instance object [mscorlib]Microsoft.Win32.RegistryKey::GetValue(string)
            IL_0020: brfalse.s IL_0044
    
            IL_0022: ldloc.0
            IL_0023: ldstr "Bunny"
            IL_0028: callvirt instance object [mscorlib]Microsoft.Win32.RegistryKey::GetValue(string)
            IL_002d: callvirt instance string [mscorlib]System.Object::ToString()
            IL_0032: ldstr "1"
            IL_0037: call bool [mscorlib]System.String::op_Equality(string, string)
            IL_003c: brfalse.s IL_0044
    
            IL_003e: ldc.i4.1
            IL_003f: stsfld bool Terraria.Main::cEd
    
            IL_0044: leave.s IL_004f
        } // end .try
        catch [mscorlib]System.Object
        {
            IL_0046: pop
            IL_0047: ldc.i4.0
            IL_0048: stsfld bool Terraria.Main::cEd
            IL_004d: leave.s IL_004f
        } // end handler
    
        IL_004f: ret
    However, instead of injecting anything, we'll just rewrite the entire method. We knw that we want to set the property cEd to true. Which can be done with:
    Code:
     
            IL_003e: ldc.i4.1
            IL_003f: stsfld bool Terraria.Main::cEd
    So we'll rewrite this method using:

    Code:
     
                MethodDefinition bunnyMethod = GetMethodDefinition(GetTypeDefinition("Main"), "CheckBunny");
                FieldDefinition bunnyField = GetFieldDefinition(GetTypeDefinition("Main"), "cEd");
    
                // Clear the old function instructions..
                bunnyMethod.Body.Instructions.Clear();
    
                // Remove the exception handler..
                bunnyMethod.Body.ExceptionHandlers.Clear();
    
                // Rewrite the function..
                var bunnyProc = bunnyMethod.Body.GetILProcessor();
                bunnyProc.Append(bunnyProc.Create(OpCodes.Nop)); // nop for alignment
                bunnyProc.Append(bunnyProc.Create(OpCodes.Ldc_I4_1)); // push true (1) onto the stack
                bunnyProc.Append(bunnyProc.Create(OpCodes.Stsfld, bunnyField)); // set field to the value on stack
                bunnyProc.Append(bunnyProc.Create(OpCodes.Ret)); // return
    My Methods Aren't Getting Called In The Right Order!
    With Terraria as an example you may notice that your XNA hooks may not be called in the right order. This is due to how Terraria is written. For example, Draw has multiple returns within it to handle drawing certain parts of the game. For instance, it will attempt to Draw the menu specifically with:

    Code:
     
        IL_52dd: ldarg.0
        IL_52de: call instance void Terraria.Main::DrawMenu()
        IL_52e3: ret
    Which will return before our PostDraw is called while we are at the main menu. There are a few ways to correct this. Without actually digging into the code here are some suggestions you can do to fix problems like:
    • Hook DrawMenu and call PostDraw at the end of it to ensure your PostDraw is called. (I recommend this method.)
    • Inject your PostDraw call after every Ret inside the function to ensure it gets called.
    • Disassemble the code and look to see where you should place each Post call to ensure that it will always be called. (This could become a tiresome process if its a large method.)
    atom0s is offline
    Reply With Quote

    Old 9th March 2012, 10:11 AM   #2
    ntKid
    h4x0!2

    ntKid's Avatar

    Join Date: Nov 2008
    Location: Portugal
    Posts: 101
    Reputation: 2302
    Rep Power: 380
    ntKid is a legend in the cheating communityntKid is a legend in the cheating communityntKid is a legend in the cheating communityntKid is a legend in the cheating communityntKid is a legend in the cheating communityntKid is a legend in the cheating communityntKid is a legend in the cheating communityntKid is a legend in the cheating communityntKid is a legend in the cheating communityntKid is a legend in the cheating communityntKid is a legend in the cheating community
    Recognitions Members who have contributed financial support towards UnKnoWnCheaTs. Donator (1)
    Points: 13,081, Level: 14
    Points: 13,081, Level: 14 Points: 13,081, Level: 14 Points: 13,081, Level: 14
    Level up: 61%, 519 Points needed
    Level up: 61% Level up: 61% Level up: 61%
    Activity: 0%
    Activity: 0% Activity: 0% Activity: 0%
    #pragma comment( legend, "atom0s" )
    +rep
    __________________
    ntKid is offline
    Reply With Quote

    Old 9th March 2012, 05:42 PM   #3
    atom0s
    Supreme H4x0|2

    atom0s's Avatar

    Threadstarter
    Join Date: Dec 2011
    Posts: 590
    Reputation: 5557
    Rep Power: 313
    atom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATS
    Points: 17,859, Level: 18
    Points: 17,859, Level: 18 Points: 17,859, Level: 18 Points: 17,859, Level: 18
    Level up: 4%, 1,441 Points needed
    Level up: 4% Level up: 4% Level up: 4%
    Activity: 0%
    Activity: 0% Activity: 0% Activity: 0%
    Last Achievements C# Loader Hooking With Mono.CecilC# Loader Hooking With Mono.CecilC# Loader Hooking With Mono.Cecil
    Heh thanks. Another fun thing you can do is use a custom attribute to automatically find methods in your application that will be applying detours/edits to the new assembly and execute them like this:

    InjectionAttribute.cs
    Code:
    // -----------------------------------------------------------------------
    // <copyright file="InjectionAttribute.cs" company="">
    // TODO: Update copyright text.
    // </copyright>
    // -----------------------------------------------------------------------
    
    namespace toxyClient.Classes
    {
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
    
        /// <summary>
        /// InjectionAttribute Class Implementation
        /// 
        /// Attribute used to mark a function as an injection function.
        /// 
        /// The main program class will scan the application for this
        /// attribute and automatically call the functions.
        /// </summary>
        public class InjectionAttribute : Attribute
        {
            /// <summary>
            /// Default Constructor
            /// </summary>
            /// <param name="detourName"></param>
            /// <param name="detourDesc"></param>
            public InjectionAttribute(String detourName, String detourDesc = "")
            {
                this.Name = detourName;
                this.Desc = detourDesc;
            }
    
            /// <summary>
            /// Gets or sets the name of this detour.
            /// </summary>
            public String Name { get; set; }
    
            /// <summary>
            /// Gets or sets the desc of this detour.
            /// </summary>
            public String Desc { get; set; }
        }
    }
    Then in your main Program.cs code use this before you call Finalize:
    Code:
                // Scan for detour attributes and apply their detour..
                (from Type t in Assembly.GetExecutingAssembly().GetTypes()
                 from MethodInfo m in t.GetMethods()
                 from InjectionAttribute d in m.GetCustomAttributes(typeof(InjectionAttribute), false)
                 select m).ToList().ForEach(m => m.Invoke(null, null));
    Then any function that you want to apply detours/injection stuff with to the new assembly just mark with the new custom attribute like this:

    Code:
            /// <summary>
            /// Applies the detours required by this class.
            /// </summary>
            [Injection("Some Name Here", "A short description about what this function is for.")]
            public static void DoInjection()
            {
            }
    atom0s is offline
    Reply With Quote

    Old 14th April 2012, 10:30 AM   #4
    w00tare
    Super H4x0r

    w00tare's Avatar

    Join Date: Jul 2010
    Location: The Netherlands
    Posts: 313
    Reputation: 477
    Rep Power: 340
    w00tare has just learned Packet Editing Doesnt Involve food toppings anymorew00tare has just learned Packet Editing Doesnt Involve food toppings anymorew00tare has just learned Packet Editing Doesnt Involve food toppings anymorew00tare has just learned Packet Editing Doesnt Involve food toppings anymorew00tare has just learned Packet Editing Doesnt Involve food toppings anymore
    Recognitions Members who have contributed financial support towards UnKnoWnCheaTs. Donator (2)
    Points: 9,925, Level: 12
    Points: 9,925, Level: 12 Points: 9,925, Level: 12 Points: 9,925, Level: 12
    Level up: 11%, 1,075 Points needed
    Level up: 11% Level up: 11% Level up: 11%
    Activity: 0%
    Activity: 0% Activity: 0% Activity: 0%
    Last Achievements C# Loader Hooking With Mono.CecilC# Loader Hooking With Mono.Cecil
    Pretty interesting, I've looked over it quickly but I bookmarked it to read it later, thanks! +rep


    Quote:
    Originally Posted by atom0s View Post
    About This Tutorial
    As far as I know Mono.Cecil only works for recreating a binary before it is loaded. I am not sure if it will allow runtime reconstruction, nor have I tried to get it to so. So if you know if it can please do let me know.
    You can't modify/reconstruct the binary when its loaded, well you can but not with Mono.Cecil.

    Last edited by w00tare; 14th April 2012 at 10:34 AM.
    w00tare is offline
    Reply With Quote

    Old 14th April 2012, 10:14 PM   #5
    atom0s
    Supreme H4x0|2

    atom0s's Avatar

    Threadstarter
    Join Date: Dec 2011
    Posts: 590
    Reputation: 5557
    Rep Power: 313
    atom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATSatom0s DEFINES UNKNOWNCHEATS
    Points: 17,859, Level: 18
    Points: 17,859, Level: 18 Points: 17,859, Level: 18 Points: 17,859, Level: 18
    Level up: 4%, 1,441 Points needed
    Level up: 4% Level up: 4% Level up: 4%
    Activity: 0%
    Activity: 0% Activity: 0% Activity: 0%
    Last Achievements C# Loader Hooking With Mono.CecilC# Loader Hooking With Mono.CecilC# Loader Hooking With Mono.Cecil
    Quote:
    Originally Posted by w00tare View Post
    Pretty interesting, I've looked over it quickly but I bookmarked it to read it later, thanks! +rep




    You can't modify/reconstruct the binary when its loaded, well you can but not with Mono.Cecil.
    Yeah, there are a few other libs like PostSharp that are supposed to be able to do it but I haven't bothered looking into them. And doing manual patches for everything is too much of a hassle. Mono.Cecil handles things pretty well for how it has to be used though.
    atom0s is offline
    Reply With Quote

    Old 3rd October 2013, 01:10 AM   #6
    omnichroma
    n00bie

    omnichroma's Avatar

    Join Date: Oct 2013
    Posts: 1
    Reputation: 10
    Rep Power: 259
    omnichroma has made posts that are generally average in quality
    Can you post what the final files look like please?
    omnichroma is offline
    Reply With Quote

    Old 3rd October 2013, 08:18 AM   #7
    learn_more
    Retired Administrator

    learn_more's Avatar

    Join Date: Sep 2006
    Posts: 14,760
    Reputation: 162909
    Rep Power: 739
    learn_more has a huge epeen!learn_more has a huge epeen!learn_more has a huge epeen!learn_more has a huge epeen!learn_more has a huge epeen!learn_more has a huge epeen!learn_more has a huge epeen!learn_more has a huge epeen!learn_more has a huge epeen!learn_more has a huge epeen!learn_more has a huge epeen!
    Recognitions Members who have contributed financial support towards UnKnoWnCheaTs. Donator (48)
    Award symbolizing a retired staff member who dedicated a notable amount of time and effort to their past staff position. Former Staff
    Awarded to members who have donated 10 times or more. Gratuity (4)
    Points: 255,107, Level: 59
    Points: 255,107, Level: 59 Points: 255,107, Level: 59 Points: 255,107, Level: 59
    Level up: 26%, 238,893 Points needed
    Level up: 26% Level up: 26% Level up: 26%
    Activity: 0%
    Activity: 0% Activity: 0% Activity: 0%
    Last Achievements C# Loader Hooking With Mono.CecilC# Loader Hooking With Mono.CecilC# Loader Hooking With Mono.CecilC# Loader Hooking With Mono.CecilC# Loader Hooking With Mono.Cecil
    Award-Showcase C# Loader Hooking With Mono.Cecil
    that will only encourage copypasting without understanding it.
    learn_more is offline
    Reply With Quote
    Reply


    Similar Threads
    Thread Thread Starter Forum Replies Last Post
    [Tutorial] [Tutorial]Vtable hooking / VMT hooking in unreal engine (c++) EddyK Unreal Engine 3 11 31st December 2013 03:35 PM
    Hooking Windows API - Technics of hooking API functions on Windows Roverturbo General Programming and Reversing 6 13th December 2012 01:11 PM
    [Help] Help with aceton loader and generic loader!! pinoy Generals and Zero Hour 2 3rd June 2005 03:59 AM
    [Question] d2 loader I NEED HELP dark_knight1 Diablo Series 0 10th May 2004 03:29 PM
    [Request] i need no cd loader dark_knight1 Diablo Series 0 9th May 2004 06:35 PM

    Tags
    hooking, loader, monocecil


    Forum Jump


    All times are GMT. The time now is 11:15 AM.

    Contact Us - Toggle Dark Theme
    Terms of Use Information Privacy Policy Information
    Copyright ©2000-2024, Unknowncheats™
    C# Loader Hooking With Mono.Cecil
    sponsored advertisement
    no new posts