This commit is contained in:
Accelerator74 2018-05-28 17:49:33 +05:00
commit 4a36a1ed6b
24 changed files with 2949 additions and 0 deletions

100
CDetour/detourhelpers.h Normal file
View File

@ -0,0 +1,100 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id: detourhelpers.h 248 2008-08-27 00:56:22Z pred $
*/
#ifndef _INCLUDE_SOURCEMOD_DETOURHELPERS_H_
#define _INCLUDE_SOURCEMOD_DETOURHELPERS_H_
#if defined PLATFORM_POSIX
#include <sys/mman.h>
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
#define ALIGN(ar) ((long)ar & ~(PAGE_SIZE-1))
#define PAGE_EXECUTE_READWRITE PROT_READ|PROT_WRITE|PROT_EXEC
#endif
struct patch_t
{
patch_t()
{
patch[0] = 0;
bytes = 0;
}
unsigned char patch[20];
size_t bytes;
};
inline void ProtectMemory(void *addr, int length, int prot)
{
#if defined PLATFORM_POSIX
void *addr2 = (void *)ALIGN(addr);
mprotect(addr2, sysconf(_SC_PAGESIZE), prot);
#elif defined PLATFORM_WINDOWS
DWORD old_prot;
VirtualProtect(addr, length, prot, &old_prot);
#endif
}
inline void SetMemPatchable(void *address, size_t size)
{
ProtectMemory(address, (int)size, PAGE_EXECUTE_READWRITE);
}
inline void DoGatePatch(unsigned char *target, void *callback)
{
SetMemPatchable(target, 20);
target[0] = 0xFF; /* JMP */
target[1] = 0x25; /* MEM32 */
*(void **)(&target[2]) = callback;
}
inline void ApplyPatch(void *address, int offset, const patch_t *patch, patch_t *restore)
{
ProtectMemory(address, 20, PAGE_EXECUTE_READWRITE);
unsigned char *addr = (unsigned char *)address + offset;
if (restore)
{
for (size_t i=0; i<patch->bytes; i++)
{
restore->patch[i] = addr[i];
}
restore->bytes = patch->bytes;
}
for (size_t i=0; i<patch->bytes; i++)
{
addr[i] = patch->patch[i];
}
}
#endif //_INCLUDE_SOURCEMOD_DETOURHELPERS_H_

227
CDetour/detours.cpp Normal file
View File

@ -0,0 +1,227 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id: detours.cpp 248 2008-08-27 00:56:22Z pred $
*/
#include "detours.h"
#include <asm/asm.h>
ISourcePawnEngine *CDetourManager::spengine = NULL;
IGameConfig *CDetourManager::gameconf = NULL;
void CDetourManager::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf)
{
CDetourManager::spengine = spengine;
CDetourManager::gameconf = gameconf;
}
CDetour *CDetourManager::CreateDetour(void *callbackfunction, void **trampoline, const char *signame)
{
CDetour *detour = new CDetour(callbackfunction, trampoline, signame);
if (detour)
{
if (!detour->Init(spengine, gameconf))
{
delete detour;
return NULL;
}
return detour;
}
return NULL;
}
CDetour *CDetourManager::CreateDetour(void *callbackfunction, void **trampoline, void *pAddress)
{
CDetour *detour = new CDetour(callbackfunction, trampoline, pAddress);
if (detour)
{
if (!detour->Init(spengine, gameconf))
{
delete detour;
return NULL;
}
return detour;
}
return NULL;
}
CDetour::CDetour(void *callbackfunction, void **trampoline, const char *signame)
{
enabled = false;
detoured = false;
detour_address = NULL;
detour_trampoline = NULL;
this->signame = signame;
this->detour_callback = callbackfunction;
spengine = NULL;
gameconf = NULL;
this->trampoline = trampoline;
}
CDetour::CDetour(void*callbackfunction, void **trampoline, void *pAddress)
{
enabled = false;
detoured = false;
detour_address = pAddress;
detour_trampoline = NULL;
this->signame = NULL;
this->detour_callback = callbackfunction;
spengine = NULL;
gameconf = NULL;
this->trampoline = trampoline;
}
bool CDetour::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf)
{
this->spengine = spengine;
this->gameconf = gameconf;
if (!CreateDetour())
{
enabled = false;
return enabled;
}
enabled = true;
return enabled;
}
void CDetour::Destroy()
{
DeleteDetour();
delete this;
}
bool CDetour::IsEnabled()
{
return enabled;
}
bool CDetour::CreateDetour()
{
if (signame && !gameconf->GetMemSig(signame, &detour_address))
{
g_pSM->LogError(myself, "Could not locate %s - Disabling detour", signame);
return false;
}
else if(!detour_address)
{
g_pSM->LogError(myself, "Invalid detour address passed - Disabling detour to prevent crashes");
return false;
}
if (!detour_address)
{
g_pSM->LogError(myself, "Sigscan for %s failed - Disabling detour to prevent crashes", signame);
return false;
}
detour_restore.bytes = copy_bytes((unsigned char *)detour_address, NULL, OP_JMP_SIZE+1);
/* First, save restore bits */
for (size_t i=0; i<detour_restore.bytes; i++)
{
detour_restore.patch[i] = ((unsigned char *)detour_address)[i];
}
JitWriter wr;
JitWriter *jit = &wr;
jit_uint32_t CodeSize = 0;
wr.outbase = NULL;
wr.outptr = NULL;
jit_rewind:
/* Patch old bytes in */
if (wr.outbase != NULL)
{
copy_bytes((unsigned char *)detour_address, (unsigned char*)wr.outptr, detour_restore.bytes);
}
wr.outptr += detour_restore.bytes;
/* Return to the original function */
jitoffs_t call = IA32_Jump_Imm32(jit, 0);
IA32_Write_Jump32_Abs(jit, call, (unsigned char *)detour_address + detour_restore.bytes);
if (wr.outbase == NULL)
{
CodeSize = wr.get_outputpos();
wr.outbase = (jitcode_t)spengine->AllocatePageMemory(CodeSize);
spengine->SetReadWrite(wr.outbase);
wr.outptr = wr.outbase;
detour_trampoline = wr.outbase;
goto jit_rewind;
}
spengine->SetReadExecute(wr.outbase);
*trampoline = detour_trampoline;
return true;
}
void CDetour::DeleteDetour()
{
if (detoured)
{
DisableDetour();
}
if (detour_trampoline)
{
/* Free the allocated trampoline memory */
spengine->FreePageMemory(detour_trampoline);
detour_trampoline = NULL;
}
}
void CDetour::EnableDetour()
{
if (!detoured)
{
DoGatePatch((unsigned char *)detour_address, &detour_callback);
detoured = true;
}
}
void CDetour::DisableDetour()
{
if (detoured)
{
/* Remove the patch */
ApplyPatch(detour_address, 0, &detour_restore, NULL);
detoured = false;
}
}

