mirror of
https://github.com/accelerator74/l4dtoolz.git
synced 2025-09-19 12:16:18 +08:00

committed by
Ivaylo Spasov

parent
488c5fd7f8
commit
934b59b480
2
Makefile
2
Makefile
@ -14,7 +14,7 @@ MMSOURCE19 = ..
|
|||||||
#####################################
|
#####################################
|
||||||
|
|
||||||
PROJECT = l4dtoolz_mm
|
PROJECT = l4dtoolz_mm
|
||||||
OBJECTS = l4dtoolz_mm.cpp
|
OBJECTS = l4dtoolz_mm.cpp signature.cpp
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
||||||
|
18
game_signature.h
Normal file
18
game_signature.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef _INCLUDE_L4D1_SIGNATURE_LINUX_
|
||||||
|
#define _INCLUDE_L4D1_SIGNATURE_LINUX_
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#ifdef L4D1
|
||||||
|
#include "l4d1_signature_win32.h"
|
||||||
|
#else
|
||||||
|
#include "l4d2_signature_win32.h"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef L4D1
|
||||||
|
#include "l4d1_signature_linux.h"
|
||||||
|
#else
|
||||||
|
#include "l4d2_signature_linux.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //_INCLUDE_L4D1_SIGNATURE_LINUX_
|
@ -1,6 +1,10 @@
|
|||||||
|
#ifndef _INCLUDE_L4D1_SIGNATURE_LINUX_
|
||||||
|
#define _INCLUDE_L4D1_SIGNATURE_LINUX_
|
||||||
|
|
||||||
const char* server_dll = "server.so";
|
const char* server_dll = "server.so";
|
||||||
const char* engine_dll = "engine.so";
|
const char* engine_dll = "engine.so";
|
||||||
const char* matchmaking_dll = "matchmaking_ds.so";
|
const char* matchmaking_dll = "matchmaking_ds.so";
|
||||||
|
const char* matchmaking_dll_alt = "matchmaking.so";
|
||||||
|
|
||||||
//CBaseServer::GetMaxHumanPlayers(void)const
|
//CBaseServer::GetMaxHumanPlayers(void)const
|
||||||
//fuction is in engine.so
|
//fuction is in engine.so
|
||||||
@ -50,3 +54,6 @@ char* unreserved_org = NULL;
|
|||||||
const char* lobby_match = "\x0A\x55\x89\xE5\xB8\x08\x00\x00\x00\x5D\xC3";
|
const char* lobby_match = "\x0A\x55\x89\xE5\xB8\x08\x00\x00\x00\x5D\xC3";
|
||||||
unsigned char lobby_match_new[] = {0x01, 0x04, 0xC3};
|
unsigned char lobby_match_new[] = {0x01, 0x04, 0xC3};
|
||||||
char* lobby_match_org = NULL;
|
char* lobby_match_org = NULL;
|
||||||
|
|
||||||
|
#endif //_INCLUDE_L4D1_SIGNATURE_LINUX_
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
#ifndef _INCLUDE_L4D1_SIGNATURE_WIN32_
|
||||||
|
#define _INCLUDE_L4D1_SIGNATURE_WIN32_
|
||||||
|
|
||||||
const char* server_dll = "server.dll";
|
const char* server_dll = "server.dll";
|
||||||
const char* engine_dll = "engine.dll";
|
const char* engine_dll = "engine.dll";
|
||||||
const char* matchmaking_dll = "matchmaking_ds.dll";
|
const char* matchmaking_dll = "matchmaking_ds.dll";
|
||||||
|
const char* matchmaking_dll_alt = "matchmaking.dll";
|
||||||
|
|
||||||
const char* friends_lobby = "\x12\x56\x8B\xF1\x8B\x0D\xC3\xC3\xC3\xC3\x85\xC9\x74\xC3\x8B\x01\x8B\x50\x48";
|
const char* friends_lobby = "\x12\x56\x8B\xF1\x8B\x0D\xC3\xC3\xC3\xC3\x85\xC9\x74\xC3\x8B\x01\x8B\x50\x48";
|
||||||
unsigned char friends_lobby_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3};
|
unsigned char friends_lobby_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3};
|
||||||
@ -38,3 +42,5 @@ const char* lobby_match = "\x06\xB8\x08\x00\x00\x00\xC3";
|
|||||||
unsigned char lobby_match_new[] = {0x01, 0x01, 0xC3};
|
unsigned char lobby_match_new[] = {0x01, 0x01, 0xC3};
|
||||||
char* lobby_match_org = NULL;
|
char* lobby_match_org = NULL;
|
||||||
|
|
||||||
|
#endif //_INCLUDE_L4D1_SIGNATURE_WIN32_
|
||||||
|
|
||||||
|
@ -1,39 +1,45 @@
|
|||||||
|
#ifndef _INCLUDE_L4D2_SIGNATURE_LINUX_
|
||||||
|
#define _INCLUDE_L4D2_SIGNATURE_LINUX_
|
||||||
|
|
||||||
const char* server_dll = "server.so";
|
const char* server_dll = "server.so";
|
||||||
const char* engine_dll = "engine.so";
|
const char* engine_dll = "engine.so";
|
||||||
const char* matchmaking_dll = "matchmaking_ds.so";
|
const char* matchmaking_dll = "matchmaking_ds.so";
|
||||||
|
const char* matchmaking_dll_alt = "matchmaking.so";
|
||||||
|
|
||||||
const char* friends_lobby = "\x18\x55\x89\xE5\x56\x53\x83\xEC\x10\xE8\xC3\xC3\xC3\xC3\x81\xC3\xC3\xC3\xC3\xC3\x8B\xC3\xC3\x8B\x83";
|
const char* friends_lobby = "\x18\x55\x89\xE5\x56\x53\x83\xEC\x10\xE8\xC3\xC3\xC3\xC3\x81\xC3\xC3\xC3\xC3\xC3\x8B\xC3\xC3\x8B\x83";
|
||||||
unsigned char friends_lobby_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3};
|
unsigned char friends_lobby_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3};
|
||||||
char* friends_lobby_org = NULL;
|
void *friends_lobby_org = NULL;
|
||||||
|
|
||||||
const char* lobby_sux = "\x09\x8B\x96\x7C\x01\x00\x00\x85\xD2\x74";
|
const char* lobby_sux = "\x09\x8B\x96\x7C\x01\x00\x00\x85\xD2\x74";
|
||||||
const char* lobby_sux_new = "\x02\x08\x90\x90";
|
const char* lobby_sux_new = "\x02\x08\x90\x90";
|
||||||
char* lobby_sux_org = NULL;
|
void *lobby_sux_org = NULL;
|
||||||
|
|
||||||
const char* max_players = "\x10\xFF\xC3\xC3\x03\xC3\xC3\x29\xC7\x3B\xBE\x7C\x01\x00\x00\x0F\x8F";
|
const char* max_players = "\x10\xFF\xC3\xC3\x03\xC3\xC3\x29\xC7\x3B\xBE\x7C\x01\x00\x00\x0F\x8F";
|
||||||
char max_players_new[]= {0x06, 0x08, 0x83, 0xFF, 0x3C, 0x90, 0x90, 0x90};
|
char max_players_new[]= {0x06, 0x08, 0x83, 0xFF, 0x3C, 0x90, 0x90, 0x90};
|
||||||
char* max_players_org = NULL;
|
void *max_players_org = NULL;
|
||||||
|
|
||||||
const char* server_bplayers ="\x21\x55\x89\xE5\x53\x83\xEC\x14\xE8\xC3\xC3\xC3\xC3\x81\xC3\xC3\xC3\xC3\xC3\x8B\x83\xC3\xC3\xC3\xC3\x8B\x10\xB8\xFF\xFF\xFF\xFF\x85\xD2";
|
const char* server_bplayers ="\x21\x55\x89\xE5\x53\x83\xEC\x14\xE8\xC3\xC3\xC3\xC3\x81\xC3\xC3\xC3\xC3\xC3\x8B\x83\xC3\xC3\xC3\xC3\x8B\x10\xB8\xFF\xFF\xFF\xFF\x85\xD2";
|
||||||
unsigned char server_bplayers_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3};
|
unsigned char server_bplayers_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3};
|
||||||
char* server_bplayers_org = NULL;
|
void *server_bplayers_org = NULL;
|
||||||
|
|
||||||
const char* human_limit = "\x11\x8B\x55\xC3\x8B\x02\x89\x14\xC3\xFF\x90\x24\x02\x00\x00\x39\xF8\x7E";
|
const char* human_limit = "\x11\x8B\x55\xC3\x8B\x02\x89\x14\xC3\xFF\x90\x24\x02\x00\x00\x39\xF8\x7E";
|
||||||
const char* human_limit_new = "\x02\x10\x90\x90";
|
const char* human_limit_new = "\x02\x10\x90\x90";
|
||||||
char* human_limit_org = NULL;
|
void *human_limit_org = NULL;
|
||||||
|
|
||||||
const char* players = "\x13\x83\xBB\xC3\xC3\xC3\xC3\x01\x7F\xC3\x8B\x80\x0C\xC3\xC3\x00\x89\xC3\xC3\xE8";
|
const char* players = "\x13\x83\xBB\xC3\xC3\xC3\xC3\x01\x7F\xC3\x8B\x80\x0C\xC3\xC3\x00\x89\xC3\xC3\xE8";
|
||||||
const char* players_new = "\x02\x07\x90\x90";
|
const char* players_new = "\x02\x07\x90\x90";
|
||||||
char* players_org = NULL;
|
void *players_org = NULL;
|
||||||
|
|
||||||
const char* players_new2 = "\x01\x1F\xEB";
|
const char* players_new2 = "\x01\x1F\xEB";
|
||||||
char* players_org2 = NULL;
|
void *players_org2 = NULL;
|
||||||
|
|
||||||
const char* unreserved = "\x1B\x55\x89\xE5\x57\x56\x53\x81\xEC\x4C\x01\x00\x00\xE8\xC3\xC3\xC3\xC3\x81\xC3\xB7\xEB\x23\x00\x8B\xC3\xC3\x8B";
|
const char* unreserved = "\x1F\x55\x89\xE5\x57\x56\x53\x81\xEC\x4C\x01\x00\x00\xE8\xC3\xC3\xC3\xC3\x81\xC3\xC3\xC3\xC3\x00\x8B\x75\xC3\x8B\x55\xC3\x8B\x45";
|
||||||
const char* unreserved_new = "\x01\x00\xC3";
|
const char* unreserved_new = "\x01\x00\xC3";
|
||||||
char* unreserved_org = NULL;
|
void *unreserved_org = NULL;
|
||||||
|
|
||||||
const char* lobby_match = "\x0A\x55\x89\xE5\xB8\x08\x00\x00\x00\x5D\xC3";
|
const char* lobby_match = "\x0A\x55\x89\xE5\xB8\x08\x00\x00\x00\x5D\xC3";
|
||||||
unsigned char lobby_match_new[] = {0x01, 0x04, 0xC3};
|
unsigned char lobby_match_new[] = {0x01, 0x04, 0xC3};
|
||||||
char* lobby_match_org = NULL;
|
void *lobby_match_org = NULL;
|
||||||
|
|
||||||
|
#endif //_INCLUDE_L4D2_SIGNATURE_LINUX_
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
#ifndef _INCLUDE_L4D2_SIGNATURE_WIN32_
|
||||||
|
#define _INCLUDE_L4D2_SIGNATURE_WIN32_
|
||||||
|
|
||||||
const char* server_dll = "server.dll";
|
const char* server_dll = "server.dll";
|
||||||
const char* engine_dll = "engine.dll";
|
const char* engine_dll = "engine.dll";
|
||||||
const char* matchmaking_dll = "matchmaking_ds.dll";
|
const char* matchmaking_dll = "matchmaking_ds.dll";
|
||||||
|
const char* matchmaking_dll_alt = "matchmaking.dll";
|
||||||
|
|
||||||
const char* friends_lobby = "\x12\x56\x8B\xF1\x8B\x0D\xC3\xC3\xC3\xC3\x85\xC9\x74\xC3\x8B\x01\x8B\x50\x48";
|
const char* friends_lobby = "\x12\x56\x8B\xF1\x8B\x0D\xC3\xC3\xC3\xC3\x85\xC9\x74\xC3\x8B\x01\x8B\x50\x48";
|
||||||
unsigned char friends_lobby_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3};
|
unsigned char friends_lobby_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3};
|
||||||
@ -38,3 +42,5 @@ const char* lobby_match = "\x06\xB8\x08\x00\x00\x00\xC3";
|
|||||||
unsigned char lobby_match_new[] = {0x01, 0x01, 0xC3};
|
unsigned char lobby_match_new[] = {0x01, 0x01, 0xC3};
|
||||||
char* lobby_match_org = NULL;
|
char* lobby_match_org = NULL;
|
||||||
|
|
||||||
|
#endif //_INCLUDE_L4D2_SIGNATURE_WIN32_
|
||||||
|
|
||||||
|
413
l4dtoolz_mm.cpp
413
l4dtoolz_mm.cpp
@ -1,260 +1,104 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include "l4dtoolz_mm.h"
|
#include "l4dtoolz_mm.h"
|
||||||
|
#include "signature.h"
|
||||||
#ifdef WIN32
|
#include "game_signature.h"
|
||||||
#include <windows.h>
|
|
||||||
#include <TlHelp32.h>
|
|
||||||
#else
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <link.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#ifdef L4D1
|
|
||||||
#include "l4d1_signature_win32.h"
|
|
||||||
#else
|
|
||||||
#include "l4d2_signature_win32.h"
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#ifdef L4D1
|
|
||||||
#include "l4d1_signature_linux.h"
|
|
||||||
#else
|
|
||||||
#include "l4d2_signature_linux.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
l4dtoolz g_l4dtoolz;
|
l4dtoolz g_l4dtoolz;
|
||||||
IVEngineServer* engine = NULL;
|
IVEngineServer* engine = NULL;
|
||||||
IServerPluginCallbacks* vsp_callbacks = NULL;
|
IServerPluginCallbacks* vsp_callbacks = NULL;
|
||||||
ICvar* icvar = NULL;
|
ICvar* icvar = NULL;
|
||||||
|
|
||||||
#ifdef WIN32
|
void* l4dtoolz::max_players_friend_lobby = NULL;
|
||||||
HANDLE l4dtoolz::hProcess;
|
void* l4dtoolz::max_players_connect = NULL;
|
||||||
#endif
|
void* l4dtoolz::max_players_server_browser = NULL;
|
||||||
|
void* l4dtoolz::lobby_sux_ptr = NULL;
|
||||||
char* l4dtoolz::max_players_friend_lobby = NULL;
|
void* l4dtoolz::chuman_limit = NULL;
|
||||||
char* l4dtoolz::max_players_connect = NULL;
|
void* l4dtoolz::tmp_player = NULL;
|
||||||
char* l4dtoolz::max_players_server_browser = NULL;
|
void* l4dtoolz::tmp_player2 = NULL;
|
||||||
char* l4dtoolz::lobby_sux_ptr = NULL;
|
void* l4dtoolz::unreserved_ptr = NULL;
|
||||||
char* l4dtoolz::chuman_limit = NULL;
|
void* l4dtoolz::lobby_match_ptr = NULL;
|
||||||
char* l4dtoolz::tmp_player = NULL;
|
|
||||||
char* l4dtoolz::tmp_player2 = NULL;
|
|
||||||
char* l4dtoolz::unreserved_ptr = NULL;
|
|
||||||
char* l4dtoolz::lobby_match_ptr = NULL;
|
|
||||||
|
|
||||||
ConVar sv_maxplayers("sv_maxplayers", "-1", 0, "Max Human Players", true, -1, true, 32, l4dtoolz::OnChangeMaxplayers);
|
ConVar sv_maxplayers("sv_maxplayers", "-1", 0, "Max Human Players", true, -1, true, 32, l4dtoolz::OnChangeMaxplayers);
|
||||||
ConVar sv_removehumanlimit("sv_removehumanlimit", "0", 0, "Remove Human limit reached kick", true, 0, true, 1, l4dtoolz::OnChangeRemovehumanlimit);
|
ConVar sv_removehumanlimit("sv_removehumanlimit", "0", 0, "Remove Human limit reached kick", true, 0, true, 1, l4dtoolz::OnChangeRemovehumanlimit);
|
||||||
ConVar L4DToolZ("L4DToolZ", "",0,"L4DToolZ Author",l4dtoolz::OnChangeIvailosp);
|
ConVar L4DToolZ("L4DToolZ", "",0,"L4DToolZ Author",l4dtoolz::OnChangeIvailosp);
|
||||||
ConVar sv_force_unreserved("sv_force_unreserved", "0", 0, "Disallow lobby reservation cookie", true, 0, true, 1, l4dtoolz::OnChangeUnreserved);
|
ConVar sv_force_unreserved("sv_force_unreserved", "0", 0, "Disallow lobby reservation cookie", true, 0, true, 1, l4dtoolz::OnChangeUnreserved);
|
||||||
|
|
||||||
void* l4dtoolz::FindSignature(const char* mask, const char* base_addr, size_t base_len, bool pure_sign)
|
|
||||||
{
|
|
||||||
char *pBasePtr = (char *)base_addr;
|
|
||||||
char *pEndPtr = pBasePtr+base_len-(int)mask[0];
|
|
||||||
int i;
|
|
||||||
char* tmp;
|
|
||||||
if(base_addr == NULL)
|
|
||||||
return NULL;
|
|
||||||
#ifndef WIN32
|
|
||||||
unsigned int p_size = sysconf(_SC_PAGESIZE);
|
|
||||||
char* all_adr = (char*)((unsigned int)pBasePtr & ~(p_size-1));
|
|
||||||
unsigned int size = pEndPtr - all_adr;
|
|
||||||
mlock(all_adr, size);
|
|
||||||
#endif
|
|
||||||
while(pBasePtr < pEndPtr)
|
|
||||||
{
|
|
||||||
tmp = pBasePtr;
|
|
||||||
|
|
||||||
for(i = 1; i <= mask[0]; ++i){
|
|
||||||
if(mask[i] == '\xC3' && pure_sign == false){
|
|
||||||
tmp++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(mask[i] != *tmp ){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tmp++;
|
|
||||||
}
|
|
||||||
if(i-1 == mask[0]){
|
|
||||||
#ifndef WIN32
|
|
||||||
munlock(all_adr, size);
|
|
||||||
#endif
|
|
||||||
return pBasePtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
pBasePtr++;
|
|
||||||
}
|
|
||||||
#ifndef WIN32
|
|
||||||
munlock(all_adr, size);
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#ifndef WIN32
|
|
||||||
struct v_data{
|
|
||||||
char* fname;
|
|
||||||
char* baddr;
|
|
||||||
size_t blen;
|
|
||||||
};
|
|
||||||
static int callback(struct dl_phdr_info *info, size_t size, void *data)
|
|
||||||
{
|
|
||||||
if (!info->dlpi_name || !info->dlpi_name[0]){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
char* filename = ((v_data*)data)->fname;
|
|
||||||
if(strstr(info->dlpi_name, filename)){
|
|
||||||
if(strstr( info->dlpi_name, "metamod") == NULL){
|
|
||||||
((v_data*)data)->baddr = (char*)info->dlpi_addr;
|
|
||||||
((v_data*)data)->blen = 0;
|
|
||||||
for(int j = 0; j < info->dlpi_phnum; ++j){
|
|
||||||
((v_data*)data)->blen+=info->dlpi_phdr[j].p_filesz;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
bool l4dtoolz::find_base(const char* name, char*& base_addr, size_t& base_len){
|
|
||||||
base_addr = NULL;
|
|
||||||
base_len = 0;
|
|
||||||
#ifdef WIN32
|
|
||||||
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
|
|
||||||
MODULEENTRY32 modent;
|
|
||||||
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
|
|
||||||
if(hModuleSnap == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
modent.dwSize = sizeof(MODULEENTRY32);
|
|
||||||
|
|
||||||
if(!Module32Next(hModuleSnap, &modent))
|
|
||||||
{
|
|
||||||
CloseHandle(hModuleSnap);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if(strstr( modent.szExePath, name))
|
|
||||||
{
|
|
||||||
if(strstr( modent.szExePath, "metamod"))
|
|
||||||
continue;
|
|
||||||
base_addr = (char*)modent.modBaseAddr;
|
|
||||||
base_len = modent.modBaseSize;
|
|
||||||
CloseHandle(hModuleSnap);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} while(Module32Next(hModuleSnap, &modent));
|
|
||||||
CloseHandle(hModuleSnap);
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
v_data vdata;
|
|
||||||
vdata.fname = (char*)name;
|
|
||||||
if(dl_iterate_phdr(callback, &vdata)){
|
|
||||||
base_addr = vdata.baddr;
|
|
||||||
base_len = vdata.blen;
|
|
||||||
return true;
|
|
||||||
}else{
|
|
||||||
base_addr = 0;
|
|
||||||
base_len = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void l4dtoolz::WriteSignature(char* addr, const char* signature){
|
|
||||||
#ifdef WIN32
|
|
||||||
WriteProcessMemory(hProcess,addr+signature[1], signature+2, signature[0], NULL);
|
|
||||||
#else
|
|
||||||
unsigned int p_size = sysconf(_SC_PAGESIZE);
|
|
||||||
char* all_adr = (char*)(((unsigned int)addr + signature[1]) & ~(p_size-1));
|
|
||||||
unsigned int size = addr - all_adr + signature[0];
|
|
||||||
mlock(all_adr, size);
|
|
||||||
mprotect(all_adr, size, PROT_READ|PROT_WRITE|PROT_EXEC);
|
|
||||||
memcpy(addr+signature[1], signature+2, signature[0]);
|
|
||||||
munlock(all_adr, size);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void l4dtoolz::ReadSignature(const char* addr, char* signature){
|
|
||||||
#ifdef WIN32
|
|
||||||
ReadProcessMemory(hProcess, addr+signature[1], signature+2, signature[0], NULL);
|
|
||||||
#else
|
|
||||||
unsigned int p_size = sysconf(_SC_PAGESIZE);
|
|
||||||
char* all_adr = (char*)(((unsigned int)addr + signature[1]) & ~(p_size-1));
|
|
||||||
unsigned int size = addr - all_adr + signature[0];
|
|
||||||
mlock(all_adr, size);
|
|
||||||
memcpy(signature+2, addr+signature[1], signature[0]);
|
|
||||||
munlock(all_adr, size);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void l4dtoolz::OnChangeMaxplayers ( IConVar *var, const char *pOldValue, float flOldValue )
|
void l4dtoolz::OnChangeMaxplayers ( IConVar *var, const char *pOldValue, float flOldValue )
|
||||||
{
|
{
|
||||||
if (max_players_friend_lobby == NULL || max_players_connect == NULL || max_players_server_browser == NULL || lobby_sux_ptr == NULL){
|
int new_value = ((ConVar*)var)->GetInt();
|
||||||
|
int old_value = atoi(pOldValue);
|
||||||
|
if (max_players_friend_lobby == NULL || max_players_connect == NULL || max_players_server_browser == NULL || lobby_sux_ptr == NULL) {
|
||||||
Msg("sv_maxplayers init error\n");
|
Msg("sv_maxplayers init error\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(((ConVar*)var)->GetInt() >= 0){
|
if(new_value != old_value) {
|
||||||
max_players_new[4] = friends_lobby_new[3] = server_bplayers_new[3] = ((ConVar*)var)->GetInt();
|
if(new_value) {
|
||||||
if(lobby_match_ptr != NULL){
|
max_players_new[4] = friends_lobby_new[3] = server_bplayers_new[3] = new_value;
|
||||||
lobby_match_new[2] = ((ConVar*)var)->GetInt();
|
if(lobby_match_ptr != NULL) {
|
||||||
WriteSignature(lobby_match_ptr, (const char*)lobby_match_new);
|
lobby_match_new[2] = new_value;
|
||||||
}else{
|
write_signature(lobby_match_ptr, lobby_match_new);
|
||||||
|
} else {
|
||||||
Msg("sv_maxplayers MS init error\n");
|
Msg("sv_maxplayers MS init error\n");
|
||||||
}
|
}
|
||||||
WriteSignature(max_players_friend_lobby, (const char*)friends_lobby_new);
|
write_signature(max_players_friend_lobby, friends_lobby_new);
|
||||||
WriteSignature(max_players_connect, (const char*)max_players_new);
|
write_signature(max_players_connect, max_players_new);
|
||||||
WriteSignature(lobby_sux_ptr, lobby_sux_new);
|
write_signature(lobby_sux_ptr, lobby_sux_new);
|
||||||
WriteSignature(max_players_server_browser, (const char*)server_bplayers_new);
|
write_signature(max_players_server_browser, server_bplayers_new);
|
||||||
}else{
|
} else {
|
||||||
WriteSignature(max_players_friend_lobby, friends_lobby_org);
|
write_signature(max_players_friend_lobby, friends_lobby_org);
|
||||||
WriteSignature(max_players_connect, max_players_org);
|
write_signature(max_players_connect, max_players_org);
|
||||||
WriteSignature(lobby_sux_ptr, lobby_sux_org);
|
write_signature(lobby_sux_ptr, lobby_sux_org);
|
||||||
WriteSignature(max_players_server_browser, server_bplayers_org);
|
write_signature(max_players_server_browser, server_bplayers_org);
|
||||||
|
|
||||||
if(lobby_match_ptr != NULL)
|
if(lobby_match_ptr != NULL)
|
||||||
WriteSignature(lobby_match_ptr, lobby_match_org);
|
write_signature(lobby_match_ptr, lobby_match_org);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void l4dtoolz::OnChangeRemovehumanlimit ( IConVar *var, const char *pOldValue, float flOldValue )
|
void l4dtoolz::OnChangeRemovehumanlimit ( IConVar *var, const char *pOldValue, float flOldValue )
|
||||||
{
|
{
|
||||||
if(chuman_limit == NULL){
|
int new_value = ((ConVar*)var)->GetInt();
|
||||||
|
int old_value = atoi(pOldValue);
|
||||||
|
if(chuman_limit == NULL) {
|
||||||
Msg( "sv_removehumanlimit init error\n");
|
Msg( "sv_removehumanlimit init error\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if( ((ConVar*)var)->GetInt() == 1){
|
if(new_value != old_value) {
|
||||||
WriteSignature(chuman_limit, human_limit_new);
|
if(new_value == 1) {
|
||||||
|
write_signature(chuman_limit, human_limit_new);
|
||||||
}else{
|
}else{
|
||||||
WriteSignature(chuman_limit, human_limit_org);
|
write_signature(chuman_limit, human_limit_org);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void l4dtoolz::OnChangeIvailosp ( IConVar *var, const char *pOldValue, float flOldValue )
|
void l4dtoolz::OnChangeIvailosp ( IConVar *var, const char *pOldValue, float flOldValue )
|
||||||
{
|
{
|
||||||
if(tmp_player == NULL || tmp_player2 == NULL){
|
if(tmp_player == NULL || tmp_player2 == NULL) {
|
||||||
Msg("L4DToolZ init error\n");
|
Msg("L4DToolZ init error\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WriteSignature(tmp_player, players_org);
|
write_signature(tmp_player, players_org);
|
||||||
WriteSignature(tmp_player2, players_org2);
|
write_signature(tmp_player2, players_org2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void l4dtoolz::OnChangeUnreserved ( IConVar *var, const char *pOldValue, float flOldValue )
|
void l4dtoolz::OnChangeUnreserved ( IConVar *var, const char *pOldValue, float flOldValue )
|
||||||
{
|
{
|
||||||
if(unreserved_ptr == NULL ){
|
int new_value = ((ConVar*)var)->GetInt();
|
||||||
|
int old_value = atoi(pOldValue);
|
||||||
|
if(unreserved_ptr == NULL ) {
|
||||||
Msg("unreserved_ptr init error\n");
|
Msg("unreserved_ptr init error\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if( ((ConVar*)var)->GetInt() == 1){
|
if(new_value != old_value) {
|
||||||
WriteSignature(unreserved_ptr, unreserved_new);
|
if(new_value == 1) {
|
||||||
|
write_signature(unreserved_ptr, unreserved_new);
|
||||||
engine->ServerCommand("sv_allow_lobby_connect_only 0\n");
|
engine->ServerCommand("sv_allow_lobby_connect_only 0\n");
|
||||||
}else{
|
} else {
|
||||||
WriteSignature(unreserved_ptr, unreserved_org);
|
write_signature(unreserved_ptr, unreserved_org);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class BaseAccessor : public IConCommandBaseAccessor
|
class BaseAccessor : public IConCommandBaseAccessor
|
||||||
@ -268,21 +112,9 @@ public:
|
|||||||
|
|
||||||
PLUGIN_EXPOSE(l4dtoolz, g_l4dtoolz);
|
PLUGIN_EXPOSE(l4dtoolz, g_l4dtoolz);
|
||||||
|
|
||||||
void l4dtoolz::get_org_sig(const char* offset, const char* new_sig, char*& org_sig){
|
|
||||||
if(!offset)
|
|
||||||
return;
|
|
||||||
if(org_sig)
|
|
||||||
delete org_sig;
|
|
||||||
org_sig = new char[new_sig[0] + 2];
|
|
||||||
org_sig[0] = new_sig[0];
|
|
||||||
org_sig[1] = new_sig[1];
|
|
||||||
ReadSignature(offset, org_sig);
|
|
||||||
}
|
|
||||||
bool l4dtoolz::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
|
bool l4dtoolz::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
|
||||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, GetCurrentProcessId());
|
|
||||||
#endif
|
|
||||||
PLUGIN_SAVEVARS();
|
PLUGIN_SAVEVARS();
|
||||||
|
|
||||||
GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
|
GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
|
||||||
@ -309,83 +141,78 @@ bool l4dtoolz::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool
|
|||||||
ConCommandBaseMgr::OneTimeInit(&s_BaseAccessor);
|
ConCommandBaseMgr::OneTimeInit(&s_BaseAccessor);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char* base_addr = NULL;
|
struct base_addr_t base_addr;
|
||||||
size_t base_len = 0;
|
base_addr.addr = NULL;
|
||||||
|
base_addr.len = 0;
|
||||||
|
|
||||||
find_base(matchmaking_dll, base_addr, base_len);
|
find_base(matchmaking_dll, &base_addr);
|
||||||
|
|
||||||
#ifdef WIN32
|
if(base_addr.addr == NULL)
|
||||||
if(base_addr == NULL)
|
find_base(matchmaking_dll_alt, &base_addr);
|
||||||
find_base("matchmaking.dll", base_addr, base_len);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(lobby_match_ptr == NULL){
|
if(!lobby_match_ptr) {
|
||||||
lobby_match_ptr = (char*)FindSignature(lobby_match, base_addr, base_len, true);
|
lobby_match_ptr = find_signature(lobby_match, &base_addr, 1);
|
||||||
get_org_sig(lobby_match, (const char*)lobby_match_new, lobby_match_org);
|
get_original_signature(lobby_match, lobby_match_new, &lobby_match_org);
|
||||||
}
|
}
|
||||||
|
|
||||||
find_base(engine_dll, base_addr, base_len);
|
find_base(engine_dll, &base_addr);
|
||||||
if(max_players_friend_lobby == NULL){
|
if(!max_players_friend_lobby) {
|
||||||
max_players_friend_lobby = (char*)FindSignature(friends_lobby, base_addr, base_len);
|
max_players_friend_lobby = find_signature(friends_lobby, &base_addr, 0);
|
||||||
get_org_sig(max_players_friend_lobby, (const char*)friends_lobby_new, friends_lobby_org);
|
get_original_signature(max_players_friend_lobby, friends_lobby_new, &friends_lobby_org);
|
||||||
}
|
}
|
||||||
if(max_players_connect == NULL){
|
if(!max_players_connect) {
|
||||||
max_players_connect = (char*)FindSignature(max_players, base_addr, base_len);
|
max_players_connect = find_signature(max_players, &base_addr, 0);
|
||||||
if(max_players_connect != NULL){
|
get_original_signature(max_players_connect, max_players_new, &max_players_org);
|
||||||
get_org_sig(max_players_connect, (const char*)max_players_new, max_players_org);
|
|
||||||
}
|
}
|
||||||
}
|
if(!lobby_sux_ptr) {
|
||||||
if(lobby_sux_ptr==NULL){
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
lobby_sux_ptr = max_players_connect;
|
lobby_sux_ptr = max_players_connect;
|
||||||
#else
|
#else
|
||||||
lobby_sux_ptr = (char*)FindSignature(lobby_sux, base_addr, base_len);
|
lobby_sux_ptr = find_signature(lobby_sux, &base_addr, 0);
|
||||||
#endif
|
#endif
|
||||||
if(lobby_sux_ptr!=NULL){
|
get_original_signature(lobby_sux_ptr, lobby_sux_new, &lobby_sux_org);
|
||||||
get_org_sig(lobby_sux_ptr, lobby_sux_new, lobby_sux_org);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if(max_players_server_browser == NULL){
|
if(!max_players_server_browser) {
|
||||||
max_players_server_browser = (char*)FindSignature(server_bplayers, base_addr, base_len);
|
max_players_server_browser = find_signature(server_bplayers, &base_addr 0);
|
||||||
get_org_sig(max_players_server_browser, (const char*)server_bplayers_new, server_bplayers_org);
|
get_original_signature(max_players_server_browser, server_bplayers_new, &server_bplayers_org);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(tmp_player == NULL){
|
if(!tmp_player) {
|
||||||
tmp_player = (char*)FindSignature(players, base_addr, base_len);
|
tmp_player = find_signature(players, &base_addr, 0);
|
||||||
if(tmp_player != NULL){
|
if(tmp_player) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
tmp_player2 = (char*)FindSignature(players2, base_addr, base_len);
|
tmp_player2 = find_signature(players2, &base_addr, 0);
|
||||||
#else
|
#else
|
||||||
tmp_player2 = tmp_player;
|
tmp_player2 = tmp_player;
|
||||||
#endif
|
#endif
|
||||||
if(tmp_player2 != NULL){
|
if(tmp_player2) {
|
||||||
get_org_sig(tmp_player, players_new, players_org);
|
get_original_signature(tmp_player, players_new, &players_org);
|
||||||
WriteSignature(tmp_player, players_new);
|
write_signature(tmp_player, players_new);
|
||||||
get_org_sig(tmp_player2, players_new2, players_org2);
|
get_original_signature(tmp_player2, players_new2, &players_org2);
|
||||||
WriteSignature(tmp_player2, players_new2);
|
write_signature(tmp_player2, players_new2);
|
||||||
engine->ServerCommand("maxplayers 32\n");
|
engine->ServerCommand("maxplayers 32\n");
|
||||||
engine->ServerCommand("L4DToolZ ivailosp@abv.bg\n");
|
engine->ServerCommand("L4DToolZ ivailosp@abv.bg\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(unreserved_ptr==NULL){
|
if(!unreserved_ptr) {
|
||||||
unreserved_ptr = (char*)FindSignature(unreserved, base_addr, base_len);
|
unreserved_ptr = find_signature(unreserved, &base_addr, 0);
|
||||||
get_org_sig(unreserved_ptr, unreserved_new, unreserved_org);
|
get_original_signature(unreserved_ptr, unreserved_new, &unreserved_org);
|
||||||
}
|
}
|
||||||
|
|
||||||
find_base(server_dll, base_addr, base_len);
|
find_base(server_dll, &base_addr);
|
||||||
|
|
||||||
if(chuman_limit == NULL){
|
if(!chuman_limit) {
|
||||||
chuman_limit = (char*)FindSignature(human_limit, base_addr, base_len);
|
chuman_limit = find_signature(human_limit, &base_addr, 0);
|
||||||
get_org_sig(chuman_limit, human_limit_new, human_limit_org);
|
get_original_signature(chuman_limit, human_limit_new, &human_limit_org);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
if(max_players_server_browser == NULL){
|
if(!max_players_server_browser) {
|
||||||
max_players_server_browser = (char*)FindSignature(server_bplayers, base_addr, base_len);
|
max_players_server_browser = find_signature(server_bplayers, &base_addr, 0);
|
||||||
get_org_sig(max_players_server_browser, (const char*)server_bplayers_new, server_bplayers_org);
|
get_original_signature(max_players_server_browser, server_bplayers_new, &server_bplayers_org);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -399,38 +226,24 @@ bool l4dtoolz::Unload(char *error, size_t maxlen)
|
|||||||
SH_RELEASE_CALLCLASS(m_EngineCC);
|
SH_RELEASE_CALLCLASS(m_EngineCC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(max_players_friend_lobby != NULL)
|
write_signature(max_players_friend_lobby, friends_lobby_org);
|
||||||
WriteSignature(max_players_friend_lobby, friends_lobby_org);
|
write_signature(max_players_connect, max_players_org);
|
||||||
if(max_players_connect != NULL)
|
write_signature(lobby_sux_ptr, lobby_sux_org);
|
||||||
WriteSignature(max_players_connect, max_players_org);
|
write_signature(max_players_server_browser, server_bplayers_org);
|
||||||
if(lobby_sux_ptr != NULL)
|
write_signature(chuman_limit, human_limit_org);
|
||||||
WriteSignature(lobby_sux_ptr, lobby_sux_org);
|
write_signature(tmp_player, players_org);
|
||||||
if(max_players_server_browser != NULL)
|
write_signature(tmp_player2, players_org2);
|
||||||
WriteSignature(max_players_server_browser, server_bplayers_org);
|
write_signature(unreserved_ptr, unreserved_org);
|
||||||
if(chuman_limit != NULL)
|
write_signature(lobby_match_ptr, lobby_match_org);
|
||||||
WriteSignature(chuman_limit, human_limit_org);
|
|
||||||
|
|
||||||
if(tmp_player != NULL)
|
free(friends_lobby_org);
|
||||||
WriteSignature(tmp_player, players_org);
|
free(max_players_org);
|
||||||
if(tmp_player2 != NULL)
|
free(lobby_sux_org);
|
||||||
WriteSignature(tmp_player2, players_org2);
|
free(server_bplayers_org);
|
||||||
if(unreserved_ptr != NULL)
|
free(human_limit_org);
|
||||||
WriteSignature(unreserved_ptr, unreserved_org);
|
free(players_org);
|
||||||
if(lobby_match_ptr != NULL)
|
free(players_org2);
|
||||||
WriteSignature(lobby_match_ptr, lobby_match_org);
|
free(unreserved_org);
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
CloseHandle(hProcess);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
delete[] friends_lobby_org;
|
|
||||||
delete[] max_players_org;
|
|
||||||
delete[] lobby_sux_org;
|
|
||||||
delete[] server_bplayers_org;
|
|
||||||
delete[] human_limit_org;
|
|
||||||
delete[] players_org;
|
|
||||||
delete[] players_org2;
|
|
||||||
delete[] unreserved_org;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include <ISmmPlugin.h>
|
#include <ISmmPlugin.h>
|
||||||
|
|
||||||
|
|
||||||
class l4dtoolz : public ISmmPlugin, public IMetamodListener
|
class l4dtoolz : public ISmmPlugin, public IMetamodListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -29,32 +28,20 @@ public:
|
|||||||
static void OnChangeUnreserved ( IConVar *var, const char *pOldValue, float flOldValue );
|
static void OnChangeUnreserved ( IConVar *var, const char *pOldValue, float flOldValue );
|
||||||
static void OnChangeIvailosp ( IConVar *var, const char *pOldValue, float flOldValue );
|
static void OnChangeIvailosp ( IConVar *var, const char *pOldValue, float flOldValue );
|
||||||
|
|
||||||
static char* max_players_friend_lobby;
|
static void* max_players_friend_lobby;
|
||||||
static char* max_players_connect;
|
static void* max_players_connect;
|
||||||
static char* max_players_server_browser;
|
static void* max_players_server_browser;
|
||||||
static char* lobby_sux_ptr;
|
static void* lobby_sux_ptr;
|
||||||
static char* chuman_limit;
|
static void* chuman_limit;
|
||||||
static char* tmp_player;
|
static void* tmp_player;
|
||||||
static char* tmp_player2;
|
static void* tmp_player2;
|
||||||
static char* unreserved_ptr;
|
static void* unreserved_ptr;
|
||||||
static char* lobby_match_ptr;
|
static void* lobby_match_ptr;
|
||||||
|
|
||||||
public:
|
|
||||||
static bool find_base(const char* name, char*& base_addr, size_t& base_len);
|
|
||||||
static void* FindSignature(const char* mask, const char* base_addr, size_t base_len, bool pure_sign = false);
|
|
||||||
static void get_org_sig(const char* offset, const char* new_sig, char*& org_sig);
|
|
||||||
static void WriteSignature(char* addr, const char* signature);
|
|
||||||
static void ReadSignature(const char* addr, char* signature);
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#if !defined METAMOD_PLAPI_VERSION
|
#if !defined METAMOD_PLAPI_VERSION
|
||||||
SourceHook::CallClass<IVEngineServer> *m_EngineCC;
|
SourceHook::CallClass<IVEngineServer> *m_EngineCC;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
private:
|
|
||||||
static HANDLE hProcess;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
216
signature.cpp
Normal file
216
signature.cpp
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "signature.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#include <TlHelp32.h>
|
||||||
|
#else
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <link.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SIGN_HEADER_LEN 2
|
||||||
|
#define SIGN_LEN_BYTE 0
|
||||||
|
#define SIGN_OFFSET_BYTE 1
|
||||||
|
|
||||||
|
|
||||||
|
static int lock_region(const void *addr, unsigned int sign_len, int lock)
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
|
unsigned int all_adr;
|
||||||
|
unsigned int all_size;
|
||||||
|
unsigned int p_size;
|
||||||
|
unsigned int u_addr;
|
||||||
|
|
||||||
|
p_size = sysconf(_SC_PAGESIZE);
|
||||||
|
u_addr = (unsigned int)addr;
|
||||||
|
|
||||||
|
all_adr = (u_addr + sign_len) & ~(p_size-1);
|
||||||
|
all_size = u_addr - all_adr + sign_len;
|
||||||
|
|
||||||
|
if(lock)
|
||||||
|
mlock((void *)all_adr, all_size);
|
||||||
|
else
|
||||||
|
munlock((void *)all_adr, all_size);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *find_signature(const char* mask, struct base_addr_t *base_addr, int pure)
|
||||||
|
{
|
||||||
|
char *pBasePtr = (char *)base_addr->addr;
|
||||||
|
char *pEndPtr = pBasePtr+base_addr->len-(int)mask[SIGN_LEN_BYTE];
|
||||||
|
int i;
|
||||||
|
char* tmp;
|
||||||
|
if(base_addr == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
lock_region(pBasePtr, pEndPtr-pBasePtr, 1);
|
||||||
|
|
||||||
|
while(pBasePtr < pEndPtr)
|
||||||
|
{
|
||||||
|
tmp = pBasePtr;
|
||||||
|
|
||||||
|
for(i = 1; i <= mask[SIGN_LEN_BYTE]; ++i) {
|
||||||
|
if(pure && mask[i] == '\xC3'){
|
||||||
|
tmp++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(mask[i] != *tmp ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tmp++;
|
||||||
|
}
|
||||||
|
if(i-1 == mask[0]) {
|
||||||
|
lock_region(pBasePtr, pEndPtr-pBasePtr, 0);
|
||||||
|
return pBasePtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pBasePtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock_region(pBasePtr, pEndPtr-pBasePtr, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
struct v_data{
|
||||||
|
const char *fname;
|
||||||
|
void *baddr;
|
||||||
|
unsigned int blen;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int callback(struct dl_phdr_info *info, size_t size, void *data)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char* filename;
|
||||||
|
|
||||||
|
if (!info->dlpi_name || !info->dlpi_name[0])
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
filename = ((struct v_data *)data)->fname;
|
||||||
|
|
||||||
|
if(strstr(info->dlpi_name, filename)) {
|
||||||
|
if(strstr( info->dlpi_name, "metamod") == NULL) {
|
||||||
|
((struct v_data *)data)->baddr = (void*)info->dlpi_addr;
|
||||||
|
((struct v_data *)data)->blen = 0;
|
||||||
|
for(i = 0; i < info->dlpi_phnum; ++i) {
|
||||||
|
((struct v_data *)data)->blen+=info->dlpi_phdr[i].p_filesz;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int find_base(const char* name, struct base_addr_t *base_addr)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
|
||||||
|
MODULEENTRY32 modent;
|
||||||
|
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
|
||||||
|
if(hModuleSnap == INVALID_HANDLE_VALUE) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
modent.dwSize = sizeof(MODULEENTRY32);
|
||||||
|
|
||||||
|
if(!Module32Next(hModuleSnap, &modent)){
|
||||||
|
CloseHandle(hModuleSnap);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
if(strstr( modent.szExePath, name)) {
|
||||||
|
if(strstr( modent.szExePath, "metamod"))
|
||||||
|
continue;
|
||||||
|
base_addr->addr = modent.modBaseAddr;
|
||||||
|
base_addr->len = modent.modBaseSize;
|
||||||
|
CloseHandle(hModuleSnap);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} while(Module32Next(hModuleSnap, &modent));
|
||||||
|
CloseHandle(hModuleSnap);
|
||||||
|
#else
|
||||||
|
struct v_data vdata;
|
||||||
|
vdata.fname = name;
|
||||||
|
if(dl_iterate_phdr(callback, &vdata)){
|
||||||
|
base_addr->addr = vdata.baddr;
|
||||||
|
base_addr->len = vdata.blen;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
base_addr->addr = NULL;
|
||||||
|
base_addr->len = 0;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int write_signature(const void* addr, const void* signature)
|
||||||
|
{
|
||||||
|
if(!addr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
unsigned int u_addr_sign;
|
||||||
|
unsigned int sign_len;
|
||||||
|
unsigned int sign_off;
|
||||||
|
unsigned int u_addr;
|
||||||
|
|
||||||
|
sign_len = ((unsigned char *)signature)[SIGN_LEN_BYTE];
|
||||||
|
sign_off = ((unsigned char *)signature)[SIGN_OFFSET_BYTE];
|
||||||
|
u_addr = (unsigned int)addr;
|
||||||
|
u_addr_sign = (unsigned int)signature;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
HANDLE h_process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
|
||||||
|
WriteProcessMemory(hProcess, (void *)(u_addr+sign_off), (void *)(u_addr_sign+SIGN_HEADER_LEN), sign_len, NULL);
|
||||||
|
CloseHandle(h_process);
|
||||||
|
#else
|
||||||
|
|
||||||
|
lock_region(addr, sign_len, 1);
|
||||||
|
memcpy((void *)(u_addr+sign_off), (void *)(u_addr_sign+SIGN_HEADER_LEN), sign_len);
|
||||||
|
lock_region(addr, sign_len, 0);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_signature(const void *addr, void *signature)
|
||||||
|
{
|
||||||
|
unsigned int u_addr_sign;
|
||||||
|
unsigned int sign_len;
|
||||||
|
unsigned int u_addr;
|
||||||
|
|
||||||
|
sign_len = ((unsigned char *)signature)[SIGN_LEN_BYTE];
|
||||||
|
u_addr = (unsigned int)addr;
|
||||||
|
u_addr_sign = (unsigned int)signature;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
HANDLE h_process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
|
||||||
|
ReadProcessMemory(h_process, (void *)(u_addr+sign_len), (void *)(u_addr_sign+SIGN_HEADER_LEN), sign_len, NULL);
|
||||||
|
CloseHandle(h_process);
|
||||||
|
#else
|
||||||
|
lock_region(addr, sign_len, 1);
|
||||||
|
memcpy((void *)(u_addr_sign+SIGN_HEADER_LEN), (void *)(u_addr+sign_len), sign_len);
|
||||||
|
lock_region(addr, sign_len, 0);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_original_signature(const void *offset, const void *new_sig, void **org_sig)
|
||||||
|
{
|
||||||
|
unsigned int sign_len;
|
||||||
|
|
||||||
|
if(!offset)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
sign_len = ((unsigned char *)new_sig)[SIGN_LEN_BYTE];
|
||||||
|
*org_sig = malloc(sign_len + SIGN_HEADER_LEN);
|
||||||
|
memcpy(org_sig, new_sig, SIGN_HEADER_LEN);
|
||||||
|
return read_signature(offset, org_sig);
|
||||||
|
}
|
||||||
|
|
15
signature.h
Normal file
15
signature.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef _INCLUDE_SIGNATURE_
|
||||||
|
#define _INCLUDE_SIGNATURE_
|
||||||
|
|
||||||
|
struct base_addr_t{
|
||||||
|
void *addr;
|
||||||
|
unsigned int len;
|
||||||
|
};
|
||||||
|
|
||||||
|
void *find_signature(const char* mask, struct base_addr_t* base_addr, int pure);
|
||||||
|
int find_base(const char* name, struct base_addr_t * base_addr);
|
||||||
|
int write_signature(const void* addr, const void* signature);
|
||||||
|
int read_signature(const void *addr, void *signature);
|
||||||
|
int get_original_signature(const void *offset, const void *new_sig, void** org_sig);
|
||||||
|
|
||||||
|
#endif //_INCLUDE_SIGNATURE_
|
Reference in New Issue
Block a user