memory.hooks module¶
Provides memory hooking functionality.
-
class
memory.hooks.
HookType
¶ Bases:
Boost.Python.enum
-
POST
= _memory.HookType.POST¶
-
PRE
= _memory.HookType.PRE¶
-
names
= {'PRE': _memory.HookType.PRE, 'POST': _memory.HookType.POST}¶
-
values
= {0: _memory.HookType.PRE, 1: _memory.HookType.POST}¶
-
-
class
memory.hooks.
PostHook
(function)[source]¶ Bases:
memory.hooks._Hook
Decorator class used to create post hooks that auto unload.
-
hook_type
= _memory.HookType.POST¶
-
-
class
memory.hooks.
PreHook
(function)[source]¶ Bases:
memory.hooks._Hook
Decorator class used to create pre hooks that auto unload.
-
hook_type
= _memory.HookType.PRE¶
-
-
memory.hooks.
set_hooks_disabled
((bool)arg1) → None :¶ Set whether or not hook callbacks are disabled.
Parameters: disabled (bool) – If True
, hook callbacks are disabled.
-
memory.hooks.
get_hooks_disabled
() → bool :¶ Return whether or not hook callbacks are disabled.
Return type: bool
-
memory.hooks.
hooks_disabled
(disabled=True)[source]¶ Temporarily disable or enable all hook callbacks. By default hooks are enabled. Thus, this context manager is mainly used to temporarily disable hook callbacks. If the context ends, the original value is restored. This can be used e. g. to avoid recursive calls when damaging a player in a
on_take_damage
hook orplayer_hurt
event.Note
This would only disable hooks created with Source.Python. Hooks that have been created by other server plugins will still be called.
Example:
from players.entity import Player from memory.hooks import hooks_disabled # Get a Player instance of the player with index 1 player = Player(1) # Damage the player. This would call e. g. on_take_damage hooks player.take_damage(5) # To avoid calling the on_take_damage hooks, use the following: with hooks_disabled() player.take_damage(5)
-
memory.hooks.
use_pre_registers
(stack_data, value=True)[source]¶ Temporarily set
StackData.use_pre_registers
to the given value. When the context ends, the previous value is restored.Some functions overwrite CPU registers during their execution with values from their internal calculations. In a post-hook, you have access to the modified CPU registers, but in some cases you might want to access the registers that were saved before the pre-hook was called. In that case you can use this context manager to get access to the previous state of the registers. On Windows this is often required when hooking THISCALL functions, because the this-pointer is saved in the CPU register
ECX
, but gets overwritten during the execution of the hooked function. So, in a post-hook you won’t have access to the this-pointer anymore.Example (CS:S/Windows):
from entities.hooks import EntityCondition from entities.hooks import EntityPostHook from entities.hooks import EntityPreHook from memory.hooks import use_pre_registers @EntityPreHook(EntityCondition.is_player, 'drop_weapon') def pre_on_drop_weapon(stack_data): print(f'PRE: this = {stack_data[0].address}') @EntityPostHook(EntityCondition.is_player, 'drop_weapon') def post_on_drop_weapon(stack_data, ret_val): print(f'POST FALSE: this = {stack_data[0].address}') with use_pre_registers(stack_data): print(f'POST CORRECT: this = {stack_data[0].address}')
Output:
PRE: this = 546778280 POST FALSE: this = 16439007 POST CORRECT: this = 546778280