All pastes #2051775 Raw Edit

Someone

public text v1 · immutable
#2051775 ·published 2011-04-29 01:00 UTC
rendered paste body
#include "amxxmodule.h"
#include <windows.h>

#define OFFSET_TEAM 456
#define TEAM_SPECTATOR 3
#define FREELOOK_ENABLE 0
#define FREELOOK_DISABLE 1

const BYTE signature[]=
{0x8B,0x83,0xC8,0x01,0x00,0x00,0xC6,0x44,0x24,0x1C,0x01,0x83,0xF8,0x03};
BYTE patch[]=
{0xC6,0x44,0x24,0x1C,0x01,0xB8,0x90,0x90,0x90,0x90,0xFF,0xD0,0x85,0xC0};

cvar_t amx_adminfreelook = {"amx_adminfreelook", "1", 1, 1.0};
cvar_t amx_adminfreelookflag = {"amx_adminfreelookflag", "d"};
cvar_t *amx_afl;
cvar_t *amx_aflf;

static DWORD get_patch_loc()
{
	MEMORY_BASIC_INFORMATION mem;
	if(!VirtualQuery(MDLL_AddToFullPack, &mem, sizeof(mem)))
		return NULL;

	if(mem.AllocationBase == NULL)
		return NULL;

	DWORD address = (DWORD)mem.AllocationBase;
	IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)address;

	if(IsBadReadPtr(dos, sizeof(IMAGE_DOS_HEADER)) || dos->e_magic != IMAGE_DOS_SIGNATURE)
		return NULL;

	address += dos->e_lfanew;
	IMAGE_NT_HEADERS *pe = (IMAGE_NT_HEADERS *)address;

	if(IsBadReadPtr(pe, sizeof(IMAGE_NT_HEADERS)) || pe->Signature != IMAGE_NT_SIGNATURE)
		return NULL;

	DWORD begin = address + pe->OptionalHeader.BaseOfCode;
	DWORD end = begin + pe->OptionalHeader.SizeOfCode - sizeof(signature);

	for(DWORD addr = begin; addr < end; ++addr)
	{
		if(!memcmp((PVOID)addr, signature, sizeof(signature)))
			return addr;
	}
	return NULL;
}

inline int PrivateToIndex(const PVOID pdata)
{
	if(pdata)
	{
		char *ptr = (char *)pdata;
		ptr += 4;
		entvars_t *pev = *(entvars_t **)ptr;
		if(pev && pev->pContainingEntity)
			return ENTINDEX(pev->pContainingEntity);
	}
	return -1;
}

int UTIL_ReadFlags(const char* c)
{
	int flags = 0;
	while(*c)
		flags |= (1<<(*c++ - 'a'));
	return flags;
}

int admin_freelook()
{
	int team;
	__asm mov eax, [ebx + OFFSET_TEAM];
	__asm mov team, eax;

	if(amx_afl->value == 0)
		return team != TEAM_SPECTATOR;

	PVOID pWatcher = NULL;
	__asm mov pWatcher, ebx;
	
	int id = PrivateToIndex(pWatcher);
	
	if(MF_GetPlayerFlags(id) & UTIL_ReadFlags(amx_aflf->string))
		return FREELOOK_ENABLE;

	return team != TEAM_SPECTATOR;
}

void OnMetaAttach()
{
	PVOID addr = (PVOID)get_patch_loc();
	if(!addr)
	{
		SERVER_PRINT("[ADMIN FREE LOOK] patch failed.\n");
		return;
	}

	union
	{
		PVOID func;
		BYTE fbyte[4];
	}ptob;

	ptob.func = &admin_freelook;
	patch[6] = ptob.fbyte[0];
	patch[7] = ptob.fbyte[1];
	patch[8] = ptob.fbyte[2];
	patch[9] = ptob.fbyte[3];
	
	DWORD oldflags;
	if(VirtualProtect(addr, sizeof(signature), PAGE_EXECUTE_READWRITE, &oldflags))
	{
		memcpy(addr, patch, sizeof(patch));
		DWORD flags;
		if(VirtualProtect(addr, sizeof(signature), oldflags, &flags))
		{
			SERVER_PRINT("[ADMIN FREE LOOK] patch succeed.\n");
			CVAR_REGISTER(&amx_adminfreelook);
			CVAR_REGISTER(&amx_adminfreelookflag);
			amx_afl = CVAR_GET_POINTER(amx_adminfreelook.name);
			amx_aflf = CVAR_GET_POINTER(amx_adminfreelookflag.name);
			return;
		}
	}
	SERVER_PRINT("[ADMIN FREE LOOK] patch failed.\n");
	return;
}