Giter Club home page Giter Club logo

Comments (15)

pardeike avatar pardeike commented on May 11, 2024 1

Right now, you can’t. I am working on an update that might have annotations for specifying parameter names, or a way to access all of them via an array.

The best option you have for now is to use a transpiler.

Regarding multiple overloads: you can only replace code that actually exists as IL in the dll. So basically any implementation. If you use a disassembler it becomes clear. In case of overloads you need to pick the class/method you want to change.

from harmony.

pardeike avatar pardeike commented on May 11, 2024 1

Actually, no. Harmony uses the known way to repoint a method to another method by inserting an assembler jump into the assembler methods start. What it does differently is that it has a high level way to define the new method. Where other solutions require you to write your own replacement method, Harmony does this by manipulating the original IL code. This has the advantage that multiple plugins can patch the same original method without overwriting each other.

The unsolved problem with this is that inlined methods cannot be redirected. Already jitted code is not a problem because to insert the assembler jump, Harmony forces a jit anyway.

from harmony.

shroudedmods avatar shroudedmods commented on May 11, 2024 1

One thing I'm not clear about: It seems to be quite complicated to clone the original method's IL and do all the rewriting of operands and branches and stuff. For non-transpiled cases, wouldn't it be easier to clone the original wholesale, without changing anything, then create a separate dynamic method that does the prefix and postfix stuff, with a call to the clone in the middle? Then make the second dynamic method the target of the hook?

from harmony.

pardeike avatar pardeike commented on May 11, 2024 1

Use Microsoft’s official documentation. CIL isn’t that hard to learn. It’s actually a very lean stack based byte code based language.

The reason why I don’t do it the way you suggested is that it does not allow for advanced transpiler handling. It is also less useful in situations where you need performance and makes input parameter manipulations more complicated. Personally, I find the IL copying not that hard compared to all the rest you have to do anyway.

from harmony.

pardeike avatar pardeike commented on May 11, 2024 1

See discussion in #20 too

from harmony.

pardeike avatar pardeike commented on May 11, 2024 1

If you’re really into the ultimate performance you need to use transpilers and direct IL code access. That will jit into optimized assembler and is not too hard to accomplish. I do it all the time.

from harmony.

bugproof avatar bugproof commented on May 11, 2024

That's great! Harmony is currently the best hooking library for C#. I would be interested in a blog post describing how it all works. For example what happens if the method is already JITted ? How does it hook it? From what I understand by reading the code it patches only IL and doesn't touch generated assembly at all?

from harmony.

bugproof avatar bugproof commented on May 11, 2024

Ah yes I see now it uses GetRuntimeMethodHandle to get a handle to JITted function in memory which is in native assembly by accessing the fields like mhandle for mono. So basically that part is just like a traditional jmp hook in native world. IL copying part like shroudedmods says is pretty complicated though. I also imagined this like that (common hooking we know from C++ world):

Pseudo code:
var originalFunc = hook(targetMethod, newMethod);

and then I would call the original myself on top of the original call for pre-hook and on the bottom for post-hook.

I was thinking of making my own hooking library before I found Harmony what I was planning to do is hooking JIT mono methods like mono_compile_method or mono_jit_runtime_invoke in C++ but that would work only for mono and I would have to think of a wrapper for C#/C++ CLR to actually make this work in high-level. Unfortunately I don't understand IL as good as x86/x64 😄

Also can you recommend any good read about IL?

from harmony.

bugproof avatar bugproof commented on May 11, 2024

Yeah it would be much easier if microsoft provided something like inline IL ASM like __asm in MSVC. Your approach is good

I think I just found the place needed to patch for obfuscated parameters support.
static void EmitCallParameter(ILGenerator il, MethodBase original, MethodInfo patch, Dictionary<string, LocalBuilder> variables)

Do you have time to work on it right now or would you accept a PR if I requested it?

from harmony.

pardeike avatar pardeike commented on May 11, 2024

I have some things in my life that need attention so my work on Harmony is slow. I think the best would be to solve this in a fork and submit a pull request. I suggest method annotations. Also check the existing pull requests for what I think is a method array implementation. I’m not totally sure it is in there but I remember someone asking for it.

from harmony.

bugproof avatar bugproof commented on May 11, 2024

The only problem with method attributes is that it's repeating. What could be cleaner is class attribute or actually we can add two or even three possibilities of renaming. What DoctorVanGogh proposed are parameter attributes.

I'm just thinking what would be the cleaniest way to accomplish this. Manual patching must work with this as well.

1. Class attributes

[HarmonyParameter("#df", "renamedParam")]
class My_Patch {
    static void Prefix(int renamedParam) {
    }
    static void Postfix(int renamedParam) {
    }
}

2. Method attributes

class My_Patch {
    [HarmonyParameter("#df", "renamedParam")]
    static void Prefix(int renamedParam) {
    }

    [HarmonyParameter("#df", "renamedParam")]
    static void Postfix(int renamedParam) {
    }
}

3. Parameter attributes

class My_Patch {
    static void Prefix([HarmonyParameter("#df")] int renamedParam) {
    }
    static void Postfix([HarmonyParameter("#df")] int renamedParam) {
    }
}

Maybe could be shorter with just Param/Parameter as the name.

The idea with special names as attributes is nice too, but removing special names would actually break existing codes using the library. The parameters could be passed in special name too like __params and it would just be an array/dictionary or other appropriate type of all parameters with name and value. Like this:

4. Magic name

class My_Patch {
    static void Prefix(Dictionary<string, object> __params) {
        int p1 = __params["#d"] as int;
    }
}
class My_Patch {
    static void Prefix(HarmonyParameters __params) {
        int p1 = __params.Get<int>("#d");
    }
}

Also some additional ideas for issue #20

class My_Patch {
    static void Prefix(Character __instance ) {
        // Some reflection helper?
        HarmonyAccessor accessor = new HarmonyAccessor(__instance);
        int f1 = accessor.GetField<int>("m_health");
        int staticfield = accessor.GetStaticField<int>("s_field");
        ...
    }
}

Or like mentioned in #20 fields could be injected with attributes too... Why not just implement all these features so everyone will use what they like? 😃

Personally I have nothing against magic names it's clean and nice. Just the only problem I encountered is when names are obfuscated.

from harmony.

bugproof avatar bugproof commented on May 11, 2024

Also for reflection it would be good to have some kind of cache, there are already existing implementations for fast reflection especially when we deal with games. I saw some library that emits IL to generate delegates for fast reflection. It would kinda suck if it would search for a field every frame for instance 🙁

from harmony.

pardeike avatar pardeike commented on May 11, 2024

Such a lib is already included in Harmony. Check out FastAccess

from harmony.

bugproof avatar bugproof commented on May 11, 2024

It could be improved by caching delegates otherwise they would have to be global or something and initialized only once. The lib I mentioned is here: https://github.com/vexe/Fast.Reflection and https://github.com/buunguyen/fasterflect very similar though.

from harmony.

bugproof avatar bugproof commented on May 11, 2024

I've noticed there's some sort of reflection helper with cache already: https://github.com/pardeike/Harmony/blob/master/Harmony/Tools/Traverse.cs

Please see my PR: #52 if you like it you might pull and close the issue. Works for me.

I also wanted to add magic __params but I couldn't really think how would it work and I don't know how to push arrays in IL so when I change entry in the array it changes the original parameter value.

It would be super cool to inject members through parameter attributes. I wonder if it's possible to inject them as references so when you assign it assigns like you would call SetValue with reflection

from harmony.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.