diff --git a/modules/hamsandwich/hook.h b/modules/hamsandwich/hook.h index 4024bdea..744d69be 100644 --- a/modules/hamsandwich/hook.h +++ b/modules/hamsandwich/hook.h @@ -39,7 +39,7 @@ public: char *ent; // ent name that's being hooked int trampSize; - Hook(void **vtable_, int entry_, void *target_, bool voidcall, bool retbuf, int paramcount, char *name) : + Hook(void **vtable_, int entry_, void *target_, bool voidcall, bool retbuf, int paramcount, const char *name) : func(NULL), vtable(vtable_), entry(entry_), target(target_), exec(0), del(0), tramp(NULL), trampSize(0) { // original function is vtable[entry] diff --git a/modules/hamsandwich/hook_native.cpp b/modules/hamsandwich/hook_native.cpp index 42a8ed87..c88c364f 100644 --- a/modules/hamsandwich/hook_native.cpp +++ b/modules/hamsandwich/hook_native.cpp @@ -534,21 +534,24 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params) CHECK_FUNCTION(func); - char *function=MF_GetAmxString(amx, params[3], 0, NULL); - char *classname=MF_GetAmxString(amx, params[2], 1, NULL); - + // Fixes a buffer issue by copying locally the strings. + // REMOVE_ENTITY invokes pfnOnFreeEntPrivateData which plugins can hook and `function` and `classname` strings are used after that + // but it is pointing to the AMXX static buffer. Basically, hooking this forward and doing stuff inside could invalid all RegisterHam calls. + ke::AString function(MF_GetAmxString(amx, params[3], 0, NULL)); + ke::AString classname(MF_GetAmxString(amx, params[2], 1, NULL)); + // Check the entity // create an entity, assign it the gamedll's class, hook it and destroy it edict_t *Entity=CREATE_ENTITY(); - CALL_GAME_ENTITY(PLID,classname,&Entity->v); + CALL_GAME_ENTITY(PLID,classname.chars(),&Entity->v); if (Entity->pvPrivateData == NULL) { REMOVE_ENTITY(Entity); - MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve classtype for \"%s\", hook for \"%s\" not active.",classname,function); + MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve classtype for \"%s\", hook for \"%s\" not active.",classname.chars(),function.chars()); return 0; } @@ -558,18 +561,18 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params) if (vtable == NULL) { - MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve vtable for \"%s\", hook for \"%s\" not active.",classname,function); + MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve vtable for \"%s\", hook for \"%s\" not active.",classname.chars(),function.chars()); return 0; } // Verify that the function is valid // Don't fail the plugin if this fails, just emit a normal error - int fwd=hooklist[func].makefunc(amx, function); + int fwd=hooklist[func].makefunc(amx, function.chars()); if (fwd == -1) { - MF_LogError(amx, AMX_ERR_NATIVE, "Function %s not found.", function); + MF_LogError(amx, AMX_ERR_NATIVE, "Function %s not found.", function.chars()); return 0; } @@ -586,9 +589,9 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params) pfwd->AddRef(); // We've passed all tests... - if (strcmp(classname, "player") == 0 && enableSpecialBot) + if (strcmp(classname.chars(), "player") == 0 && enableSpecialBot) { - SpecialbotHandler.RegisterHamSpecialBot(amx, func, function, post, pfwd); + SpecialbotHandler.RegisterHamSpecialBot(amx, func, function.chars(), post, pfwd); } int **ivtable=(int **)vtable; @@ -615,7 +618,7 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params) } // If we got here, the function is not hooked - Hook *hook = new Hook(vtable, hooklist[func].vtid, hooklist[func].targetfunc, hooklist[func].isvoid, hooklist[func].needsretbuf, hooklist[func].paramcount, classname); + Hook *hook = new Hook(vtable, hooklist[func].vtid, hooklist[func].targetfunc, hooklist[func].isvoid, hooklist[func].needsretbuf, hooklist[func].paramcount, classname.chars()); hooks[func].append(hook); if (post)