diff --git a/Makefile b/Makefile index 144a4ad..51f72a8 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ MMSOURCE19 = .. ##################################### PROJECT = l4dtoolz_mm -OBJECTS = l4dtoolz_mm.cpp +OBJECTS = l4dtoolz_mm.cpp signature.cpp ############################################## ### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ### diff --git a/game_signature.h b/game_signature.h new file mode 100644 index 0000000..b08d702 --- /dev/null +++ b/game_signature.h @@ -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_ diff --git a/l4d1_signature_linux.h b/l4d1_signature_linux.h index 54dec25..2c81898 100644 --- a/l4d1_signature_linux.h +++ b/l4d1_signature_linux.h @@ -1,6 +1,10 @@ +#ifndef _INCLUDE_L4D1_SIGNATURE_LINUX_ +#define _INCLUDE_L4D1_SIGNATURE_LINUX_ + const char* server_dll = "server.so"; const char* engine_dll = "engine.so"; const char* matchmaking_dll = "matchmaking_ds.so"; +const char* matchmaking_dll_alt = "matchmaking.so"; //CBaseServer::GetMaxHumanPlayers(void)const //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"; unsigned char lobby_match_new[] = {0x01, 0x04, 0xC3}; char* lobby_match_org = NULL; + +#endif //_INCLUDE_L4D1_SIGNATURE_LINUX_ + diff --git a/l4d1_signature_win32.h b/l4d1_signature_win32.h index 6b62b72..b9d9c52 100644 --- a/l4d1_signature_win32.h +++ b/l4d1_signature_win32.h @@ -1,6 +1,10 @@ +#ifndef _INCLUDE_L4D1_SIGNATURE_WIN32_ +#define _INCLUDE_L4D1_SIGNATURE_WIN32_ + const char* server_dll = "server.dll"; const char* engine_dll = "engine.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"; 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}; char* lobby_match_org = NULL; +#endif //_INCLUDE_L4D1_SIGNATURE_WIN32_ + diff --git a/l4d2_signature_linux.h b/l4d2_signature_linux.h index b20389c..db56f72 100644 --- a/l4d2_signature_linux.h +++ b/l4d2_signature_linux.h @@ -1,39 +1,45 @@ +#ifndef _INCLUDE_L4D2_SIGNATURE_LINUX_ +#define _INCLUDE_L4D2_SIGNATURE_LINUX_ + const char* server_dll = "server.so"; const char* engine_dll = "engine.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"; 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_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"; 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"; 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_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_new = "\x02\x07\x90\x90"; -char* players_org = NULL; +void *players_org = NULL; 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"; -char* unreserved_org = NULL; +void *unreserved_org = NULL; const char* lobby_match = "\x0A\x55\x89\xE5\xB8\x08\x00\x00\x00\x5D\xC3"; unsigned char lobby_match_new[] = {0x01, 0x04, 0xC3}; -char* lobby_match_org = NULL; +void *lobby_match_org = NULL; + +#endif //_INCLUDE_L4D2_SIGNATURE_LINUX_ diff --git a/l4d2_signature_win32.h b/l4d2_signature_win32.h index 6b62b72..d560bed 100644 --- a/l4d2_signature_win32.h +++ b/l4d2_signature_win32.h @@ -1,6 +1,10 @@ +#ifndef _INCLUDE_L4D2_SIGNATURE_WIN32_ +#define _INCLUDE_L4D2_SIGNATURE_WIN32_ + const char* server_dll = "server.dll"; const char* engine_dll = "engine.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"; 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}; char* lobby_match_org = NULL; +#endif //_INCLUDE_L4D2_SIGNATURE_WIN32_ + diff --git a/l4dtoolz_mm.cpp b/l4dtoolz_mm.cpp index a4d3989..4309c57 100644 --- a/l4dtoolz_mm.cpp +++ b/l4dtoolz_mm.cpp @@ -1,260 +1,104 @@ -#include #include "l4dtoolz_mm.h" - -#ifdef WIN32 -#include -#include -#else -#include -#include -#include -#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 +#include "signature.h" +#include "game_signature.h" l4dtoolz g_l4dtoolz; IVEngineServer* engine = NULL; IServerPluginCallbacks* vsp_callbacks = NULL; ICvar* icvar = NULL; -#ifdef WIN32 -HANDLE l4dtoolz::hProcess; -#endif - -char* l4dtoolz::max_players_friend_lobby = NULL; -char* l4dtoolz::max_players_connect = NULL; -char* l4dtoolz::max_players_server_browser = NULL; -char* l4dtoolz::lobby_sux_ptr = NULL; -char* l4dtoolz::chuman_limit = NULL; -char* l4dtoolz::tmp_player = NULL; -char* l4dtoolz::tmp_player2 = NULL; -char* l4dtoolz::unreserved_ptr = NULL; -char* l4dtoolz::lobby_match_ptr = NULL; +void* l4dtoolz::max_players_friend_lobby = NULL; +void* l4dtoolz::max_players_connect = NULL; +void* l4dtoolz::max_players_server_browser = NULL; +void* l4dtoolz::lobby_sux_ptr = NULL; +void* l4dtoolz::chuman_limit = NULL; +void* l4dtoolz::tmp_player = NULL; +void* l4dtoolz::tmp_player2 = NULL; +void* l4dtoolz::unreserved_ptr = NULL; +void* l4dtoolz::lobby_match_ptr = NULL; 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 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); -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 ) { - 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"); return; } - if(((ConVar*)var)->GetInt() >= 0){ - max_players_new[4] = friends_lobby_new[3] = server_bplayers_new[3] = ((ConVar*)var)->GetInt(); - if(lobby_match_ptr != NULL){ - lobby_match_new[2] = ((ConVar*)var)->GetInt(); - WriteSignature(lobby_match_ptr, (const char*)lobby_match_new); - }else{ - Msg("sv_maxplayers MS init error\n"); - } - WriteSignature(max_players_friend_lobby, (const char*)friends_lobby_new); - WriteSignature(max_players_connect, (const char*)max_players_new); - WriteSignature(lobby_sux_ptr, lobby_sux_new); - WriteSignature(max_players_server_browser, (const char*)server_bplayers_new); - }else{ - WriteSignature(max_players_friend_lobby, friends_lobby_org); - WriteSignature(max_players_connect, max_players_org); - WriteSignature(lobby_sux_ptr, lobby_sux_org); - WriteSignature(max_players_server_browser, server_bplayers_org); + if(new_value != old_value) { + if(new_value) { + max_players_new[4] = friends_lobby_new[3] = server_bplayers_new[3] = new_value; + if(lobby_match_ptr != NULL) { + lobby_match_new[2] = new_value; + write_signature(lobby_match_ptr, lobby_match_new); + } else { + Msg("sv_maxplayers MS init error\n"); + } + write_signature(max_players_friend_lobby, friends_lobby_new); + write_signature(max_players_connect, max_players_new); + write_signature(lobby_sux_ptr, lobby_sux_new); + write_signature(max_players_server_browser, server_bplayers_new); + } else { + write_signature(max_players_friend_lobby, friends_lobby_org); + write_signature(max_players_connect, max_players_org); + write_signature(lobby_sux_ptr, lobby_sux_org); + write_signature(max_players_server_browser, server_bplayers_org); - if(lobby_match_ptr != NULL) - WriteSignature(lobby_match_ptr, lobby_match_org); + if(lobby_match_ptr != NULL) + write_signature(lobby_match_ptr, lobby_match_org); + } } } + 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"); return; } - if( ((ConVar*)var)->GetInt() == 1){ - WriteSignature(chuman_limit, human_limit_new); - }else{ - WriteSignature(chuman_limit, human_limit_org); + if(new_value != old_value) { + if(new_value == 1) { + write_signature(chuman_limit, human_limit_new); + }else{ + write_signature(chuman_limit, human_limit_org); + } } } 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"); return; } - WriteSignature(tmp_player, players_org); - WriteSignature(tmp_player2, players_org2); + write_signature(tmp_player, players_org); + write_signature(tmp_player2, players_org2); } + 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"); return; } - if( ((ConVar*)var)->GetInt() == 1){ - WriteSignature(unreserved_ptr, unreserved_new); - engine->ServerCommand("sv_allow_lobby_connect_only 0\n"); - }else{ - WriteSignature(unreserved_ptr, unreserved_org); + if(new_value != old_value) { + if(new_value == 1) { + write_signature(unreserved_ptr, unreserved_new); + engine->ServerCommand("sv_allow_lobby_connect_only 0\n"); + } else { + write_signature(unreserved_ptr, unreserved_org); + } } - } class BaseAccessor : public IConCommandBaseAccessor @@ -268,21 +112,9 @@ public: 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) { -#ifdef WIN32 - hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, GetCurrentProcessId()); -#endif + PLUGIN_SAVEVARS(); 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); #endif - char* base_addr = NULL; - size_t base_len = 0; + struct base_addr_t base_addr; + 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 == NULL) - find_base("matchmaking.dll", base_addr, base_len); -#endif + if(base_addr.addr == NULL) + find_base(matchmaking_dll_alt, &base_addr); - if(lobby_match_ptr == NULL){ - lobby_match_ptr = (char*)FindSignature(lobby_match, base_addr, base_len, true); - get_org_sig(lobby_match, (const char*)lobby_match_new, lobby_match_org); + if(!lobby_match_ptr) { + lobby_match_ptr = find_signature(lobby_match, &base_addr, 1); + get_original_signature(lobby_match, lobby_match_new, &lobby_match_org); } - find_base(engine_dll, base_addr, base_len); - if(max_players_friend_lobby == NULL){ - max_players_friend_lobby = (char*)FindSignature(friends_lobby, base_addr, base_len); - get_org_sig(max_players_friend_lobby, (const char*)friends_lobby_new, friends_lobby_org); + find_base(engine_dll, &base_addr); + if(!max_players_friend_lobby) { + max_players_friend_lobby = find_signature(friends_lobby, &base_addr, 0); + get_original_signature(max_players_friend_lobby, friends_lobby_new, &friends_lobby_org); } - if(max_players_connect == NULL){ - max_players_connect = (char*)FindSignature(max_players, base_addr, base_len); - if(max_players_connect != NULL){ - get_org_sig(max_players_connect, (const char*)max_players_new, max_players_org); - } + if(!max_players_connect) { + max_players_connect = find_signature(max_players, &base_addr, 0); + get_original_signature(max_players_connect, max_players_new, &max_players_org); } - if(lobby_sux_ptr==NULL){ + if(!lobby_sux_ptr) { #ifdef WIN32 lobby_sux_ptr = max_players_connect; #else - lobby_sux_ptr = (char*)FindSignature(lobby_sux, base_addr, base_len); + lobby_sux_ptr = find_signature(lobby_sux, &base_addr, 0); #endif - if(lobby_sux_ptr!=NULL){ - get_org_sig(lobby_sux_ptr, lobby_sux_new, lobby_sux_org); - } + get_original_signature(lobby_sux_ptr, lobby_sux_new, &lobby_sux_org); } #ifdef WIN32 - if(max_players_server_browser == NULL){ - max_players_server_browser = (char*)FindSignature(server_bplayers, base_addr, base_len); - get_org_sig(max_players_server_browser, (const char*)server_bplayers_new, server_bplayers_org); + if(!max_players_server_browser) { + max_players_server_browser = find_signature(server_bplayers, &base_addr 0); + get_original_signature(max_players_server_browser, server_bplayers_new, &server_bplayers_org); } #endif - if(tmp_player == NULL){ - tmp_player = (char*)FindSignature(players, base_addr, base_len); - if(tmp_player != NULL){ + if(!tmp_player) { + tmp_player = find_signature(players, &base_addr, 0); + if(tmp_player) { #ifdef WIN32 - tmp_player2 = (char*)FindSignature(players2, base_addr, base_len); + tmp_player2 = find_signature(players2, &base_addr, 0); #else tmp_player2 = tmp_player; #endif - if(tmp_player2 != NULL){ - get_org_sig(tmp_player, players_new, players_org); - WriteSignature(tmp_player, players_new); - get_org_sig(tmp_player2, players_new2, players_org2); - WriteSignature(tmp_player2, players_new2); + if(tmp_player2) { + get_original_signature(tmp_player, players_new, &players_org); + write_signature(tmp_player, players_new); + get_original_signature(tmp_player2, players_new2, &players_org2); + write_signature(tmp_player2, players_new2); engine->ServerCommand("maxplayers 32\n"); engine->ServerCommand("L4DToolZ ivailosp@abv.bg\n"); } } } - if(unreserved_ptr==NULL){ - unreserved_ptr = (char*)FindSignature(unreserved, base_addr, base_len); - get_org_sig(unreserved_ptr, unreserved_new, unreserved_org); + if(!unreserved_ptr) { + unreserved_ptr = find_signature(unreserved, &base_addr, 0); + 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){ - chuman_limit = (char*)FindSignature(human_limit, base_addr, base_len); - get_org_sig(chuman_limit, human_limit_new, human_limit_org); + if(!chuman_limit) { + chuman_limit = find_signature(human_limit, &base_addr, 0); + get_original_signature(chuman_limit, human_limit_new, &human_limit_org); } #ifndef WIN32 - if(max_players_server_browser == NULL){ - max_players_server_browser = (char*)FindSignature(server_bplayers, base_addr, base_len); - get_org_sig(max_players_server_browser, (const char*)server_bplayers_new, server_bplayers_org); + if(!max_players_server_browser) { + max_players_server_browser = find_signature(server_bplayers, &base_addr, 0); + get_original_signature(max_players_server_browser, server_bplayers_new, &server_bplayers_org); } #endif @@ -399,38 +226,24 @@ bool l4dtoolz::Unload(char *error, size_t maxlen) SH_RELEASE_CALLCLASS(m_EngineCC); #endif - if(max_players_friend_lobby != NULL) - WriteSignature(max_players_friend_lobby, friends_lobby_org); - if(max_players_connect != NULL) - WriteSignature(max_players_connect, max_players_org); - if(lobby_sux_ptr != NULL) - WriteSignature(lobby_sux_ptr, lobby_sux_org); - if(max_players_server_browser != NULL) - WriteSignature(max_players_server_browser, server_bplayers_org); - if(chuman_limit != NULL) - WriteSignature(chuman_limit, human_limit_org); + write_signature(max_players_friend_lobby, friends_lobby_org); + write_signature(max_players_connect, max_players_org); + write_signature(lobby_sux_ptr, lobby_sux_org); + write_signature(max_players_server_browser, server_bplayers_org); + write_signature(chuman_limit, human_limit_org); + write_signature(tmp_player, players_org); + write_signature(tmp_player2, players_org2); + write_signature(unreserved_ptr, unreserved_org); + write_signature(lobby_match_ptr, lobby_match_org); - if(tmp_player != NULL) - WriteSignature(tmp_player, players_org); - if(tmp_player2 != NULL) - WriteSignature(tmp_player2, players_org2); - if(unreserved_ptr != NULL) - WriteSignature(unreserved_ptr, unreserved_org); - if(lobby_match_ptr != NULL) - WriteSignature(lobby_match_ptr, lobby_match_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; + free(friends_lobby_org); + free(max_players_org); + free(lobby_sux_org); + free(server_bplayers_org); + free(human_limit_org); + free(players_org); + free(players_org2); + free(unreserved_org); return true; } diff --git a/l4dtoolz_mm.h b/l4dtoolz_mm.h index 6a60d4a..d41f578 100644 --- a/l4dtoolz_mm.h +++ b/l4dtoolz_mm.h @@ -3,7 +3,6 @@ #include - class l4dtoolz : public ISmmPlugin, public IMetamodListener { public: @@ -29,32 +28,20 @@ public: static void OnChangeUnreserved ( IConVar *var, const char *pOldValue, float flOldValue ); static void OnChangeIvailosp ( IConVar *var, const char *pOldValue, float flOldValue ); - static char* max_players_friend_lobby; - static char* max_players_connect; - static char* max_players_server_browser; - static char* lobby_sux_ptr; - static char* chuman_limit; - static char* tmp_player; - static char* tmp_player2; - static char* unreserved_ptr; - static char* 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); + static void* max_players_friend_lobby; + static void* max_players_connect; + static void* max_players_server_browser; + static void* lobby_sux_ptr; + static void* chuman_limit; + static void* tmp_player; + static void* tmp_player2; + static void* unreserved_ptr; + static void* lobby_match_ptr; private: #if !defined METAMOD_PLAPI_VERSION SourceHook::CallClass *m_EngineCC; #endif - -#ifdef WIN32 -private: - static HANDLE hProcess; -#endif }; diff --git a/signature.cpp b/signature.cpp new file mode 100644 index 0000000..4966a11 --- /dev/null +++ b/signature.cpp @@ -0,0 +1,216 @@ +#include +#include +#include +#include "signature.h" + +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#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); +} + diff --git a/signature.h b/signature.h new file mode 100644 index 0000000..9748e38 --- /dev/null +++ b/signature.h @@ -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_