diff options
author | Davide Beatrici <git@davidebeatrici.dev> | 2020-10-28 01:21:44 +0300 |
---|---|---|
committer | Davide Beatrici <git@davidebeatrici.dev> | 2020-10-28 21:27:01 +0300 |
commit | 13cbf728775cee0b6c963d642193192dd57f24e1 (patch) | |
tree | 9411a64df0e96dcee8ec2f91629860a104a519cc /plugins | |
parent | 0968efa7b4011a099c40449f894d0886becbc334 (diff) |
REFAC(plugins): Use new C++ classes in Source Engine plugin
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/se/CMakeLists.txt | 13 | ||||
-rw-r--r-- | plugins/se/client.h | 34 | ||||
-rw-r--r-- | plugins/se/common.h | 20 | ||||
-rw-r--r-- | plugins/se/engine.h | 32 | ||||
-rw-r--r-- | plugins/se/se.cpp | 86 |
5 files changed, 108 insertions, 77 deletions
diff --git a/plugins/se/CMakeLists.txt b/plugins/se/CMakeLists.txt index 348abcaa7..aaf63ac7d 100644 --- a/plugins/se/CMakeLists.txt +++ b/plugins/se/CMakeLists.txt @@ -3,4 +3,15 @@ # that can be found in the LICENSE file at the root of the # Mumble source tree or at <https://www.mumble.info/LICENSE>. -add_library(se SHARED "se.cpp") +add_library(se SHARED + "se.cpp" + + "../Process.cpp" + "../ProcessWindows.cpp" +) + +if(WIN32) + target_sources(se PRIVATE "../HostWindows.cpp") +else() + target_sources(se PRIVATE "../HostLinux.cpp" "../ProcessLinux.cpp") +endif() diff --git a/plugins/se/client.h b/plugins/se/client.h index 583e971f7..c470dd859 100644 --- a/plugins/se/client.h +++ b/plugins/se/client.h @@ -42,20 +42,20 @@ struct EntityCacheInfo { static int32_t getDataVar(const std::string &name, procptr_t predMap) { while (predMap) { DataMap dataMap; - if (!peekProc(predMap, dataMap)) { + if (!proc->peek(predMap, dataMap)) { return 0; } // The structure is 4 bytes bigger on Linux. const size_t realStructSize = isWin32 ? sizeof(TypeDescription) : sizeof(TypeDescription) + 4; - const auto descs = peekProcVector< TypeDescription >(dataMap.dataDesc, dataMap.dataNumFields, realStructSize); + const auto descs = proc->peekVector< TypeDescription >(dataMap.dataDesc, dataMap.dataNumFields, realStructSize); for (const auto &desc : descs) { if (!desc.fieldName) { continue; } - const auto fieldName = peekProcString(desc.fieldName); + const auto fieldName = proc->peekString(desc.fieldName); if (fieldName == name) { return desc.fieldOffset; @@ -80,9 +80,9 @@ static int32_t getDataVarFromEntity(const std::string &name, const procptr_t ent // Brute-force virtual function index. for (uint8_t i = 20; i > 16; --i) { - GetPredDescMap = getVirtualFunction(entity, i); + GetPredDescMap = proc->virtualFunction(entity, i); - if (peekProc< uint8_t >(GetPredDescMap + (isWin32 ? 0 : 1)) == 0xB8) { + if (proc->peek< uint8_t >(GetPredDescMap + (isWin32 ? 0 : 1)) == 0xB8) { break; } } @@ -97,11 +97,11 @@ static int32_t getDataVarFromEntity(const std::string &name, const procptr_t ent // 89 E5 mov ebp, esp // 5D pop ebp // C3 retn - return getDataVar(name, peekProc< uint32_t >(GetPredDescMap + (isWin32 ? 1 : 2))); + return getDataVar(name, proc->peek< uint32_t >(GetPredDescMap + (isWin32 ? 1 : 2))); } static procptr_t getLocalPlayer(const procptr_t localClient, procptr_t clientEntityList, const procptr_t engineClient) { - const auto GetLocalPlayer = getVirtualFunction(engineClient, 12); + const auto GetLocalPlayer = proc->virtualFunction(engineClient, 12); // Windows: // 6A FF push 0FFFFFFFFh @@ -121,10 +121,10 @@ static procptr_t getLocalPlayer(const procptr_t localClient, procptr_t clientEnt // C9 leave // 83 C0 01 add eax, 1 // C3 retn - const auto localPlayerIndexOffset = peekProc< int32_t >(GetLocalPlayer + (isWin32 ? 9 : 14)); - const auto localPlayerIndex = peekProc< uint32_t >(localClient + localPlayerIndexOffset) + 1; + const auto localPlayerIndexOffset = proc->peek< int32_t >(GetLocalPlayer + (isWin32 ? 9 : 14)); + const auto localPlayerIndex = proc->peek< uint32_t >(localClient + localPlayerIndexOffset) + 1; - auto GetClientNetworkable = getVirtualFunction(clientEntityList, 0); + auto GetClientNetworkable = proc->virtualFunction(clientEntityList, 0); // Left 4 Dead: // 8B 44 24 04 mov eax, [esp+arg_0] @@ -143,8 +143,8 @@ static procptr_t getLocalPlayer(const procptr_t localClient, procptr_t clientEnt // 81 6C 24 04 ?? ?? ?? ?? sub [esp+arg_0], ???????? // EB ?? jmp short GetClientNetworkable if (!isWin32) { - clientEntityList -= peekProc< int32_t >(GetClientNetworkable + 4); - GetClientNetworkable = GetClientNetworkable + 10 + peekProc< int8_t >(GetClientNetworkable + 9); + clientEntityList -= proc->peek< int32_t >(GetClientNetworkable + 4); + GetClientNetworkable = GetClientNetworkable + 10 + proc->peek< int8_t >(GetClientNetworkable + 9); // 55 push ebp // 89 E5 mov ebp, esp @@ -158,17 +158,17 @@ static procptr_t getLocalPlayer(const procptr_t localClient, procptr_t clientEnt procptr_t entityCacheInfo; if (isWin32) { - if (peekProc< uint8_t >(GetClientNetworkable + 6) == 0xC1) { + if (proc->peek< uint8_t >(GetClientNetworkable + 6) == 0xC1) { // Left 4 Dead - entityCacheInfo = clientEntityList + peekProc< int8_t >(GetClientNetworkable + 7); + entityCacheInfo = clientEntityList + proc->peek< int8_t >(GetClientNetworkable + 7); } else { - entityCacheInfo = clientEntityList + peekProc< int8_t >(GetClientNetworkable + 9); + entityCacheInfo = clientEntityList + proc->peek< int8_t >(GetClientNetworkable + 9); } } else { - entityCacheInfo = clientEntityList + peekProc< int32_t >(GetClientNetworkable + 13); + entityCacheInfo = clientEntityList + proc->peek< int32_t >(GetClientNetworkable + 13); } - const auto entity = peekProc< EntityCacheInfo >(entityCacheInfo + sizeof(EntityCacheInfo) * localPlayerIndex); + const auto entity = proc->peek< EntityCacheInfo >(entityCacheInfo + sizeof(EntityCacheInfo) * localPlayerIndex); // We subtract 8 bytes in order to cast from IClientNetworkable to IClientEntity. return entity.networkable ? (entity.networkable - 8) : 0; diff --git a/plugins/se/common.h b/plugins/se/common.h index d0e020938..0ae2e1785 100644 --- a/plugins/se/common.h +++ b/plugins/se/common.h @@ -18,16 +18,16 @@ static Interfaces getInterfaces(const procptr_t module) { Interfaces interfaces; // s_pInterfaceRegs is exported on Linux - auto s_pInterfaceRegs = getExportedSymbol("s_pInterfaceRegs", module); + auto s_pInterfaceRegs = proc->exportedSymbol("s_pInterfaceRegs", module); if (!s_pInterfaceRegs) { - const auto CreateInterface = getExportedSymbol("CreateInterface", module); + const auto CreateInterface = proc->exportedSymbol("CreateInterface", module); if (CreateInterface == 0) { return interfaces; } bool jmpOnly; - if (peekProc< uint8_t >(CreateInterface) == 0xE9) { + if (proc->peek< uint8_t >(CreateInterface) == 0xE9) { // Left 4 Dead: // E9 ?? ?? ?? ?? jmp CreateInterface_0 jmpOnly = true; @@ -40,7 +40,7 @@ static Interfaces getInterfaces(const procptr_t module) { jmpOnly = false; } - const auto jmpTarget = peekProc< int32_t >(CreateInterface + (jmpOnly ? 1 : 5)); + const auto jmpTarget = proc->peek< int32_t >(CreateInterface + (jmpOnly ? 1 : 5)); const auto jmpInstructionEnd = CreateInterface + (jmpOnly ? 5 : 9); const auto CreateInterfaceInternal = jmpInstructionEnd + jmpTarget; @@ -55,21 +55,21 @@ static Interfaces getInterfaces(const procptr_t module) { // 8B EC mov ebp, esp // 56 push esi // 8B 35 ?? ?? ?? ?? mov esi, s_pInterfaceRegs - if (peekProc< uint16_t >(CreateInterfaceInternal + (jmpOnly ? 1 : 4)) != 0x358B) { + if (proc->peek< uint16_t >(CreateInterfaceInternal + (jmpOnly ? 1 : 4)) != 0x358B) { return interfaces; } - s_pInterfaceRegs = peekProc< uint32_t >(CreateInterfaceInternal + (jmpOnly ? 3 : 6)); + s_pInterfaceRegs = proc->peek< uint32_t >(CreateInterfaceInternal + (jmpOnly ? 3 : 6)); } - auto iface = peekProc< InterfaceReg >(peekProcPtr(s_pInterfaceRegs)); + auto iface = proc->peek< InterfaceReg >(proc->peekPtr(s_pInterfaceRegs)); do { - const auto name = peekProcString(iface.name); - const auto address = peekProc< uint32_t >(iface.createFunction + (isWin32 ? 1 : 2)); + const auto name = proc->peekString(iface.name); + const auto address = proc->peek< uint32_t >(iface.createFunction + (isWin32 ? 1 : 2)); interfaces.insert(Interfaces::value_type(name, address)); - } while (iface.next && peekProc(iface.next, iface)); + } while (iface.next && proc->peek(iface.next, iface)); return interfaces; } diff --git a/plugins/se/engine.h b/plugins/se/engine.h index 77f9a90fd..2a0cf35cc 100644 --- a/plugins/se/engine.h +++ b/plugins/se/engine.h @@ -17,7 +17,7 @@ static procptr_t getLocalClient(const procptr_t engineClient) { // GetLocalClient() gets the client from an array at the index passed to the function. // There are multiple clients because of the split screen feature. - const auto GetNetChannelInfo = getVirtualFunction(engineClient, 74); + const auto GetNetChannelInfo = proc->virtualFunction(engineClient, 74); // Windows: // E8 ?? ?? ?? ?? call GetBaseLocalClient @@ -32,7 +32,7 @@ static procptr_t getLocalClient(const procptr_t engineClient) { // 8B 40 ?? mov eax, [eax+?] // C9 leave // C3 retn - const auto callTarget = peekProc< int32_t >(GetNetChannelInfo + (isWin32 ? 1 : 7)); + const auto callTarget = proc->peek< int32_t >(GetNetChannelInfo + (isWin32 ? 1 : 7)); const auto callInstructionEnd = GetNetChannelInfo + (isWin32 ? 5 : 11); const auto GetBaseLocalClient = callInstructionEnd + callTarget; @@ -41,7 +41,8 @@ static procptr_t getLocalClient(const procptr_t engineClient) { // 83 C0 ?? add eax, ? // C3 retn if (isWin32) { - return peekProcPtr(peekProc< uint32_t >(GetBaseLocalClient + 1)) + peekProc< int8_t >(GetBaseLocalClient + 7); + return proc->peekPtr(proc->peek< uint32_t >(GetBaseLocalClient + 1)) + + proc->peek< int8_t >(GetBaseLocalClient + 7); } // Linux: @@ -85,11 +86,11 @@ static procptr_t getLocalClient(const procptr_t engineClient) { // // Its purpose seem to be to iterate over the clients array, which is done directly by GetBaseLocalClient() and // GetLocalClient() on Windows. - return peekProcPtr(peekProc< uint32_t >(GetBaseLocalClient + 17) + 4) + 4; + return proc->peekPtr(proc->peek< uint32_t >(GetBaseLocalClient + 17) + 4) + 4; } static int8_t getSignOnStateOffset(const procptr_t engineClient) { - const auto IsInGame = getVirtualFunction(engineClient, 26); + const auto IsInGame = proc->virtualFunction(engineClient, 26); // Windows: // E8 ?? ?? ?? ?? call GetBaseLocalClient @@ -107,11 +108,11 @@ static int8_t getSignOnStateOffset(const procptr_t engineClient) { // C9 leave // 0F 94 C0 setz al // C3 retn - return peekProc< int8_t >(IsInGame + (isWin32 ? 9 : 13)); + return proc->peek< int8_t >(IsInGame + (isWin32 ? 9 : 13)); } static int32_t getLevelNameOffset(const procptr_t engineClient) { - const auto GetLevelNameShort = getVirtualFunction(engineClient, 53); + const auto GetLevelNameShort = proc->virtualFunction(engineClient, 53); // Windows: // ... @@ -128,19 +129,19 @@ static int32_t getLevelNameOffset(const procptr_t engineClient) { // 05 ?? ?? ?? ?? add eax, ? // C3 retn if (isWin32) { - if (peekProc< uint8_t >(GetLevelNameShort + 37) == 0x05) { + if (proc->peek< uint8_t >(GetLevelNameShort + 37) == 0x05) { // Left 4 Dead - return peekProc< int32_t >(GetLevelNameShort + 38); + return proc->peek< int32_t >(GetLevelNameShort + 38); } else { - return peekProc< int32_t >(GetLevelNameShort + 40); + return proc->peek< int32_t >(GetLevelNameShort + 40); } } - return peekProc< int32_t >(GetLevelNameShort + 57); + return proc->peek< int32_t >(GetLevelNameShort + 57); } static int32_t getNetInfoOffset(const procptr_t localClient, const procptr_t engineClient) { - const auto GetNetChannelInfo = getVirtualFunction(engineClient, 74); + const auto GetNetChannelInfo = proc->virtualFunction(engineClient, 74); // Windows: // E8 ?? ?? ?? ?? call GetBaseLocalClient @@ -155,8 +156,9 @@ static int32_t getNetInfoOffset(const procptr_t localClient, const procptr_t eng // 8B 40 ?? mov eax, [eax+?] // C9 leave // C3 retn - const auto NetChannelInfo = peekProcPtr(localClient + peekProc< int8_t >(GetNetChannelInfo + (isWin32 ? 7 : 13))); - const auto GetAddress = getVirtualFunction(NetChannelInfo, 1); + const auto NetChannelInfo = + proc->peekPtr(localClient + proc->peek< int8_t >(GetNetChannelInfo + (isWin32 ? 7 : 13))); + const auto GetAddress = proc->virtualFunction(NetChannelInfo, 1); // Windows: // 6A 00 push 0 @@ -175,7 +177,7 @@ static int32_t getNetInfoOffset(const procptr_t localClient, const procptr_t eng // E8 ?? ?? ?? ?? call ToString // C9 leave // C3 retn - const auto netInfo = NetChannelInfo + peekProc< int32_t >(GetAddress + (isWin32 ? 4 : 18)); + const auto netInfo = NetChannelInfo + proc->peek< int32_t >(GetAddress + (isWin32 ? 4 : 18)); return static_cast< int32_t >(netInfo - localClient); } diff --git a/plugins/se/se.cpp b/plugins/se/se.cpp index b84363e3a..4560046e5 100644 --- a/plugins/se/se.cpp +++ b/plugins/se/se.cpp @@ -3,8 +3,20 @@ // that can be found in the LICENSE file at the root of the // Mumble source tree or at <https://www.mumble.info/LICENSE>. -#include "../mumble_plugin_main.h" -#include "../mumble_plugin_utils.h" +#include "mumble_plugin.h" +#include "mumble_plugin_utils.h" + +#ifdef OS_LINUX +# include "ProcessLinux.h" +#endif +#include "ProcessWindows.h" + +#include <cstring> +#include <sstream> + +std::unique_ptr< Process > proc; + +static bool isWin32 = false; #include "client.h" #include "common.h" @@ -40,7 +52,7 @@ int32_t signOnStateOffset, deadFlagOffset, rotationOffset, originPositionOffset, static int fetch(float *avatarPos, float *avatarFront, float *avatarTop, float *cameraPos, float *cameraFront, float *cameraTop, std::string &context, std::wstring &identity) { - const auto signOnState = peekProc< uint32_t >(localClient + signOnStateOffset); + const auto signOnState = proc->peek< uint32_t >(localClient + signOnStateOffset); // 0: SIGNONSTATE_NONE // 1: SIGNONSTATE_CHALLENGE @@ -54,7 +66,7 @@ static int fetch(float *avatarPos, float *avatarFront, float *avatarTop, float * return false; } - const auto isPlayerDead = peekProc< bool >(localPlayer + deadFlagOffset); + const auto isPlayerDead = proc->peek< bool >(localPlayer + deadFlagOffset); if (isPlayerDead) { context.clear(); identity.clear(); @@ -67,22 +79,22 @@ static int fetch(float *avatarPos, float *avatarFront, float *avatarTop, float * } float rotation[3]; - if (!peekProc(localPlayer + rotationOffset, rotation, sizeof(rotation))) { + if (!proc->peek(localPlayer + rotationOffset, rotation, sizeof(rotation))) { return false; } float originPosition[3]; - if (!peekProc(localPlayer + originPositionOffset, originPosition, sizeof(originPosition))) { + if (!proc->peek(localPlayer + originPositionOffset, originPosition, sizeof(originPosition))) { return false; } float eyesPositionOffset[3]; - if (!peekProc(localPlayer + eyesPositionOffsetOffset, eyesPositionOffset, sizeof(eyesPositionOffset))) { + if (!proc->peek(localPlayer + eyesPositionOffsetOffset, eyesPositionOffset, sizeof(eyesPositionOffset))) { return false; } NetInfo ni; - if (!peekProc(localClient + netInfoOffset, ni)) { + if (!proc->peek(localClient + netInfoOffset, ni)) { return false; } @@ -112,7 +124,7 @@ static int fetch(float *avatarPos, float *avatarFront, float *avatarTop, float * // 40 is the size of the char array in the engine's code char map[40]; - if (!peekProc(localClient + levelNameOffset, map, sizeof(map))) { + if (!proc->peek(localClient + levelNameOffset, map, sizeof(map))) { map[0] = '\0'; } @@ -168,18 +180,31 @@ static int fetch(float *avatarPos, float *avatarFront, float *avatarTop, float * } static bool tryInit(const std::multimap< std::wstring, unsigned long long int > &pids) { + const std::vector< std::string > names{ #ifdef OS_LINUX - if (initialize(pids, L"hl2_linux")) { - return true; - } + "hl2_linux", #endif + "left4dead2.exe", "left4dead.exe" + }; - if (initialize(pids, L"left4dead2.exe")) { - return true; - } - - if (initialize(pids, L"left4dead.exe")) { - return true; + for (const auto &name : names) { + const auto id = Process::find(name, pids); + if (!id) { + continue; + } +#ifdef OS_WINDOWS + proc.reset(new ProcessWindows(id, name)); +#else + isWin32 = HostLinux::isWine(id); + if (isWin32) { + proc.reset(new ProcessWindows(id, name)); + } else { + proc.reset(new ProcessLinux(id, name)); + } +#endif + if (proc->isOk()) { + return true; + } } return false; @@ -190,12 +215,12 @@ static int tryLock(const std::multimap< std::wstring, unsigned long long int > & return false; } - const auto engine = getModuleAddr(isWin32 ? L"engine.dll" : L"engine.so"); + const auto engine = proc->module(isWin32 ? "engine.dll" : "engine.so"); if (!engine) { return false; } - const auto client = getModuleAddr(isWin32 ? L"client.dll" : L"client.so"); + const auto client = proc->module(isWin32 ? "client.dll" : "client.so"); if (!client) { return false; } @@ -217,7 +242,7 @@ static int tryLock(const std::multimap< std::wstring, unsigned long long int > & return false; } - const auto signOnState = peekProc< uint32_t >(localClient + signOnStateOffset); + const auto signOnState = proc->peek< uint32_t >(localClient + signOnStateOffset); if (signOnState != 6) { return false; } @@ -273,17 +298,7 @@ static int tryLock(const std::multimap< std::wstring, unsigned long long int > & return false; } - float avatarPos[3], avatarFront[3], avatarTop[3]; - float cameraPos[3], cameraFront[3], cameraTop[3]; - std::string context; - std::wstring identity; - - if (fetch(avatarPos, avatarFront, avatarTop, cameraPos, cameraFront, cameraTop, context, identity)) { - return true; - } else { - generic_unlock(); - return false; - } + return true; } static const std::wstring longDesc() { @@ -297,8 +312,11 @@ static int tryLock1() { return tryLock(std::multimap< std::wstring, unsigned long long int >()); } -static MumblePlugin sePlug = { MUMBLE_PLUGIN_MAGIC, description, shortName, NULL, NULL, tryLock1, - generic_unlock, longDesc, fetch }; +static void nullUnlock() { +} + +static MumblePlugin sePlug = { MUMBLE_PLUGIN_MAGIC, description, shortName, nullptr, nullptr, tryLock1, + nullUnlock, longDesc, fetch }; static MumblePlugin2 sePlug2 = { MUMBLE_PLUGIN_MAGIC_2, MUMBLE_PLUGIN_VERSION, tryLock }; |