/* ======== SourceMM ======== * Copyright (C) 2004-2008 Metamod:Source Development Team * No warranties of any kind * * License: zlib/libpng * * Author(s): David "BAILOPAN" Anderson * ============================ */ #ifndef _INCLUDE_UTIL_H #define _INCLUDE_UTIL_H #include #include /** * @brief Utility functions * @file util.h */ #define IA32_JMP_IMM32 '\xE9' /** * @brief Returns a pointer to the extension in a file name. */ const char *UTIL_GetExtension(const char *file); /** * @brief Removes whitespace characters from left side of string. */ void UTIL_TrimLeft(char *buffer); /** * @brief Removes whitespace characters from right side of string. */ void UTIL_TrimRight(char *buffer); /** * @brief Compares two file paths. */ bool UTIL_PathCmp(const char *path1, const char *path2); /** * @brief Same as snprintf except that it ensures the string buffer is null terminated. */ size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...); /** * @brief Same as vsnprintf except that it ensures the string buffer is null terminated. */ size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list params); /** * @brief Forms a relative path given two absolute paths. * * @param buffer Buffer to store relative path in. * @param maxlength Maximum length of the output buffer. * @param relTo Destination folder to use as a working directory. * Final folder name should not be pathchar-terminated. * @param relFrom Source file or folder to use as a target. * @return True on success, false on failure. */ bool UTIL_Relatize(char buffer[], size_t maxlength, const char *relTo, const char *relFrom); /** * @brief Compares memory address against a signature. * * @param addr Memory address to check. * @param sig Signature used to check against memory address. Accept 0x2A as wildcard. * @param len Length of signature. * @return True if signature was verified, false otherwise. */ bool UTIL_VerifySignature(const void *addr, const char *sig, size_t len); /** * @brief Returns the original function address of a given virtual function. * * @param mfp Member function pointer to virtual function. * @param ptr Pointer to interface in which the virtual function belongs. * @param cls A CallClass for the interface in which the virtual function belongs. * @return Address of function originally pointed to by the virtual function. */ template char *UTIL_GetOrigFunction(MFP vfunc, Iface *ptr, SourceHook::CallClass *cls) { SourceHook::MemFuncInfo info = {true, -1, 0, 0}; SourceHook::GetFuncInfo(vfunc, info); /* Get address of original GetUserMessageInfo() */ char *func = reinterpret_cast(cls->GetOrigFunc(info.vtbloffs, info.vtblindex)); /* If we can't get original function, that means there's no hook */ if (func == NULL) { /* Get virtual function address 'manually' then */ char *adjustedptr = reinterpret_cast(ptr) + info.vtbloffs + info.vtbloffs; char **vtable = *reinterpret_cast(adjustedptr); func = vtable[info.vtblindex]; } /* Check for relative jumps */ if (func[0] == IA32_JMP_IMM32) { /* Get address from displacement... * * Add 5 because it's relative to next instruction: * Opcode <1 byte> + 32-bit displacement <4 bytes> */ func += *reinterpret_cast(func + 1) + 5; } return func; } #endif //_INCLUDE_UTIL_H