Hook Guide
Introduction
Hook is a technique for modifying the behavior of functions at runtime. It is commonly used to alter the behavior of functions without modifying the original source code.
Explanation of Hook on Wikipedia: Hooking
In LeviLamina, we provide well-packaged Hook APIs, allowing you to quickly and conveniently modify the behavior of game functions in Minecraft Bedrock Dedicated Servers (referred to as BDS
).
Defines of Hooks
In ll/api/memory/Hook.h
, we defined the following Hook macros:
C++ | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
The AUTO-marked Hooks automatically register, i.e., call the hook() function to register at runtime. The TYPED-marked Hooks inherit your DEF_TYPE to the specified type.
STATIC_HOOK
For hooking static functions.
INSTANCE_HOOK
For hooking member functions.
Explanation of Hook Parameters
DEF_TYPE
: The type name you give to your Hook.
PRIORITY
: Hook priority, e.g., ll::memory::HookPriority::Normal
Note
Generally, unless there's a special need, we do not recommend a very high priority; Normal is sufficient.
TYPE
: The type to which your defined DEF_TYPE is inherited.
IDENTIFIER
: The identifier used for the Hook lookup function, which can be: function's decorated name, function bytecode, function definition.
RET_TYPE
: The return type of the Hook function.
...
: The parameter list of the Hook function.
Using Hooks
You can refer to static program analysis tools, such as IDA Pro, to obtain the symbols or signatures of the functions you want to Hook.
Or refer to the Fake Header
provided by LeviLamina to obtain the symbols or definitions of the functions you want to Hook.
A Simple Hook Example
C++ | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
This code hooks the constructor of DedicatedServer and prints a log message when the constructor is called.
Analysis:
Referring to the DedicatedServer.h
provided by LeviLamina, we know that the symbol for DedicatedServer's constructor is ??0DedicatedServer@@QEAA@XZ
.
Since the constructor is a member function of the class, we used the INSTANCE_HOOK
type of Hook, which means we don't need to fill in the first this pointer
parameter generated by the compiler.
We used the AUTO
-marked Hook because we want it to automatically register when the plugin is loaded.
Finally, for convenience, we used the TYPE
-marked Hook, so we can directly call functions under the DedicatedServer type in the function body. Although we did not use it in this code, it is a good habit.
Registering and Unloading Hooks
Registration
For non-automatically registered Hooks, you need
to call the hook()
function to register at the moment your plugin needs to register the Hook.
Unloading
All Hooks will automatically unload when BDS unloads. You can also call the unhook()
function to unload when your plugin needs to unload the Hook.
In Conclusion
Hook is a very powerful technique but also a double-edged sword. If used improperly, it can cause crashes of the BDS core or plugins, and in severe cases, affect the game saves.
Therefore, please be cautious when using Hooks, check your code carefully to avoid unnecessary errors.