307
CDetour/detours.h Normal file
View File

@ -0,0 +1,307 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id: detours.h 257 2008-09-23 03:12:13Z pred $
*/
#ifndef _INCLUDE_SOURCEMOD_DETOURS_H_
#define _INCLUDE_SOURCEMOD_DETOURS_H_
#include "extension.h"
#include <jit/jit_helpers.h>
#include <jit/x86/x86_macros.h>
#include "detourhelpers.h"
/**
* CDetours class for SourceMod Extensions by pRED*
* detourhelpers.h entirely stolen from CSS:DM and were written by BAILOPAN (I assume).
* asm.h/c from devmaster.net (thanks cybermind) edited by pRED* to handle gcc -fPIC thunks correctly
* Concept by Nephyrin Zey (http://www.doublezen.net/) and Windows Detour Library (http://research.microsoft.com/sn/detours/)
* Member function pointer ideas by Don Clugston (http://www.codeproject.com/cpp/FastDelegate.asp)
*/
#define DETOUR_MEMBER_CALL(name) (this->*name##_Actual)
#define DETOUR_STATIC_CALL(name) (name##_Actual)
#define DETOUR_DECL_STATIC0(name, ret) \
ret (*name##_Actual)(void) = NULL; \
ret name(void)
#define DETOUR_DECL_STATIC1(name, ret, p1type, p1name) \
ret (*name##_Actual)(p1type) = NULL; \
ret name(p1type p1name)
#define DETOUR_DECL_STATIC2(name, ret, p1type, p1name, p2type, p2name) \
ret (*name##_Actual)(p1type, p2type) = NULL; \
ret name(p1type p1name, p2type p2name)
#define DETOUR_DECL_STATIC3(name, ret, p1type, p1name, p2type, p2name, p3type, p3name) \
ret (*name##_Actual)(p1type, p2type, p3type) = NULL; \
ret name(p1type p1name, p2type p2name, p3type p3name)
#define DETOUR_DECL_STATIC4(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name) \
ret (*name##_Actual)(p1type, p2type, p3type, p4type) = NULL; \
ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name)
#define DETOUR_DECL_STATIC5(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name) \
ret (*name##_Actual)(p1type, p2type, p3type, p4type, p5type) = NULL; \
ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name)
#define DETOUR_DECL_STATIC6(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name) \
ret (*name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type) = NULL; \
ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name)
#define DETOUR_DECL_STATIC7(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name, p7type, p7name) \
ret (*name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type, p7type) = NULL; \
ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name, p7type p7name)
#define DETOUR_DECL_STATIC8(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name, p7type, p7name, p8type, p8name) \
ret (*name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type, p7type, p8type) = NULL; \
ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name, p7type p7name, p8type p8name)
#define DETOUR_DECL_MEMBER0(name, ret) \
class name##Class \
{ \
public: \
ret name(); \
static ret (name##Class::* name##_Actual)(void); \
}; \
ret (name##Class::* name##Class::name##_Actual)(void) = NULL; \
ret name##Class::name()
#define DETOUR_DECL_MEMBER1(name, ret, p1type, p1name) \
class name##Class \
{ \
public: \
ret name(p1type p1name); \
static ret (name##Class::* name##_Actual)(p1type); \
}; \
ret (name##Class::* name##Class::name##_Actual)(p1type) = NULL; \
ret name##Class::name(p1type p1name)
#define DETOUR_DECL_MEMBER2(name, ret, p1type, p1name, p2type, p2name) \
class name##Class \
{ \
public: \
ret name(p1type p1name, p2type p2name); \
static ret (name##Class::* name##_Actual)(p1type, p2type); \
}; \
ret (name##Class::* name##Class::name##_Actual)(p1type, p2type) = NULL; \
ret name##Class::name(p1type p1name, p2type p2name)
#define DETOUR_DECL_MEMBER3(name, ret, p1type, p1name, p2type, p2name, p3type, p3name) \
class name##Class \
{ \
public: \
ret name(p1type p1name, p2type p2name, p3type p3name); \
static ret (name##Class::* name##_Actual)(p1type, p2type, p3type); \
}; \
ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type) = NULL; \
ret name##Class::name(p1type p1name, p2type p2name, p3type p3name)
#define DETOUR_DECL_MEMBER4(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name) \
class name##Class \
{ \
public: \
ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name); \
static ret (name##Class::* name##_Actual)(p1type, p2type, p3type, p4type); \
}; \
ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type, p4type) = NULL; \
ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name)
#define DETOUR_DECL_MEMBER5(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name) \
class name##Class \
{ \
public: \
ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name); \
static ret (name##Class::* name##_Actual)(p1type, p2type, p3type, p4type, p5type); \
}; \
ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type, p4type, p5type) = NULL; \
ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name)
#define DETOUR_DECL_MEMBER6(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name) \
class name##Class \
{ \
public: \
ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name); \
static ret (name##Class::* name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type); \
}; \
ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type) = NULL; \
ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name)
#define DETOUR_DECL_MEMBER7(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name, p7type, p7name) \
class name##Class \
{ \
public: \
ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name, p7type p7name); \
static ret (name##Class::* name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type, p7type); \
}; \
ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type, p7type) = NULL; \
ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name, p7type p7name)
#define DETOUR_DECL_MEMBER8(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name, p7type, p7name, p8type, p8name) \
class name##Class \
{ \
public: \
ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name, p7type p7name, p8type p8name); \
static ret (name##Class::* name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type, p7type, p8type); \
}; \
ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type, p7type, p8type) = NULL; \
ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name, p7type p7name, p8type p8name)
#define GET_MEMBER_CALLBACK(name) (void *)GetCodeAddress(&name##Class::name)
#define GET_MEMBER_TRAMPOLINE(name) (void **)(&name##Class::name##_Actual)
#define GET_STATIC_CALLBACK(name) (void *)&name
#define GET_STATIC_TRAMPOLINE(name) (void **)&name##_Actual
#define DETOUR_CREATE_MEMBER(name, gamedata) CDetourManager::CreateDetour(GET_MEMBER_CALLBACK(name), GET_MEMBER_TRAMPOLINE(name), gamedata);
#define DETOUR_CREATE_STATIC(name, gamedata) CDetourManager::CreateDetour(GET_STATIC_CALLBACK(name), GET_STATIC_TRAMPOLINE(name), gamedata);
class GenericClass {};
typedef void (GenericClass::*VoidFunc)();
inline void *GetCodeAddr(VoidFunc mfp)
{
return *(void **)&mfp;
}
/**
* Converts a member function pointer to a void pointer.
* This relies on the assumption that the code address lies at mfp+0
* This is the case for both g++ and later MSVC versions on non virtual functions but may be different for other compilers
* Based on research by Don Clugston : http://www.codeproject.com/cpp/FastDelegate.asp
*/
#define GetCodeAddress(mfp) GetCodeAddr(reinterpret_cast<VoidFunc>(mfp))
class CDetourManager;
class CDetour
{
public:
bool IsEnabled();
/**
* These would be somewhat self-explanatory I hope
*/
void EnableDetour();
void DisableDetour();
void Destroy();
friend class CDetourManager;
protected:
CDetour(void *callbackfunction, void **trampoline, const char *signame);
CDetour(void*callbackfunction, void **trampoline, void *pAddress);
bool Init(ISourcePawnEngine *spengine, IGameConfig *gameconf);
private:
/* These create/delete the allocated memory */
bool CreateDetour();
void DeleteDetour();
bool enabled;
bool detoured;
patch_t detour_restore;
/* Address of the detoured function */
void *detour_address;
/* Address of the allocated trampoline function */
void *detour_trampoline;
/* Address of the callback handler */
void *detour_callback;
/* The function pointer used to call our trampoline */
void **trampoline;
const char *signame;
ISourcePawnEngine *spengine;
IGameConfig *gameconf;
};
class CDetourManager
{
public:
static void Init(ISourcePawnEngine *spengine, IGameConfig *gameconf);
/**
* Creates a new detour
*
* @param callbackfunction Void pointer to your detour callback function.
* @param trampoline Address of the trampoline pointer
* @param signame Section name containing a signature to fetch from the gamedata file.
* @return A new CDetour pointer to control your detour.
*
* Example:
*
* CBaseServer::ConnectClient(netadr_s &, int, int, int, char const*, char const*, char const*, int)
*
* Define a new class with the required function and a member function pointer to the same type:
*
* class CBaseServerDetour
* {
* public:
* bool ConnectClient(void *netaddr_s, int, int, int, char const*, char const*, char const*, int);
* static bool (CBaseServerDetour::* ConnectClient_Actual)(void *netaddr_s, int, int, int, char const*, char const*, char const*, int);
* }
*
* void *callbackfunc = GetCodeAddress(&CBaseServerDetour::ConnectClient);
* void **trampoline = (void **)(&CBaseServerDetour::ConnectClient_Actual);
*
* Creation:
* CDetourManager::CreateDetour(callbackfunc, trampoline, "ConnectClient");
*
* Usage:
*
* CBaseServerDetour::ConnectClient(void *netaddr_s, int, int, int, char const*, char const*, char const*, int)
* {
* //pre hook code
* bool result = (this->*ConnectClient_Actual)(netaddr_s, rest of params);
* //post hook code
* return result;
* }
*
* Note we changed the netadr_s reference into a void* to avoid needing to define the type
*/
static CDetour *CreateDetour(void *callbackfunction, void **trampoline, const char *signame);
static CDetour *CreateDetour(void *callbackfunction, void **trampoline, void *pAddress);
friend class CBlocker;
friend class CDetour;
private:
static ISourcePawnEngine *spengine;
static IGameConfig *gameconf;
};
#endif // _INCLUDE_SOURCEMOD_DETOURS_H_

