Page 1 of 1
[CSGO] Hooking AcceptInput
Posted: Sat Oct 20, 2018 3:40 am
by VinciT
I'm trying to hook
CBaseEntity::AcceptInput and I keep getting '
ESP not present' (followed by a crash) whenever the hook is called.
This is the offset I've added (
thanks to SM):
Syntax: Select all
# bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
[[accept_input]]
offset_linux = 41
offset_windows = 40
arguments = POINTER, POINTER, POINTER, POINTER, INT
return_type = BOOL
Am I messing up the arguments or is there something else at play here?
Re: [CSGO] Hooking AcceptInput
Posted: Sat Oct 20, 2018 5:48 am
by L'In20Cible
You need to specify the convention. It is defaulted to
CDECL and you are hooking a THISCALL method. Also, your prototype is not right. Should be:
Syntax: Select all
# bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
[[accept_input]]
offset_linux = 41
offset_windows = 40
arguments = POINTER, STRING, POINTER, POINTER, POINTER, INT
return_type = BOOL
convention = THISCALL
However, instead of hooking that method it would be easier to get the specific input function you want to hook from the datamaps and hook it directly. That way you don't have to use signatures.
Re: [CSGO] Hooking AcceptInput
Posted: Sat Oct 20, 2018 6:04 am
by Ayuto
You don't need to specify the convention. It's already thiscall in that data file.
Re: [CSGO] Hooking AcceptInput
Posted: Sat Oct 20, 2018 7:12 am
by L'In20Cible
Ayuto wrote:You don't need to specify the convention. It's already thiscall in that data file.
What file?

