21.08.2014, 14:08
Hey.
I am trying to find a way how to hook into callbacks in my plugin.
I do not want to depend on any pawn code here:
I want to hook a callback directly by swapping their address with the address of my callback (and calling the original callback then...)
I already worked out how to do this with natives (functions):
Hooking Natives (functions)
This works for natives... but now lets try callbacks (which are publics)
I am not an expert in the field of embedded scripting but I guess if I copy the original address of any callback and then call it in my hooked address this should work... shouldn't it?
Unfortunately the server just crashes because of an exception...
This is my code:
Hooking Callbacks (publics?)
My suggestions:
Thank you for any help!
I am trying to find a way how to hook into callbacks in my plugin.
I do not want to depend on any pawn code here:
Код:
public OnPlayerConnect(playerid) { return hook_OnPlayerConnect(playerid); }
I already worked out how to do this with natives (functions):
Hooking Natives (functions)
Код:
AMX_NATIVE original_SetPlayerHealth; cell AMX_NATIVE_CALL hook_SetPlayerHealth(AMX *amx, cell *params) { logprintf(" SetPlayerPos called! Player did not use health cheat..."); return original_SetPlayerHealth(amx, params); } PLUGIN_EXPORT int PLUGIN_CALL AmxLoad( AMX *amx ) { int index=0; if(amx_FindNative(amx, "SetPlayerHealth", &index) == AMX_ERR_NONE) { AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base); AMX_FUNCSTUBNT *natives = reinterpret_cast<AMX_FUNCSTUBNT*>(amx->base + hdr->natives); //SWAP the addresses of the original function with my hook //store the original address to call it in the hook afterwards ::original_SetPlayerHealth = reinterpret_cast<AMX_NATIVE>(natives[index].address); natives[index].address = reinterpret_cast<ucell>( hook_SetPlayerHealth ); logprintf(" SetPlayerPos found and hooked successfully!"); } else { logprintf(" SetPlayerHealth is not used in this script..."); } return amx_Register(amx, PluginNatives, -1); }
I am not an expert in the field of embedded scripting but I guess if I copy the original address of any callback and then call it in my hooked address this should work... shouldn't it?
Unfortunately the server just crashes because of an exception...
This is my code:
Hooking Callbacks (publics?)
Код:
AMX_NATIVE original_OnPlayerConnect; cell AMX_NATIVE_CALL hooked_OnPlayerConnect(AMX *amx, cell *params) { logprintf(" ON PLAYER CONNECT called!"); return original_OnPlayerConnect(amx, params); } PLUGIN_EXPORT int PLUGIN_CALL AmxLoad( AMX *amx ) { int basis = 0; if(amx_FindPublic(amx, "OnPlayerConnect", &basis) == AMX_ERR_NONE) { AMX_HEADER *header = reinterpret_cast<AMX_HEADER*>( amx->base ); AMX_FUNCSTUBNT *publics = reinterpret_cast<AMX_FUNCSTUBNT*>(amx->base + header->publics); ::original_OnPlayerConnect = reinterpret_cast< ucell >(publics[basis].address); publics[basis].address = reinterpret_cast<ucell>( hooked_OnPlayerConnect ); logprintf(" Hooking event OnPlayerConnect"); } else { logprintf(" OnPlayerConnect NOT found?!"); } }
- Callbacks are much more difficult to hook than I thought
- The type of original_OnPlayerConnect is wrong
Thank you for any help!