195
Makefile Normal file
View File

@ -0,0 +1,195 @@
# (C)2004-2008 SourceMod Development Team
# Makefile written by David "BAILOPAN" Anderson
SMSDK = ../sourcemod
HL2SDK_ORIG = ../../hl2sdk
HL2SDK_OB = ../../hl2sdk-ob
HL2SDK_CSS = ../hl2sdk-css
HL2SDK_OB_VALVE = ../hl2sdk-tf2
HL2SDK_L4D = ../hl2sdk-l4d
HL2SDK_L4D2 = ../hl2sdk
HL2SDK_CSGO = ../hl2sdk-csgo
MMSOURCE19 = ../mmsource110
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
PROJECT = cleaner
OBJECTS = smsdk_ext.cpp extension.cpp CDetour/detours.cpp asm/asm.c
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
##############################################
C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
C_GCC4_FLAGS = -fvisibility=hidden
CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
CPP = gcc-6
override ENGSET = false
ifneq (,$(filter original orangebox orangeboxvalve css left4dead left4dead2 csgo,$(ENGINE)))
override ENGSET = true
endif
ifeq "$(ENGINE)" "original"
HL2SDK = $(HL2SDK_ORIG)
CFLAGS += -DSOURCE_ENGINE=1
GAMEFIX = 1.ep1
endif
ifeq "$(ENGINE)" "orangebox"
HL2SDK = $(HL2SDK_OB)
CFLAGS += -DSOURCE_ENGINE=3
GAMEFIX = 2.ep2
endif
ifeq "$(ENGINE)" "css"
HL2SDK = $(HL2SDK_CSS)
CFLAGS += -DSOURCE_ENGINE=6
GAMEFIX = 2.css
endif
ifeq "$(ENGINE)" "orangeboxvalve"
HL2SDK = $(HL2SDK_OB_VALVE)
CFLAGS += -DSOURCE_ENGINE=7
GAMEFIX = 2.ep2v
endif
ifeq "$(ENGINE)" "left4dead"
HL2SDK = $(HL2SDK_L4D)
CFLAGS += -DSOURCE_ENGINE=8
GAMEFIX = 2.l4d
endif
ifeq "$(ENGINE)" "left4dead2"
HL2SDK = $(HL2SDK_L4D2)
CFLAGS += -DSOURCE_ENGINE=9
GAMEFIX = 2.l4d2
endif
ifeq "$(ENGINE)" "csgo"
HL2SDK = $(HL2SDK_CSGO)
CFLAGS += -DSOURCE_ENGINE=12
GAMEFIX = 2.csgo
endif
HL2PUB = $(HL2SDK)/public
ifeq "$(ENGINE)" "original"
INCLUDE += -I$(HL2SDK)/public/dlls
METAMOD = $(MMSOURCE19)/core-legacy
else
INCLUDE += -I$(HL2SDK)/public/game/server
METAMOD = $(MMSOURCE19)/core
endif
OS := $(shell uname -s)
ifeq "$(OS)" "Darwin"
LIB_EXT = dylib
HL2LIB = $(HL2SDK)/lib/mac
else
LIB_EXT = so
ifeq "$(ENGINE)" "original"
HL2LIB = $(HL2SDK)/linux_sdk
else
HL2LIB = $(HL2SDK)/lib/linux
endif
endif
# if ENGINE is original or OB
ifneq (,$(filter original orangebox,$(ENGINE)))
LIB_SUFFIX = _i486.$(LIB_EXT)
else
LIB_PREFIX = lib
ifneq (,$(filter orangeboxvalve css left4dead2,$(ENGINE)))
ifneq "$(OS)" "Darwin"
LIB_SUFFIX = _srv.$(LIB_EXT)
else
LIB_SUFFIX = .$(LIB_EXT)
endif
else
LIB_SUFFIX = .$(LIB_EXT)
endif
endif
INCLUDE += -I. -I.. -I$(HL2PUB) -I$(HL2PUB)/engine -I$(HL2PUB)/tier0 \
-I$(HL2PUB)/tier1 -I$(METAMOD) -I$(METAMOD)/sourcehook -I$(SMSDK)/public -I$(SMSDK)/public/extensions \
-I$(SMSDK)/sourcepawn/include
LINK += $(HL2LIB)/tier1_i486.a $(LIB_PREFIX)vstdlib$(LIB_SUFFIX) $(LIB_PREFIX)tier0$(LIB_SUFFIX)
ifeq "$(ENGINE)" "csgo"
LINK += $(HL2LIB)/interfaces_i486.a
endif
CFLAGS += -DSE_EPISODEONE=1 -DSE_DARKMESSIAH=2 -DSE_ORANGEBOX=3 -DSE_BLOODYGOODTIME=4 -DSE_EYE=5 \
-DSE_CSS=6 -DSE_ORANGEBOXVALVE=7 -DSE_LEFT4DEAD=8 -DSE_LEFT4DEAD2=9 -DSE_ALIENSWARM=10 \
-DSE_PORTAL2=11 -DSE_CSGO=12
LINK += -m32 -ldl -lm
CFLAGS += -DPOSIX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
-D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -DCOMPILER_GCC \
-Wno-switch -Wall -Werror -mfpmath=sse -msse -DSOURCEMOD_BUILD -DHAVE_STDINT_H -m32
CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti -fno-threadsafe-statics -std=c++11
################################################
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
################################################
BINARY = $(PROJECT).ext.$(GAMEFIX).$(LIB_EXT)
ifeq "$(DEBUG)" "true"
BIN_DIR = Debug
CFLAGS += $(C_DEBUG_FLAGS)
else
BIN_DIR = Release
CFLAGS += $(C_OPT_FLAGS)
endif
ifeq "$(OS)" "Darwin"
CPP = $(CPP_OSX)
LIB_EXT = dylib
CFLAGS += -DOSX -D_OSX
LINK += -dynamiclib -lstdc++ -mmacosx-version-min=10.5
else
LIB_EXT = so
CFLAGS += -D_LINUX
LINK += -static-libgcc -shared
endif
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
ifeq "$(GCC_VERSION)" "4"
CFLAGS += $(C_GCC4_FLAGS)
CPPFLAGS += $(CPP_GCC4_FLAGS)
endif
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
$(BIN_DIR)/%.o: %.cpp
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
all: check
ln -sf $(SMSDK)/public/smsdk_ext.cpp
mkdir -p $(BIN_DIR)/CDetour
ln -sf $(HL2LIB)/$(LIB_PREFIX)vstdlib$(LIB_SUFFIX); \
ln -sf $(HL2LIB)/$(LIB_PREFIX)tier0$(LIB_SUFFIX); \
$(MAKE) -f Makefile extension
check:
if [ "$(ENGSET)" = "false" ]; then \
echo "You must supply one of the following values for ENGINE:"; \
echo "csgo, left4dead2, left4dead, css, orangeboxvalve, orangebox, or original"; \
exit 1; \
fi
extension: check $(OBJ_LINUX)
$(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -o $(BIN_DIR)/$(BINARY)
debug:
$(MAKE) -f Makefile all DEBUG=true
default: all
clean: check
rm -rf $(BIN_DIR)/*.o
rm -rf $(BIN_DIR)/CDetour/*.o
rm -rf $(BIN_DIR)/asm/*.o
rm -rf $(BIN_DIR)/$(BINARY)

0
Release/cleaner.autoload Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

420
asm/asm.c Normal file
View File

@ -0,0 +1,420 @@
#include "asm.h"
#ifndef WIN32
#define _GNU_SOURCE
#include <dlfcn.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define REG_EAX 0
#define REG_ECX 1
#define REG_EDX 2
#define REG_EBX 3
#define IA32_MOV_REG_IMM 0xB8 // encoding is +r <imm32>
#endif
/**
* Checks if a call to a fpic thunk has just been written into dest.
* If found replaces it with a direct mov that sets the required register to the value of pc.
*
* @param dest Destination buffer where a call opcode + addr (5 bytes) has just been written.
* @param pc The program counter value that needs to be set (usually the next address from the source).
* @noreturn
*/
void check_thunks(unsigned char *dest, unsigned char *pc)
{
#ifndef WIN32
/* Step write address back 4 to the start of the function address */
unsigned char *writeaddr = dest - 4;
unsigned char *calloffset = *(unsigned char **)writeaddr;
unsigned char *calladdr = (unsigned char *)(dest + (unsigned int)calloffset);
/* Lookup name of function being called */
if ((*calladdr == 0x8B) && (*(calladdr+2) == 0x24) && (*(calladdr+3) == 0xC3))
{
//a thunk maybe?
char movByte = IA32_MOV_REG_IMM;
/* Calculate the correct mov opcode */
switch (*(calladdr+1))
{
case 0x04:
{
movByte += REG_EAX;
break;
}
case 0x1C:
{
movByte += REG_EBX;
break;
}
case 0x0C:
{
movByte += REG_ECX;
break;
}
case 0x14:
{
movByte += REG_EDX;
break;
}
default:
{
printf("Unknown thunk: %c\n", *(calladdr+1));
#ifndef NDEBUG
abort();
#endif
break;
}
}
/* Move our write address back one to where the call opcode was */
writeaddr--;
/* Write our mov */
*writeaddr = movByte;
writeaddr++;
/* Write the value - The provided program counter value */
*(void **)writeaddr = (void *)pc;
writeaddr += 4;
}
#endif
}
//if dest is NULL, returns minimum number of bytes needed to be copied
//if dest is not NULL, it will copy the bytes to dest as well as fix CALLs and JMPs
//http://www.devmaster.net/forums/showthread.php?t=2311
int copy_bytes(unsigned char *func, unsigned char* dest, int required_len) {
int bytecount = 0;
while(bytecount < required_len && *func != 0xCC)
{
// prefixes F0h, F2h, F3h, 66h, 67h, D8h-DFh, 2Eh, 36h, 3Eh, 26h, 64h and 65h
int operandSize = 4;
int FPU = 0;
int twoByte = 0;
unsigned char opcode = 0x90;
unsigned char modRM = 0xFF;
while(*func == 0xF0 ||
*func == 0xF2 ||
*func == 0xF3 ||
(*func & 0xFC) == 0x64 ||
(*func & 0xF8) == 0xD8 ||
(*func & 0x7E) == 0x62)
{
if(*func == 0x66)
{
operandSize = 2;
}
else if((*func & 0xF8) == 0xD8)
{
FPU = *func;
if (dest)
*dest++ = *func++;
else
func++;
bytecount++;
break;
}
if (dest)
*dest++ = *func++;
else
func++;
bytecount++;
}
// two-byte opcode byte
if(*func == 0x0F)
{
twoByte = 1;
if (dest)
*dest++ = *func++;
else
func++;
bytecount++;
}
// opcode byte
opcode = *func++;
if (dest) *dest++ = opcode;
bytecount++;
// mod R/M byte
modRM = 0xFF;
if(FPU)
{
if((opcode & 0xC0) != 0xC0)
{
modRM = opcode;
}
}
else if(!twoByte)
{
if((opcode & 0xC4) == 0x00 ||
((opcode & 0xF4) == 0x60 && ((opcode & 0x0A) == 0x02 || (opcode & 0x09) == 0x09)) ||
(opcode & 0xF0) == 0x80 ||
((opcode & 0xF8) == 0xC0 && (opcode & 0x0E) != 0x02) ||
(opcode & 0xFC) == 0xD0 ||
(opcode & 0xF6) == 0xF6)
{
modRM = *func++;
if (dest) *dest++ = modRM;
bytecount++;
}
}
else
{
if(((opcode & 0xF0) == 0x00 && (opcode & 0x0F) >= 0x04 && (opcode & 0x0D) != 0x0D) ||
(opcode & 0xF0) == 0x30 ||
opcode == 0x77 ||
(opcode & 0xF0) == 0x80 ||
((opcode & 0xF0) == 0xA0 && (opcode & 0x07) <= 0x02) ||
(opcode & 0xF8) == 0xC8)
{
// No mod R/M byte
}
else
{
modRM = *func++;
if (dest) *dest++ = modRM;
bytecount++;
}
}
// SIB
if((modRM & 0x07) == 0x04 &&
(modRM & 0xC0) != 0xC0)
{
if (dest)
*dest++ = *func++; //SIB
else
func++;
bytecount++;
}
// mod R/M displacement
// Dword displacement, no base
if((modRM & 0xC5) == 0x05) {
if (dest) {
*(unsigned int*)dest = *(unsigned int*)func;
dest += 4;
}
func += 4;
bytecount += 4;
}
// Byte displacement
if((modRM & 0xC0) == 0x40) {
if (dest)
*dest++ = *func++;
else
func++;
bytecount++;
}
// Dword displacement
if((modRM & 0xC0) == 0x80) {
if (dest) {
*(unsigned int*)dest = *(unsigned int*)func;
dest += 4;
}
func += 4;
bytecount += 4;
}
// immediate
if(FPU)
{
// Can't have immediate operand
}
else if(!twoByte)
{
if((opcode & 0xC7) == 0x04 ||
(opcode & 0xFE) == 0x6A || // PUSH/POP/IMUL
(opcode & 0xF0) == 0x70 || // Jcc
opcode == 0x80 ||
opcode == 0x83 ||
(opcode & 0xFD) == 0xA0 || // MOV
opcode == 0xA8 || // TEST
(opcode & 0xF8) == 0xB0 || // MOV
(opcode & 0xFE) == 0xC0 || // RCL
opcode == 0xC6 || // MOV
opcode == 0xCD || // INT
(opcode & 0xFE) == 0xD4 || // AAD/AAM
(opcode & 0xF8) == 0xE0 || // LOOP/JCXZ
opcode == 0xEB ||
(opcode == 0xF6 && (modRM & 0x30) == 0x00)) // TEST
{
if (dest)
*dest++ = *func++;
else
func++;
bytecount++;
}
else if((opcode & 0xF7) == 0xC2) // RET
{
if (dest) {
*(unsigned short*)dest = *(unsigned short*)func;
dest += 2;
}
func += 2;
bytecount += 2;
}
else if((opcode & 0xFC) == 0x80 ||
(opcode & 0xC7) == 0x05 ||
(opcode & 0xF8) == 0xB8 ||
(opcode & 0xFE) == 0xE8 || // CALL/Jcc
(opcode & 0xFE) == 0x68 ||
(opcode & 0xFC) == 0xA0 ||
(opcode & 0xEE) == 0xA8 ||
opcode == 0xC7 ||
(opcode == 0xF7 && (modRM & 0x30) == 0x00))
{
if (dest) {
//Fix CALL/JMP offset
if ((opcode & 0xFE) == 0xE8) {
if (operandSize == 4)
{
*(long*)dest = ((func + *(long*)func) - dest);
//pRED* edit. func is the current address of the call address, +4 is the next instruction, so the value of $pc
check_thunks(dest+4, func+4);
}
else
*(short*)dest = ((func + *(short*)func) - dest);
} else {
if (operandSize == 4)
*(unsigned long*)dest = *(unsigned long*)func;
else
*(unsigned short*)dest = *(unsigned short*)func;
}
dest += operandSize;
}
func += operandSize;
bytecount += operandSize;
}
}
else
{
if(opcode == 0xBA || // BT
opcode == 0x0F || // 3DNow!
(opcode & 0xFC) == 0x70 || // PSLLW
(opcode & 0xF7) == 0xA4 || // SHLD
opcode == 0xC2 ||
opcode == 0xC4 ||
opcode == 0xC5 ||
opcode == 0xC6)
{
if (dest)
*dest++ = *func++;
else
func++;
}
else if((opcode & 0xF0) == 0x80) // Jcc -i
{
if (dest) {
if (operandSize == 4)
*(unsigned long*)dest = *(unsigned long*)func;
else
*(unsigned short*)dest = *(unsigned short*)func;
dest += operandSize;
}
func += operandSize;
bytecount += operandSize;
}
}
}
return bytecount;
}
//insert a specific JMP instruction at the given location
void inject_jmp(void* src, void* dest) {
*(unsigned char*)src = OP_JMP;
*(long*)((unsigned char*)src+1) = (long)((unsigned char*)dest - ((unsigned char*)src + OP_JMP_SIZE));
}
//fill a given block with NOPs
void fill_nop(void* src, unsigned int len) {
unsigned char* src2 = (unsigned char*)src;
while (len) {
*src2++ = OP_NOP;
--len;
}
}
void* eval_jump(void* src) {
unsigned char* addr = (unsigned char*)src;
if (!addr) return 0;
//import table jump
if (addr[0] == OP_PREFIX && addr[1] == OP_JMP_SEG) {
addr += 2;
addr = *(unsigned char**)addr;
//TODO: if addr points into the IAT
return *(void**)addr;
}
//8bit offset
else if (addr[0] == OP_JMP_BYTE) {
addr = &addr[OP_JMP_BYTE_SIZE] + *(char*)&addr[1];
//mangled 32bit jump?
if (addr[0] == OP_JMP) {
addr = addr + *(int*)&addr[1];
}
return addr;
}
/*
//32bit offset
else if (addr[0] == OP_JMP) {
addr = &addr[OP_JMP_SIZE] + *(int*)&addr[1];
}
*/
return addr;
}
/*
from ms detours package
static bool detour_is_imported(PBYTE pbCode, PBYTE pbAddress)
{
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery((PVOID)pbCode, &mbi, sizeof(mbi));
__try {
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)mbi.AllocationBase;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
return false;
}
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
pDosHeader->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
return false;
}
if (pbAddress >= ((PBYTE)pDosHeader +
pNtHeader->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) &&
pbAddress < ((PBYTE)pDosHeader +
pNtHeader->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress +
pNtHeader->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size)) {
return true;
}
return false;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
return false;
}
}
*/

40
asm/asm.h Normal file
View File

@ -0,0 +1,40 @@
#ifndef __ASM_H__
#define __ASM_H__
#define OP_JMP 0xE9
#define OP_JMP_SIZE 5
#define OP_NOP 0x90
#define OP_NOP_SIZE 1
#define OP_PREFIX 0xFF
#define OP_JMP_SEG 0x25
#define OP_JMP_BYTE 0xEB
#define OP_JMP_BYTE_SIZE 2
#ifdef __cplusplus
extern "C" {
#endif
void check_thunks(unsigned char *dest, unsigned char *pc);
//if dest is NULL, returns minimum number of bytes needed to be copied
//if dest is not NULL, it will copy the bytes to dest as well as fix CALLs and JMPs
//http://www.devmaster.net/forums/showthread.php?t=2311
int copy_bytes(unsigned char *func, unsigned char* dest, int required_len);
//insert a specific JMP instruction at the given location
void inject_jmp(void* src, void* dest);
//fill a given block with NOPs
void fill_nop(void* src, unsigned int len);
//evaluate a JMP at the target
void* eval_jump(void* src);
#ifdef __cplusplus
}
#endif
#endif //__ASM_H__

116
extension.cpp Normal file
View File

@ -0,0 +1,116 @@
#include "extension.h"
#include "sigs.h"
#define TIER0_NAME SOURCE_BIN_PREFIX "tier0" SOURCE_BIN_SUFFIX SOURCE_BIN_EXT
Cleaner g_Cleaner;
SMEXT_LINK(&g_Cleaner);
CDetour *g_pDetour = 0;
char ** g_szStrings;
int g_iStrings = 0;
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
DETOUR_DECL_MEMBER4(Detour_LogDirect, LoggingResponse_t, LoggingChannelID_t, channelID, LoggingSeverity_t, severity, Color, color, const tchar *, pMessage)
{
for(int i=0;i<g_iStrings;++i)
if(strstr(pMessage, g_szStrings[i])!=0)
return LR_CONTINUE;
return DETOUR_MEMBER_CALL(Detour_LogDirect)(channelID, severity, color, pMessage);
}
#else
DETOUR_DECL_STATIC2(Detour_DefSpew, SpewRetval_t, SpewType_t, channel, char *, text)
{
for(int i=0;i<g_iStrings;++i)
if(strstr(text, g_szStrings[i])!=0)
return SPEW_CONTINUE;
return DETOUR_STATIC_CALL(Detour_DefSpew)(channel, text);
}
#endif
bool Cleaner::SDK_OnLoad(char *error, size_t maxlength, bool late)
{
CDetourManager::Init(g_pSM->GetScriptingEngine(), 0);
char szPath[256];
g_pSM->BuildPath(Path_SM, szPath, sizeof(szPath), "configs/cleaner.cfg");
FILE * file = fopen(szPath, "r");
if(file==NULL)
{
snprintf(error, maxlength, "Could not read configs/cleaner.cfg.");
return false;
}
int c, lines = 0;
do
{
c = fgetc(file);
++lines;
} while (c != EOF);
rewind(file);
int len;
g_szStrings = (char**)malloc(lines*sizeof(char**));
while(!feof(file))
{
g_szStrings[g_iStrings] = (char*)malloc(256*sizeof(char*));
if (fgets(g_szStrings[g_iStrings], 255, file) != NULL)
{
len = strlen(g_szStrings[g_iStrings]);
if(g_szStrings[g_iStrings][len-1]=='\r' || g_szStrings[g_iStrings][len-1]=='\n')
g_szStrings[g_iStrings][len-1]=0;
if(g_szStrings[g_iStrings][len-2]=='\r')
g_szStrings[g_iStrings][len-2]=0;
++g_iStrings;
}
}
fclose(file);
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
#ifdef PLATFORM_WINDOWS
HMODULE tier0 = GetModuleHandle(TIER0_NAME);
void * fn = memutils->FindPattern(tier0, SIG_WINDOWS, SIG_WIN_SIZE);
#elif defined PLATFORM_LINUX
void * tier0 = dlopen(TIER0_NAME, RTLD_NOW);
void * fn = memutils->ResolveSymbol(tier0, SIG_LINUX);
dlclose(tier0);
#else
#error "Unsupported OS"
#endif
if(!fn)
{
snprintf(error, maxlength, "Failed to find signature. Please contact the author.");
return false;
}
#if defined SIG_LINUX_OFFSET
#ifdef PLATFORM_LINUX
fn = (void *)((intptr_t)fn + SIG_LINUX_OFFSET);
#endif
#endif
g_pDetour = DETOUR_CREATE_MEMBER(Detour_LogDirect, fn);
#else
g_pDetour = DETOUR_CREATE_STATIC(Detour_DefSpew, (gpointer)GetSpewOutputFunc());
#endif
if (g_pDetour == NULL)
{
snprintf(error, maxlength, "Failed to initialize the detours. Please contact the author.");
return false;
}
g_pDetour->EnableDetour();
return true;
}
void Cleaner::SDK_OnUnload()
{
if(g_pDetour)
g_pDetour->Destroy();
delete [] g_szStrings;
}

147
extension.h Normal file
View File

@ -0,0 +1,147 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod Sample Extension
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
/**
* @file extension.h
* @brief Sample extension code header.
*/
#include "smsdk_ext.h"
#include "CDetour/detours.h"
#include <tier0/dbg.h>
//HalfLife2.h
#if defined _WIN32
#define SOURCE_BIN_PREFIX ""
#define SOURCE_BIN_SUFFIX ""
#define SOURCE_BIN_EXT ".dll"
#elif defined __APPLE__
#define SOURCE_BIN_PREFIX ""
#define SOURCE_BIN_SUFFIX ""
#define SOURCE_BIN_EXT ".dylib"
#elif defined __linux__
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 \
|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_LEFT4DEAD2 || SOURCE_ENGINE == SE_NUCLEARDAWN \
|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_INSURGENCY || SOURCE_ENGINE == SE_DOI
#define SOURCE_BIN_PREFIX "lib"
#define SOURCE_BIN_SUFFIX "_srv"
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
#define SOURCE_BIN_PREFIX "lib"
#define SOURCE_BIN_SUFFIX ""
#else
#define SOURCE_BIN_PREFIX ""
#define SOURCE_BIN_SUFFIX "_i486"
#endif
#define SOURCE_BIN_EXT ".so"
#endif
typedef void * gpointer;
/**
* @brief Sample implementation of the SDK Extension.
* Note: Uncomment one of the pre-defined virtual functions in order to use it.
*/
class Cleaner : public SDKExtension
{
public:
/**
* @brief This is called after the initial loading sequence has been processed.
*
* @param error Error message buffer.
* @param maxlength Size of error message buffer.
* @param late Whether or not the module was loaded after map load.
* @return True to succeed loading, false to fail.
*/
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
/**
* @brief This is called right before the extension is unloaded.
*/
virtual void SDK_OnUnload();
/**
* @brief This is called once all known extensions have been loaded.
* Note: It is is a good idea to add natives here, if any are provided.
*/
//virtual void SDK_OnAllLoaded();
/**
* @brief Called when the pause state is changed.
*/
//virtual void SDK_OnPauseChange(bool paused);
/**
* @brief this is called when Core wants to know if your extension is working.
*
* @param error Error message buffer.
* @param maxlength Size of error message buffer.
* @return True if working, false otherwise.
*/
//virtual bool QueryRunning(char *error, size_t maxlength);
public:
#if defined SMEXT_CONF_METAMOD
/**
* @brief Called when Metamod is attached, before the extension version is called.
*
* @param error Error buffer.
* @param maxlength Maximum size of error buffer.
* @param late Whether or not Metamod considers this a late load.
* @return True to succeed, false to fail.
*/
//virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late);
/**
* @brief Called when Metamod is detaching, after the extension version is called.
* NOTE: By default this is blocked unless sent from SourceMod.
*
* @param error Error buffer.
* @param maxlength Maximum size of error buffer.
* @return True to succeed, false to fail.
*/
//virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
/**
* @brief Called when Metamod's pause state is changing.
* NOTE: By default this is blocked unless sent from SourceMod.
*
* @param paused Pause state being set.
* @param error Error buffer.
* @param maxlength Maximum size of error buffer.
* @return True to succeed, false to fail.
*/
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
#endif
};
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_

80
msvc10/sdk.sln Normal file
View File

@ -0,0 +1,80 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdk", "sdk.vcxproj", "{B3E797CF-4E77-4C9D-B8A8-7589B6902206}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug - CSGO|Win32 = Debug - CSGO|Win32
Debug - Alien Swarm|Win32 = Debug - Alien Swarm|Win32
Debug - CSS|Win32 = Debug - CSS|Win32
Debug - Dark Messiah|Win32 = Debug - Dark Messiah|Win32
Debug - Episode 1|Win32 = Debug - Episode 1|Win32
Debug - Left 4 Dead 2|Win32 = Debug - Left 4 Dead 2|Win32
Debug - Left 4 Dead|Win32 = Debug - Left 4 Dead|Win32
Debug - Old Metamod|Win32 = Debug - Old Metamod|Win32
Debug - Orange Box Valve|Win32 = Debug - Orange Box Valve|Win32
Debug - Orange Box|Win32 = Debug - Orange Box|Win32
Debug|Win32 = Debug|Win32
Release - CSGO|Win32 = Release - CSGO|Win32
Release - CSS|Win32 = Release - CSS|Win32
Release - Alien Swarm|Win32 = Release - Alien Swarm|Win32
Release - Dark Messiah|Win32 = Release - Dark Messiah|Win32
Release - Episode 1|Win32 = Release - Episode 1|Win32
Release - Left 4 Dead 2|Win32 = Release - Left 4 Dead 2|Win32
Release - Left 4 Dead|Win32 = Release - Left 4 Dead|Win32
Release - Old Metamod|Win32 = Release - Old Metamod|Win32
Release - Orange Box Valve|Win32 = Release - Orange Box Valve|Win32
Release - Orange Box|Win32 = Release - Orange Box|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Alien Swarm|Win32.ActiveCfg = Debug - Alien Swarm|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Alien Swarm|Win32.Build.0 = Debug - Alien Swarm|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - CSGO|Win32.ActiveCfg = Debug - CSGO|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - CSGO|Win32.Build.0 = Debug - CSGO|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - CSS|Win32.ActiveCfg = Debug - CSS|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - CSS|Win32.Build.0 = Debug - CSS|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Dark Messiah|Win32.ActiveCfg = Debug - Dark Messiah|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Dark Messiah|Win32.Build.0 = Debug - Dark Messiah|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Episode 1|Win32.ActiveCfg = Debug - Episode 1|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Episode 1|Win32.Build.0 = Debug - Episode 1|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Left 4 Dead 2|Win32.ActiveCfg = Debug - Left 4 Dead 2|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Left 4 Dead 2|Win32.Build.0 = Debug - Left 4 Dead 2|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Left 4 Dead|Win32.ActiveCfg = Debug - Left 4 Dead|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Left 4 Dead|Win32.Build.0 = Debug - Left 4 Dead|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Old Metamod|Win32.ActiveCfg = Debug - Old Metamod|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Old Metamod|Win32.Build.0 = Debug - Old Metamod|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Orange Box Valve|Win32.ActiveCfg = Debug - Orange Box Valve|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Orange Box Valve|Win32.Build.0 = Debug - Orange Box Valve|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Orange Box|Win32.ActiveCfg = Debug - Orange Box|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Orange Box|Win32.Build.0 = Debug - Orange Box|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.ActiveCfg = Debug|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.Build.0 = Debug|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Alien Swarm|Win32.ActiveCfg = Release - Alien Swarm|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Alien Swarm|Win32.Build.0 = Release - Alien Swarm|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Dark Messiah|Win32.ActiveCfg = Release - Dark Messiah|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Dark Messiah|Win32.Build.0 = Release - Dark Messiah|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - CSGO|Win32.ActiveCfg = Release - CSGO|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - CSGO|Win32.Build.0 = Release - CSGO|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - CSS|Win32.ActiveCfg = Release - CSS|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - CSS|Win32.Build.0 = Release - CSS|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Episode 1|Win32.ActiveCfg = Release - Episode 1|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Episode 1|Win32.Build.0 = Release - Episode 1|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Left 4 Dead 2|Win32.ActiveCfg = Release - Left 4 Dead 2|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Left 4 Dead 2|Win32.Build.0 = Release - Left 4 Dead 2|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Left 4 Dead|Win32.ActiveCfg = Release - Left 4 Dead|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Left 4 Dead|Win32.Build.0 = Release - Left 4 Dead|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Old Metamod|Win32.ActiveCfg = Release - Old Metamod|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Old Metamod|Win32.Build.0 = Release - Old Metamod|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Orange Box Valve|Win32.ActiveCfg = Release - Orange Box Valve|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Orange Box Valve|Win32.Build.0 = Release - Orange Box Valve|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Orange Box|Win32.ActiveCfg = Release - Orange Box|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Orange Box|Win32.Build.0 = Release - Orange Box|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.ActiveCfg = Release|Win32
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

1164
msvc10/sdk.vcxproj Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
<Filter Include="SourceMod SDK">
<UniqueIdentifier>{31958233-BB2D-4e41-A8F9-CE8A4684F436}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\asm\asm.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\CDetour\detours.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\extension.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\smsdk_ext.cpp">
<Filter>SourceMod SDK</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\asm\asm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\CDetour\detourhelpers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\CDetour\detours.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\extension.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\sigs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\smsdk_config.h">
<Filter>SourceMod SDK</Filter>
</ClInclude>
<ClInclude Include="..\..\smsdk_ext.h">
<Filter>SourceMod SDK</Filter>
</ClInclude>
</ItemGroup>
</Project>

15
sigs.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _SIGS_H_
#define _SIGS_H_
#if SOURCE_ENGINE == SE_CSGO
#define SIG_WINDOWS "\x55\x8B\xEC\x83\xE4\xF8\x8B\x45\x08\x83\xEC\x14"
#define SIG_WIN_SIZE 12
#define SIG_LINUX "LoggingSystem_Log"
#define SIG_LINUX_OFFSET 144
#elif SOURCE_ENGINE == SE_LEFT4DEAD2
#define SIG_WINDOWS "\x55\x8B\xEC\x83\xEC\x1C\xA1\x2A\x2A\x2A\x2A"
#define SIG_WIN_SIZE 11
#define SIG_LINUX "_ZN14CLoggingSystem9LogDirectEi17LoggingSeverity_t5ColorPKc"
#endif
#endif // _SIGS_H_

81
smsdk_config.h Normal file
View File

@ -0,0 +1,81 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod Sample Extension
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
#define _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
/**
* @file smsdk_config.h
* @brief Contains macros for configuring basic extension information.
*/
/* Basic information exposed publicly */
#define SMEXT_CONF_NAME "Console Cleaner"
#define SMEXT_CONF_DESCRIPTION "Console warning suppressor"
#define SMEXT_CONF_VERSION "1.1.0"
#define SMEXT_CONF_AUTHOR "Zephyrus, Accelerator"
#define SMEXT_CONF_URL "https://github.com/Accelerator74/Cleaner"
#define SMEXT_CONF_LOGTAG "Cleaner"
#define SMEXT_CONF_LICENSE "GPLv3"
#define SMEXT_CONF_DATESTRING __DATE__
/**
* @brief Exposes plugin's main interface.
*/
#define SMEXT_LINK(name) SDKExtension *g_pExtensionIface = name;
/**
* @brief Sets whether or not this plugin required Metamod.
* NOTE: Uncomment to enable, comment to disable.
*/
//#define SMEXT_CONF_METAMOD
/** Enable interfaces you want to use here by uncommenting lines */
//#define SMEXT_ENABLE_FORWARDSYS
//#define SMEXT_ENABLE_HANDLESYS
//#define SMEXT_ENABLE_PLAYERHELPERS
//#define SMEXT_ENABLE_DBMANAGER
#define SMEXT_ENABLE_GAMECONF
#define SMEXT_ENABLE_MEMUTILS
//#define SMEXT_ENABLE_GAMEHELPERS
//#define SMEXT_ENABLE_TIMERSYS
//#define SMEXT_ENABLE_THREADER
//#define SMEXT_ENABLE_LIBSYS
//#define SMEXT_ENABLE_MENUS
//#define SMEXT_ENABLE_ADTFACTORY
//#define SMEXT_ENABLE_PLUGINSYS
//#define SMEXT_ENABLE_ADMINSYS
//#define SMEXT_ENABLE_TEXTPARSERS
//#define SMEXT_ENABLE_USERMSGS
//#define SMEXT_ENABLE_TRANSLATOR
//#define SMEXT_ENABLE_NINVOKE
#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_