Re: [CSGO] Hooking AcceptInput
Posted: Sat Oct 20, 2018 9:05 am
by Ayuto
I guess it's the file to reconstruct the CBaseEntity class. When the file is parsed, SP already assumes THISCALL plus the this pointer is added automatically to the arguments.
Re: [CSGO] Hooking AcceptInput
Posted: Sat Oct 20, 2018 3:44 pm
by VinciT
Thanks for the quick replies! Sadly, it's still crashing. I'm trying to get the player that used a
func_button to trigger something else (in this case a func_door).
I tried using the OnEntityOutput listener for this, but it doesn't trigger for some entities. So I thought I should hook the input instead. This is my test code:
Syntax: Select all
# ../door_test/door_test.py
# Source.Python
from entities.hooks import EntityPreHook, EntityCondition
is_door = EntityCondition.equals_entity_classname('func_door')
@EntityPreHook(is_door, 'accept_input')
def pre_accept_input(stack_data):
print(stack_data)
Without setting the convention in the .ini file, I get the following error:
Code: Select all
[SP] Caught an Exception:
Traceback (most recent call last):
File "..\addons\source-python\plugins\door_test\door_test.py", line 12, in pre_accept_input
print(stack_data)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd9 in position 2: invalid continuation byte
ESP not present.
If I set the convention, I get two errors:
Code: Select all
[SP] Caught an Exception:
Traceback (most recent call last):
File "..\addons\source-python\packages\source-python\memory\helpers.py", line 144, in as_conventio
n
return Convention.names[value]
KeyError: 'thiscall'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "..\addons\source-python\packages\source-python\plugins\command.py", line 162, in load_plugin
plugin = self.manager.load(plugin_name)
File "..\addons\source-python\packages\source-python\plugins\manager.py", line 194, in load
plugin._load()
File "..\addons\source-python\packages\source-python\plugins\instance.py", line 74, in _load
self.module = import_module(self.import_name)
File "..\addons\source-python\plugins\door_test\door_test.py", line 10, in <module>
@EntityPreHook(is_door, 'accept_input')
File "..\addons\source-python\packages\source-python\entities\hooks.py", line 129, in __call__
if self.initialize(entity):
File "..\addons\source-python\packages\source-python\entities\hooks.py", line 162, in initialize
self.hooked_function = getattr(entity, self.function)
File "..\addons\source-python\packages\source-python\entities\_base.py", line 107, in __getattr__
for server_class in self.server_classes:
File "..\addons\source-python\packages\source-python\entities\_base.py", line 244, in server_class
es
yield from server_classes.get_entity_server_classes(self)
File "..\addons\source-python\packages\source-python\entities\classes.py", line 198, in get_entity
_server_classes
datamap=entity_datamaps.get(class_name, {}),
File "..\addons\source-python\packages\source-python\entities\classes.py", line 232, in _get_serve
r_class
instance = self.create_type_from_file(class_name, manager_contents)
File "..\addons\source-python\packages\source-python\memory\manager.py", line 342, in create_type_
from_file
type_name, GameConfigObj(f), bases)
File "..\addons\source-python\packages\source-python\memory\manager.py", line 413, in create_type_
from_dict
for name, data in vfuncs:
File "..\addons\source-python\packages\source-python\memory\helpers.py", line 397, in parse_data
value if value is default else converter(manager, value))
File "..\addons\source-python\packages\source-python\memory\helpers.py", line 146, in as_conventio
n
return manager.custom_conventions[value]
KeyError: 'thiscall'
Code: Select all
[SP] Caught an Exception:
Traceback (most recent call last):
File "..\addons\source-python\packages\source-python\entities\hooks.py", line 227, in on_entity_cr
eated
_waiting_entity_hooks.initialize(base_entity.index)
File "..\addons\source-python\packages\source-python\entities\hooks.py", line 212, in initialize
if hook.initialize(entity):
File "..\addons\source-python\packages\source-python\entities\hooks.py", line 162, in initialize
self.hooked_function = getattr(entity, self.function)
File "..\addons\source-python\packages\source-python\entities\_base.py", line 116, in __getattr__
raise AttributeError('Attribute "{0}" not found'.format(attr))
AttributeError: Attribute "accept_input" not found
Re: [CSGO] Hooking AcceptInput
Posted: Sat Oct 20, 2018 4:35 pm
by VinciT
I tried using the offset with only one argument, to see if it would work, and it does! No more crashing.
Syntax: Select all
(<_memory.Pointer object at 0x0EDB4DA0>, 'Use')
Syntax: Select all
[[accept_input]]
offset_linux = 41
offset_windows = 40
arguments = STRING
return_type = BOOL
But there's a problem - the buttons aren't sending any outputs. I added return True at the end of the hook, but they're still broken.
Then I tried adding another argument (POINTER) and it started crashing again.
Re: [CSGO] Hooking AcceptInput
Posted: Sat Oct 20, 2018 5:16 pm
by Ayuto
Could you please post the output of "sp info". Also, to which ini-file have you added the data (I'm assuming some CBaseEntity.ini in Source.Python's data files).
You get the KeyError if you specify the convetion, because it's case-sensitive (use upper case). Also, you don't necessarily need the quotes.
Re: [CSGO] Hooking AcceptInput
Posted: Sat Oct 20, 2018 5:30 pm
by VinciT
Code: Select all
--------------------------------------------------------
Checksum : 405a773ffd84ab3fe11824740fa5cb2b
Date : 2018-10-20 17:27:09.301686
OS : Windows-8.1-6.3.9600
Game : csgo
SP version : 663
Github commit : d13b5c9e380d021166ac6ab5ce487fafeea686e7
Server plugins:
00: Source.Python, (C) 2012-2018, Source.Python Team.
SP plugins:
00: door_test
--------------------------------------------------------
Yep, your assumption is correct. I added it directly to SP's CBaseEntity.ini (..csgo\addons\source-python\data\source-python\entities\csgo\CBaseEntity.ini)
I changed the convention to THISCALL, but it's still crashing whenever I add the second argument to the data.
Re: [CSGO] Hooking AcceptInput
Posted: Sat Oct 20, 2018 7:32 pm
by Ayuto
On Windows the variant_t argument, which has the size of 20 bytes, gets copied to the stack instead of a single pointer that gets pushed to the stack. Thus, we need to add a few fake arguments, so we don't mess up the stack:
Code: Select all
# bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
[[accept_input]]
offset_linux = 41
offset_windows = 40
arguments_linux = STRING, POINTER, POINTER, POINTER, INT
arguments_windows = STRING, POINTER, POINTER, POINTER, POINTER, POINTER, POINTER, POINTER, INT
return_type = BOOL
I haven't tested it, but you should be able to access the arguments like this on Windows:
Code: Select all
# args[0] = this
# args[1] = input_name
# args[2] = activator
# args[3] = caller
# args[8] = value
# args[9] = output_id
Re: [CSGO] Hooking AcceptInput
Posted: Sat Oct 20, 2018 8:54 pm
by VinciT
Ayuto, you're amazing! It works! Thank you so much.