1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// Copyright 2020-2023 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
#ifndef MUMBLE_MUMBLE_PLUGIN_SE_ENGINE_
#define MUMBLE_MUMBLE_PLUGIN_SE_ENGINE_
struct NetInfo {
uint32_t type;
uint8_t ip[4];
uint16_t port;
};
static procptr_t getLocalClient(const procptr_t engineClient) {
// We use GetBaseLocalClient() instead of GetLocalClient() because we just need the main client.
// 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 = proc->virtualFunction(engineClient, 74);
// Windows:
// E8 ?? ?? ?? ?? call GetBaseLocalClient
// 8B 40 ?? mov eax, [eax+?]
// C3 retn
//
// Linux:
// 55 push ebp
// 89 E5 mov ebp, esp
// 83 EC 08 sub esp, 8
// E8 ?? ?? ?? ?? call GetBaseLocalClient
// 8B 40 ?? mov eax, [eax+?]
// C9 leave
// C3 retn
const auto callTarget = proc->peek< int32_t >(GetNetChannelInfo + (isWin32 ? 1 : 7));
const auto callInstructionEnd = GetNetChannelInfo + (isWin32 ? 5 : 11);
const auto GetBaseLocalClient = callInstructionEnd + callTarget;
// Windows:
// A1 ?? ?? ?? ?? mov eax, dword_????????
// 83 C0 ?? add eax, ?
// C3 retn
//
// Linux:
// A1 ?? ?? ?? ?? mov eax, dword_????????
// 55 push ebp
// 89 E5 mov ebp, esp
// 5D pop ebp
// 83 C0 ?? add eax, ?
// C3 retn
return proc->peekPtr(proc->peek< uint32_t >(GetBaseLocalClient + 1))
+ proc->peek< int8_t >(GetBaseLocalClient + (isWin32 ? 7 : 11));
}
static int8_t getSignOnStateOffset(const procptr_t engineClient) {
const auto IsInGame = proc->virtualFunction(engineClient, 26);
// Windows:
// E8 ?? ?? ?? ?? call GetBaseLocalClient
// 33 C9 xor ecx, ecx
// 83 78 ?? 06 cmp dword ptr [eax+?], 6
// 0F 94 C0 setz al
// C3 retn
//
// Linux:
// 55 push ebp
// 89 E5 mov ebp, esp
// 83 EC 08 sub esp, 8
// E8 ?? ?? ?? ?? call GetBaseLocalClient
// 83 78 ?? 06 cmp dword ptr [eax+?], 6
// C9 leave
// 0F 94 C0 setz al
// C3 retn
return proc->peek< int8_t >(IsInGame + (isWin32 ? 9 : 13));
}
static int32_t getLevelNameOffset(const procptr_t engineClient) {
const auto GetLevelNameShort = proc->virtualFunction(engineClient, 53);
// Windows:
// ...
//
// E8 ?? ?? ?? ?? call GetBaseLocalClient
// 05 ?? ?? ?? ?? add eax, ?
// C3 retn
//
// Linux:
// ...
//
// E8 ?? ?? ?? ?? call GetBaseLocalClient
// 05 ?? ?? ?? ?? add eax, ?
// C9 leave
// C3 retn
if (isWin32) {
if (proc->peek< uint8_t >(GetLevelNameShort + 37) == 0x05) {
// Left 4 Dead
return proc->peek< int32_t >(GetLevelNameShort + 38);
} else {
return proc->peek< int32_t >(GetLevelNameShort + 40);
}
}
return proc->peek< int32_t >(GetLevelNameShort + 46);
}
static int32_t getNetInfoOffset(const procptr_t localClient, const procptr_t engineClient) {
const auto GetNetChannelInfo = proc->virtualFunction(engineClient, 74);
// Windows:
// E8 ?? ?? ?? ?? call GetBaseLocalClient
// 8B 40 ?? mov eax, [eax+?]
// C3 retn
//
// Linux:
// 55 push ebp
// 89 E5 mov ebp, esp
// 83 EC 08 sub esp, 8
// E8 ?? ?? ?? ?? call GetBaseLocalClient
// 8B 40 ?? mov eax, [eax+?]
// C9 leave
// C3 retn
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
// 81 C1 ?? ?? ?? ?? add ecx, ?
// E8 C3 9D 1D 00 call ToString
// C3 retn
//
// Linux:
// 55 push ebp
// 89 E5 mov ebp, esp
// 83 EC ?? sub esp, ?
// 8B 45 08 mov eax, [ebp+arg_0]
// C7 44 24 04 00 00 00 00 mov dword ptr [esp+4], 0
// 05 ?? ?? ?? ?? add eax, ?
// 89 04 24 mov [esp], eax
// E8 ?? ?? ?? ?? call ToString
// C9 leave
// C3 retn
const auto netInfo = NetChannelInfo + proc->peek< int32_t >(GetAddress + (isWin32 ? 4 : 18));
return static_cast< int32_t >(netInfo - localClient);
}
#endif
|