Jump to content
View in the app

A better way to browse. Learn more.

Tuts 4 You

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

[C#] dnlib patcher code

Featured Replies

Posted

Today I wrote a small class that assists with patching .NET binaries.

using System;
using System.IO;
using dnlib.DotNet;
using dnlib.DotNet.Emit;

namespace MyNamespace
{
    class Patcher
    {
        public delegate bool PatchStrategy(AssemblyDef asm);

        private static bool patchMethodReturnBool(AssemblyDef asm, string classPath, string methodName, bool returnValue, int numArguments = 0)
        {
            var method = findMethod(asm, classPath, methodName);
            if (method != null && method.Parameters.Count == numArguments)
            {
                //patch instructions
                var instructions = method.Body.Instructions;
                if (returnValue)
                    instructions.Insert(0, OpCodes.Ldc_I4_1.ToInstruction()); //true
                else
                    instructions.Insert(0, OpCodes.Ldc_I4_0.ToInstruction()); //false
                instructions.Insert(1, OpCodes.Ret.ToInstruction());
                return true;
            }
            return false;
        }

        private static MethodDef findMethod(TypeDef type, string methodName)
        {
            if (type != null)
            {
                foreach (var method in type.Methods)
                {
                    if (method.Name == methodName)
                        return method;
                }
            }
            return null;
        }

        private static MethodDef findMethod(AssemblyDef asm, string classPath, string methodName)
        {
            return findMethod(findType(asm, classPath), methodName);
        }

        private static TypeDef findType(AssemblyDef asm, string classPath)
        {
            foreach (var module in asm.Modules)
            {
                foreach (var type in module.Types)
                {
                    if (type.FullName == classPath)
                        return type;
                }
            }
            return null;
        }

        public static bool PatchAssembly(string path, ref string error, PatchStrategy patcher)
        {
            var bakpath = path + ".bak";
            try
            {
                //handle backup
                if (!File.Exists(bakpath))
                    File.Copy(path, bakpath);
                else
                    File.Copy(bakpath, path, true);
            }
            catch (Exception x)
            {
                error = x.ToString();
                return false;
            }
            try
            {
                DateTime creationTime = File.GetCreationTime(path);

                //load module
                var module = ModuleDefMD.Load(File.ReadAllBytes(path));

                //execute patching strategy
                if (!patcher(module.Assembly))
                    return false;

                //write assembly
                if (module.IsILOnly)
                    module.Write(path);
                else
                    module.NativeWrite(path);

                //restore file date
                File.SetLastWriteTime(path, creationTime);
                File.SetCreationTime(path, creationTime);
                return true;
            }
            catch (Exception x)
            {
                File.Copy(bakpath, path, true);
                error = x.ToString();
            }
            return false;
        }
    }
}

For every patch you write a strategy like this:

public static bool PatchRegistrationCheck(AssemblyDef asm)
{
    string classPath = "MyNamespace.MyClass";
    /*
     * public bool IsRegistered(RegistrationData rd)
     * {
     *     return true;
     * }
     */
    if (!patchMethodReturnBool(asm, classPath, "IsRegistered", true, 2)) //2 parameters (this + rd)
        throw new Exception("MyClass.IsRegistered not patched!");
    return true;
}

Then you call it like this:

Patcher.PatchAssembly(filePath, Patcher.PatchRegistrationCheck);

Hope it will be useful for some of you.

Greetings

Edited by Mr. eXoDia

Create an account or sign in to comment

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.