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 or player_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