File: common.h

package info (click to toggle)
mumble 1.5.857-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 90,180 kB
  • sloc: cpp: 556,939; ansic: 81,662; python: 3,607; sh: 659; makefile: 506; cs: 389; asm: 371; sql: 228; javascript: 143; xml: 88; perl: 80
file content (86 lines) | stat: -rw-r--r-- 2,651 bytes parent folder | download | duplicates (3)
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
// 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_COMMON_
#define MUMBLE_MUMBLE_PLUGIN_SE_COMMON_

typedef std::map< std::string, procptr_t > Interfaces;

struct InterfaceReg {
	uint32_t createFunction;
	uint32_t name;
	uint32_t next;
};

static Interfaces getInterfaces(const procptr_t module) {
	Interfaces interfaces;

	// s_pInterfaceRegs is exported on Linux
	auto s_pInterfaceRegs = proc->exportedSymbol("s_pInterfaceRegs", module);
	if (!s_pInterfaceRegs) {
		const auto CreateInterface = proc->exportedSymbol("CreateInterface", module);
		if (CreateInterface == 0) {
			return interfaces;
		}

		bool jmpOnly;

		if (proc->peek< uint8_t >(CreateInterface) == 0xE9) {
			// Left 4 Dead:
			// E9 ?? ?? ?? ??    jmp    CreateInterface_0
			jmpOnly = true;
		} else {
			// Other games:
			// 55                push    ebp
			// 8B EC             mov     ebp, esp
			// 5D                pop     ebp
			// E9 ?? ?? ?? ??    jmp     CreateInterfaceInternal
			jmpOnly = false;
		}

		const auto jmpTarget               = proc->peek< int32_t >(CreateInterface + (jmpOnly ? 1 : 5));
		const auto jmpInstructionEnd       = CreateInterface + (jmpOnly ? 5 : 9);
		const auto CreateInterfaceInternal = jmpInstructionEnd + jmpTarget;

		// Left 4 Dead:
		// 56                   push    esi
		// 8B 35 ?? ?? ?? ??    mov     esi, s_pInterfaceRegs
		// 85 F6                test    esi, esi
		// 57                   push    edi
		//
		// Other games:
		// 55                   push    ebp
		// 8B EC                mov     ebp, esp
		// 56                   push    esi
		// 8B 35 ?? ?? ?? ??    mov     esi, s_pInterfaceRegs
		if (proc->peek< uint16_t >(CreateInterfaceInternal + (jmpOnly ? 1 : 4)) != 0x358B) {
			return interfaces;
		}

		s_pInterfaceRegs = proc->peek< uint32_t >(CreateInterfaceInternal + (jmpOnly ? 3 : 6));
	}

	auto iface = proc->peek< InterfaceReg >(proc->peekPtr(s_pInterfaceRegs));

	do {
		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 && proc->peek(iface.next, iface));

	return interfaces;
}

static procptr_t getInterfaceAddress(const std::string &name, const Interfaces &interfaces) {
	const auto iface = interfaces.find(name);
	if (iface == interfaces.end()) {
		return 0;
	}

	return iface->second;
}

#endif