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:
authordavidebeatrici <davidebeatrici@gmail.com>2017-11-19 23:46:29 +0300
committerdavidebeatrici <davidebeatrici@gmail.com>2017-11-19 23:48:49 +0300
commit7286fb0f6815a01114e84572edb7cadc5a786134 (patch)
treed65fa9570e534ce02f4a172465a53e050a132d6d /plugins/mumble_plugin_linux.h
parent8bf71ba16d0c0c8e3ae030fd2fbe5b666bed6212 (diff)
Determine correct pointer size automatically, without the need of specific headers and variables
This commit removes the architecture-specific headers, by keeping only the OS-specific ones. The different headers were needed to keep the legacy Windows header, after we created the "procptr32_t" (4 bytes) and "procptr64_t" (8 bytes) variables. We created these variables because the "peekProc" functions read as many bytes as the variable can hold. A pointer is 4 bytes on 32 bit platforms and 8 bytes on 64 bit ones. Now there's a new variable, called "procptr_t" and with a size of 8 bytes (unsigned long long). We had a "peekProc" template function which returned the value stored at the specified memory address, but it has been used only to read pointers so far. Since we needed a new function that checks the process architecture and sets the correct size of the memory to read, I decided to "recycle" it.
Diffstat (limited to 'plugins/mumble_plugin_linux.h')
-rw-r--r--plugins/mumble_plugin_linux.h75
1 files changed, 57 insertions, 18 deletions
diff --git a/plugins/mumble_plugin_linux.h b/plugins/mumble_plugin_linux.h
index fe2b6a6ae..5229e50b4 100644
--- a/plugins/mumble_plugin_linux.h
+++ b/plugins/mumble_plugin_linux.h
@@ -6,10 +6,6 @@
#ifndef MUMBLE_PLUGIN_LINUX_H_
#define MUMBLE_PLUGIN_LINUX_H_
-#ifndef PTR_TYPE_CONCRETE
-# define PTR_TYPE_CONCRETE PTR_TYPE
-#endif
-
#include <sys/uio.h>
#include <stdio.h>
#include <stdlib.h>
@@ -23,7 +19,8 @@
#include "mumble_plugin.h"
pid_t pPid;
-static PTR_TYPE_CONCRETE pModule;
+int is64Bit;
+static procptr_t pModule;
static inline std::string readAll(std::string fn) {
std::ifstream ifs;
@@ -43,7 +40,41 @@ static inline std::string readAll(std::string fn) {
return content;
}
-static inline PTR_TYPE_CONCRETE getModuleAddr(pid_t pid, const wchar_t *modname) {
+// 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 pid_t pid)
+{
+ // We can know the process architecture by looking at its ELF header.
+ char elf[5];
+
+ 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()) {
+ return -1;
+ }
+
+ ifs.read(elf, LENGTH_OF(elf));
+ ifs.close();
+
+ if (ifs.gcount() != LENGTH_OF(elf)) {
+ return -1;
+ }
+
+ // 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;
+}
+
+static inline procptr_t getModuleAddr(pid_t pid, const wchar_t *modname) {
std::wstring modnameWide(modname);
std::string modnameNonWide(modnameWide.begin(), modnameWide.end());
@@ -151,11 +182,11 @@ static inline PTR_TYPE_CONCRETE getModuleAddr(pid_t pid, const wchar_t *modname)
return 0;
}
-static inline PTR_TYPE_CONCRETE getModuleAddr(const wchar_t *modname) {
+static inline procptr_t getModuleAddr(const wchar_t *modname) {
return getModuleAddr(pPid, modname);
}
-static inline bool peekProc(PTR_TYPE base, void *dest, size_t len) {
+static inline bool peekProc(procptr_t base, void *dest, size_t len) {
struct iovec in;
in.iov_base = reinterpret_cast<void *>(base); // Address from target process
in.iov_len = len; // Length
@@ -170,16 +201,7 @@ static inline bool peekProc(PTR_TYPE base, void *dest, size_t len) {
}
template<class T>
-T peekProc(PTR_TYPE base) {
- T v = 0;
- if (!peekProc(base, reinterpret_cast<T *>(&v), sizeof(T))) {
- return 0;
- }
- return v;
-}
-
-template<class T>
-bool peekProc(PTR_TYPE base, T &dest) {
+bool peekProc(procptr_t base, T &dest) {
struct iovec in;
in.iov_base = reinterpret_cast<void *>(base); // Address from target process
in.iov_len = sizeof(T); // Length
@@ -193,6 +215,16 @@ bool peekProc(PTR_TYPE base, T &dest) {
return (nread != -1 && static_cast<size_t>(nread) == in.iov_len);
}
+static inline procptr_t peekProcPtr(procptr_t base) {
+ procptr_t v = 0;
+
+ if (!peekProc(base, &v, is64Bit ? 8 : 4)) {
+ return 0;
+ }
+
+ return v;
+}
+
static bool inline initialize(const std::multimap<std::wstring, unsigned long long int> &pids, const wchar_t *procname, const wchar_t *modname = NULL) {
pModule = 0;
@@ -210,6 +242,13 @@ static bool inline initialize(const std::multimap<std::wstring, unsigned long lo
if (pPid == 0)
return false;
+ int result = checkProcessIs64Bit(pPid);
+ if (result == -1) {
+ return false;
+ }
+
+ is64Bit = result;
+
pModule = getModuleAddr(modname ? modname : procname);
if (pModule == 0) {