View Single Post
Author Message
LunaTheReborn
Junior Member
Join Date: Feb 2020
Old 12-04-2023 , 03:03   Some signatures for 25th Anniversary Edition (Dec 02 2023)
Reply With Quote #1

Important:
This post and all signatures are for Counter-Strike and Zero Condition. I have never play another GoldSrc engine game and not did I tested on them!

It seems like Valve changed some compilation flags such that almost all signatures are dead and so are my piles of Orpheu plugins.

So while migrating my projects into C++ form, I would like to share some commonly used function signatures.

All of the following signatures are for C++ project, one may convert them for Orpheu. '\x2A' means "any 1 byte value". It should convert to "*" if you are using Orpheu.

All of my signatures have a displacement of 1, as in Orpheu terminology. This means that for the address retrieved, one would need to add precisely one byte of displacement on top of it.

hw.dll
Fetch the build number.
Code:
int __cdecl BuildNumber(void);
inline constexpr unsigned char BUILD_NUMBER_ANNIVERSARY_PATTERN[] = "\xA1\x2A\x2A\x2A\x2A\x53\x33\xDB\x85\xC0\x0F\x85\x2A\x2A\x2A\x2A\x57\x33\xFF\x0F\x1F\x40\x00\x66\x0F\x1F\x84\x00\x00\x00\x00\x00";
mp.dll
Get the game rule object from its return value. (g_pGameRules)
Code:
CGameRules *__cdecl InstallGameRules(void);
CC 55 8B EC 6A FF 68 ? ? ? ? 64 A1 ? ? ? ? 50 51 A1 ? ? ? ? 33 C5 50 8D 45 F4 64 A3 ? ? ? ?
Code:
void __cdecl RadiusFlash(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage);
inline constexpr unsigned char RADIUS_FLASH_FN_ANNIV_PATTERN[] = "\xCC\x55\x8B\xEC\x83\xE4\xF8\x81\xEC\x2A\x2A\x2A\x2A\xF3\x0F\x10\x45\x2A\x8D\x45\x08";
Code:
void __thiscall SelectItem(CBasePlayer *pThis, const char *pszItemName);
inline constexpr unsigned char SELECT_ITEM_FN_ANNIV_PATTERN[] = "\xCC\x55\x8B\xEC\x83\xEC\x08\x53\x8B\x5D\x08\x57\x8B\xF9\x89\x7D\xF8\x85\xDB";
Code:
void __thiscall SetAnimation(CBasePlayer *pPlayer, PLAYER_ANIM playerAnim);
inline constexpr unsigned char SET_ANIMATION_FN_ANNIV_PATTERN[] = "\xCC\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x54\xA1\x2A\x2A\x2A\x2A\x33\xC4\x89\x44\x24\x50";
One should consider using CBaseEntity::TraceAttack() instead of AddMultiDamage(). We are playing a gun-based game, pal.
Code:
void __cdecl AddMultiDamage(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType)
inline constexpr unsigned char ADD_MULTI_DAMAGE_FN_ANNIV_PATTERN[] = "\xCC\x55\x8B\xEC\x56\x8B\x75\x0C\x85\xF6\x74\x6A\xA1\x2A\x2A\x2A\x2A\x0B\x45";
Code:
void __cdecl ApplyMultiDamage(entvars_t *pevInflictor, entvars_t *pevAttacker);
inline constexpr unsigned char APPLY_MULTI_DAMAGE_FN_ANNIV_PATTERN[] = "\xCC\x55\x8B\xEC\x8B\x0D\x2A\x2A\x2A\x2A\x85\xC9\x74\x1F\xFF\x35\x2A\x2A\x2A\x2A\xF3\x0F\x10\x05";
Code:
void __cdecl ClearMultiDamage(void);
inline constexpr unsigned char CLEAR_MULTI_DAMAGE_FN_ANNIV_PATTERN[] = "\xC3\xC7\x05\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x2A\xC7\x05\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x2A\xC7\x05\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x2A\xC3\xCC";
'qboolean' is just int. So does 'BOOL'.
The last parameter may have been an actual C++ bool type, but the alignment force every argument to be at list the length of sizeof(void*)
Code:
qboolean __thiscall DefaultDeploy(CBasePlayerWeapon *pThis, const char *szViewModel, const char *szWeaponModel, int iAnim, const char *szAnimExt, qboolean skiplocal);
inline constexpr unsigned char DEFAULT_DEPLOY_FN_ANNIV_PATTERN[] = "\xCC\x55\x8B\xEC\x56\x8B\xF1\x8B\x06\xFF\x90\x2A\x2A\x2A\x2A\x85\xC0";
Code:
qboolean __thiscall SwitchWeapon(CBasePlayer *pThis, CBasePlayerItem *pWeapon)
inline constexpr unsigned char SWITCH_WEAPON_FN_ANNIV_PATTERN[] = "\xCC\x55\x8B\xEC\x56\x57\x8B\x7D\x08\x8B\xF1\x8B\xCF\x8B\x07\xFF\x90";
CBaseEntity::FireBullets() function won't fit into Orpheu. As it exceeding the 16 arguments limitation. (Consider Vector passed as float[3])
Code:
void __thiscall FireBullets(CBaseEntity *pThis, unsigned long cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker);
inline constexpr unsigned char FIRE_BULLETS_FN_ANNIV_PATTERN[] = "\xCC\x55\x8B\xEC\x83\xEC\x78\xA1\x2A\x2A\x2A\x2A\x53\x56\x57\xF3\x0F\x10\x40\x2A\x8B";
Infamous CBaseEntity::FireBullets3().
Check the function prototype CAREFULLY here.
It returns a C++ type, exceeding the size of void*, therefore it is treated differently after compilation.
The first parameter is this as usual. The second parameter represents edx register in your CPU. The third parameter is your return value address. The supposedly returned object is created in advance by the caller of the function. So should you if you are calling it.
Pass nullptr into edx if one is calling, and make sure edx was passed on if one is hooking and forwarding the original function.
Code:
using fnFireBullets3_t = Vector *(__fastcall *)(CBaseEntity *pThis, void* edx, Vector* pret, Vector vecSrc, Vector vecDirShooting, float flSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, qboolean bPistol, int shared_rand);
inline constexpr unsigned char FIRE_BULLETS_3_FN_ANNIV_PATTERN[] = "\xCC\x55\x8B\xEC\x83\xEC\x74\xA1\x2A\x2A\x2A\x2A\x53\x56\x57\xF3\x0F\x10\x40\x2A\x8B";
Should you find any function you are particularly interested in, I would love to help. It is always hard to find enough support or help for a 25 years old game.

Last edited by LunaTheReborn; 12-07-2023 at 15:37. Reason: Clarify this is for CS and CZ, not other games.
LunaTheReborn is offline