Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavide Beatrici <davidebeatrici@gmail.com>2019-08-12 05:51:16 +0300
committerDavide Beatrici <davidebeatrici@gmail.com>2019-08-17 01:31:18 +0300
commit6fb885c451382631f7a690210fed5e5fcf098ea5 (patch)
tree209c92e72abec4ad3ac2e61d9d77f6497b065c02 /plugins
parent86154c82344f130ed14633a21fdbe19b7937a80f (diff)
mumble_plugin_linux.h: detect process architecture by reading the process' memory instead of its binary
Aside from being faster, it also requires less code. This commit also changes the way architecture is detected for Win32 processes. Previously, we relied on the Wine's preloader binary's architecture because we read its ELF header; now we read the NT header(s) by calling isWin32Process64Bit() (implemented in 86154c82344f130ed14633a21fdbe19b7937a80f).
Diffstat (limited to 'plugins')
-rw-r--r--plugins/mumble_plugin_linux.h104
-rw-r--r--plugins/mumble_plugin_main.h6
2 files changed, 74 insertions, 36 deletions
diff --git a/plugins/mumble_plugin_linux.h b/plugins/mumble_plugin_linux.h
index 1815874b4..4b91c012d 100644
--- a/plugins/mumble_plugin_linux.h
+++ b/plugins/mumble_plugin_linux.h
@@ -38,38 +38,53 @@ static inline std::string readAll(const std::string &fn) {
return content;
}
-// This function returns 0 if the process is 32-bit and 1 if it's 64-bit.
-// In case of failure, it returns -1.
-static inline int checkProcessIs64Bit(const procid_t &pid)
-{
+// This function returns:
+// -1 in case of failure.
+// 0 if the process is 32-bit.
+// 1 if the process is 64-bit.
+static inline int isProcess64Bit(const procptr_t &baseAddress) {
+ if (isWin32) {
+ return isWin32Process64Bit(baseAddress);
+ }
+
// We can know the process architecture by looking at its ELF header.
- char elf[5];
+ uint8_t elf[5];
+
+ peekProc(baseAddress, elf, sizeof(elf));
+ // The first 4 bytes constitute the magical number in ASCII: 0x7F 45 4c 46.
+ if (!(elf[0] == 0x7f && elf[1] == 'E' && elf[2] == 'L' && elf[3] == 'F')) {
+ return -1;
+ }
+
+ // The fifth byte is 1 in case the process is 32-bit or 2 in case it's 64-bit.
+ return elf[4] != 1;
+}
+
+// This function returns:
+// -1 in case of failure.
+// 0 if the process is not running through Wine.
+// 1 if the process is running through Wine.
+static inline int8_t isProcessWin32(const procid_t &pid) {
std::stringstream ss;
ss << "/proc/";
ss << static_cast<unsigned long>(pid);
ss << "/exe";
- std::ifstream ifs;
- ifs.open(ss.str(), std::ifstream::binary);
- if (!ifs.is_open()) {
+ char *path = realpath(ss.str().c_str(), nullptr);
+ if (!path) {
return -1;
}
- ifs.read(elf, LENGTH_OF(elf));
- ifs.close();
+ const char *filename = basename(path);
- if (ifs.gcount() != LENGTH_OF(elf)) {
- return -1;
- }
+ free(path);
- // The first 4 bytes constitute the magical number in ASCII: 0x7F 45 4c 46.
- if (!(elf[0] == 0x7f && elf[1] == 'E' && elf[2] == 'L' && elf[3] == 'F')) {
- return -1;
+ if (strcmp(filename, "wine-preloader") == 0 || strcmp(filename, "wine64-preloader") == 0) {
+ return 1;
}
- // The fifth byte is 1 in case the process is 32-bit or 2 in case it's 64-bit.
- return elf[4] != 1;
+ return 0;
}
static inline procptr_t getModuleAddr(const procid_t &pid, const wchar_t *modname) {
@@ -194,43 +209,60 @@ static inline bool peekProc(const procptr_t &addr, void *dest, const size_t &len
return (nread != -1 && static_cast<size_t>(nread) == in.iov_len);
}
-static bool inline initialize(const std::multimap<std::wstring, unsigned long long int> &pids, const wchar_t *procname, const wchar_t *modname = nullptr) {
+static void generic_unlock() {
pModule = 0;
+ pPid = 0;
+}
- if (! pids.empty()) {
- std::multimap<std::wstring, unsigned long long int>::const_iterator iter = pids.find(std::wstring(procname));
+static bool initialize(const std::multimap<std::wstring, unsigned long long int> &pids, const wchar_t *procname, const wchar_t *modname = nullptr) {
+ pModule = 0;
- if (iter != pids.end())
- pPid = static_cast<pid_t>(iter->second);
- else
+ if (!pids.empty()) {
+ auto iter = pids.find(std::wstring(procname));
+ if (iter != pids.end()) {
+ pPid = static_cast<procid_t>(iter->second);
+ } else {
pPid = 0;
+ }
} else {
pPid = 0;
}
- if (pPid == 0)
+ if (!pPid) {
return false;
+ }
- int result = checkProcessIs64Bit(pPid);
- if (result == -1) {
+ pModule = getModuleAddr(procname);
+ if (!pModule) {
+ pPid = 0;
return false;
}
- is64Bit = result;
+ int8_t ret = isProcessWin32(pPid);
+ if (ret == -1) {
+ generic_unlock();
+ return false;
+ }
- pModule = getModuleAddr(modname ? modname : procname);
+ isWin32 = ret;
- if (pModule == 0) {
- pPid = 0;
+ ret = isProcess64Bit(pModule);
+ if (ret == -1) {
+ generic_unlock();
return false;
}
- return true;
-}
+ is64Bit = ret;
-static void generic_unlock() {
- pModule = 0;
- pPid = 0;
+ if (modname) {
+ pModule = getModuleAddr(modname);
+ if (!pModule) {
+ pPid = 0;
+ return false;
+ }
+ }
+
+ return true;
}
#endif
diff --git a/plugins/mumble_plugin_main.h b/plugins/mumble_plugin_main.h
index 831d576cf..a542471df 100644
--- a/plugins/mumble_plugin_main.h
+++ b/plugins/mumble_plugin_main.h
@@ -17,6 +17,12 @@
#include "mumble_plugin.h"
#include "mumble_plugin_win32_internals.h"
+#ifdef WIN32
+static const bool isWin32 = true;
+#else
+static bool isWin32;
+#endif
+
static bool is64Bit;
static procid_t pPid;
static procptr_t pModule;