Delegate function hooking #132
Replies: 2 comments
-
What's the use-case for this ? I'm unable to come up with a reason why knowing what delegate triggered the UFunction would be important. I did some cursory checking and to support this, we'd most likely need to add yet another AOB to the already long list of AOBs that we scan for. The call-stack for
|
Beta Was this translation helpful? Give feedback.
-
The user story is like: There is a UI that defines a delegate for when some data loads. You may want to be a delegate, prevent all the delegates from running, or change the data before it reaches those delegates. You can't be certain what delegates are being dispatched to, maybe they're blueprints that aren't always loaded. So you can't just hook those ufunctions, you'd need to preestablish all blueprints that might have the delegate to modify them with bpmodloader. Maybe you could generally hook SomeDelegateName__Event regardless of the class owner if wildcard support is added to RegisterHook, as we might be guaranteed that naming shceme, but there's a conflict issue when a game has ClassA.SomeDelegate as well as ClassB.SomeDelegate with different signatures. I'll keep looking for an easier way to do this that doesn't introduce a new hook, no problem. I do kind of want to replace the pattern scanning system with something that is more compatible/reliable with different versions - for example, find references to string "Invalid object name" and walk up to the first call instruction to find the FName constructor. This exists on retail builds as well as debug/unoptimized builds, and isn't going to break due to compiler differences or optimization level differences. I think it can be made much more reliable introducing a little bit of program analysis like this, and the sporadic use of zydis is a good foundation. Thanks for the call stack & pointers! |
Beta Was this translation helpful? Give feedback.
-
It'd be convenient to have a hook on delegate dispatch. They reach processevent eventually, but at that point I don't think we can easily recover the delegate this ufunction was dispatched because of (correct me if I'm wrong). The options of TScriptDelegate, FMulticastDelegate, FMulticastInlineDelegate, and FMulticastSparseDelegate complicate matters. The multicast types all get their
InvocationList
member from the same base class, TMulticastScriptDelegate, which makes life a little easier, maybe, if delegates were to be supported in a more simple way where we allow you to fetch the bound func or getter/setter the TArray InvocationList.Here are some notes from looking for where this could most easily be done:
FCallDelegateHelper::CallMulticastDelegate
I don't quite follow who invokes this, but we should be reaching it via a user of FUNC_DECLARE_DYNAMIC_MULTICAST_DELEGATE invoking Broadcast (or execute/executeifbound for the non-multicast delegates)
TMulticastScriptDelegate::ProcessMulticastDelegate
Templated, invoked from CallMulticastDelegate, and the template is code-generated by the macro for UHT emitted here.. Likely multiple sites to hook. Inconvenient.
Beta Was this translation helpful? Give feedback.
All reactions