New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plugins: Determine correct pointer size automatically, without the need of specific headers and variables #3262
Plugins: Determine correct pointer size automatically, without the need of specific headers and variables #3262
Conversation
7bb33c2
to
a601e52
Compare
a601e52
to
222298c
Compare
4ad5944
to
755b853
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes the code quite a bit more convenient. Not exactly fond of the linux way of checking for 64bit but that probably can't be helped if we want this feature.
See comments.
plugins/mumble_plugin_linux.h
Outdated
@@ -23,7 +19,8 @@ | |||
#include "mumble_plugin.h" | |||
|
|||
pid_t pPid; | |||
static PTR_TYPE_CONCRETE pModule; | |||
bool is64Bit; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no bool in C
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should create an enum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually... no. It's better if we change the variable to an integer, otherwise we can't use the inline if statement.
plugins/mumble_plugin_linux.h
Outdated
@@ -23,7 +19,8 @@ | |||
#include "mumble_plugin.h" | |||
|
|||
pid_t pPid; | |||
static PTR_TYPE_CONCRETE pModule; | |||
bool is64Bit; | |||
static procptr_t pModule; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why this is static to be honest. We only include it in one TU and having it multiple times would almost always lead to mistakes as you'd have to initialize is separately from each TU. Without static at least the linker would complain. Any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I asked myself too why this is static, but I decided to left it as it was.
plugins/mumble_plugin_linux.h
Outdated
std::ifstream ifs; | ||
ifs.open(ss.str(), std::ifstream::binary); | ||
|
||
std::string elf; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
istreams have a read method that does what you want (http://www.cplusplus.com/reference/istream/istream/read/):
char elf[5];
ifs.read(elf, 5);
Don't forget to check whether the stream is ok after than.
plugins/mumble_plugin_linux.h
Outdated
ifs.close(); | ||
|
||
if (!(elf.at(0) == 0x7f && elf.at(1) == 'E' && elf.at(2) == 'L' && elf.at(3) == 'F')) { | ||
return -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does -1 indicate failure to identify then? Please document the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right.
if (!hProcess) { | ||
int result = checkProcessIs64Bit(hProcess); | ||
if (result == -1) { | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaking hProcess?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think it's better if we create a dedicated handle in checkProcessIs64Bit()
, so that the global one needs only PROCESS_VM_READ
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That just gives us another handle that we mustn't leak ;) I would just close the handle instead of leaking it in the error cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course, but in addition to that it's better to use a dedicated handle for IsWow64Process()
, as it needs a specific permission which we use only one time.
is64Bit = result != 0; | ||
|
||
pModule=getModuleAddr(modname ? modname : procname); | ||
if (!pModule) { | ||
dwPid = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaking hProcess?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm going to move it above OpenProcess()
.
plugins/mumble_plugin_linux.h
Outdated
// The first 4 bytes constitute the magical number in ASCII: 0x7F 45 4c 46. | ||
|
||
std::stringstream ss; | ||
ss << std::string("/proc/"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the std::string wrapping? Just causes a needless alloc. Pretty sure there's a const char* overload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took the code from getModuleAddr()
, which was written by @mkrautz.
How would you do it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ss << "/proc/";
Should work I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just tried, it works.
plugins/mumble_plugin_linux.h
Outdated
T peekProc(PTR_TYPE base) { | ||
T v = 0; | ||
if (!peekProc(base, reinterpret_cast<T *>(&v), sizeof(T))) { | ||
procptr_t peekProcPtr(procptr_t base) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should document that this relies on initialize.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a new pull request, as this one is focused on the automatic pointer size, not on cleaning up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dependency was introduced by making it rely in the 64bit check so imho documenting that belongs into the PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, every peekProc()
function relies on initialize()
.
ad7f74e
to
ce1df33
Compare
plugins/mumble_plugin_linux.h
Outdated
std::ifstream ifs; | ||
ifs.open(ss.str(), std::ifstream::binary); | ||
if (ifs.is_open()) { | ||
ifs.read(elf, 5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing check for failure. I guess in this case we could just not check and instead make sure elf is zero initialized. Bad habit to get into though.
plugins/mumble_plugin_linux.h
Outdated
char elf[5]; | ||
|
||
std::stringstream ss; | ||
ss << std::string("/proc/"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ss << "/proc/";
plugins/mumble_plugin_linux.h
Outdated
std::stringstream ss; | ||
ss << std::string("/proc/"); | ||
ss << static_cast<unsigned long>(pid); | ||
ss << std::string("/exe"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
|
||
BOOL isWow64Process; | ||
if (!IsWow64Process(handle, &isWow64Process)) { | ||
return -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leaking handle
plugins/mumble_plugin_linux.h
Outdated
std::ifstream ifs; | ||
ifs.open(ss.str(), std::ifstream::binary); | ||
if (ifs.is_open()) { | ||
ifs.read(elf, 5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should sizeof elf. I believe we have a define for array sizeof somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -23,7 +19,8 @@ | |||
#include "mumble_plugin.h" | |||
|
|||
pid_t pPid; | |||
static PTR_TYPE_CONCRETE pModule; | |||
int is64Bit; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Named like a bool. Should be a bool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it should, but C doesn't have a boolean data type, as pointed out by @hacst.
static inline PTR_TYPE_CONCRETE getModuleAddr(DWORD pid, const wchar_t *modname) { | ||
static inline int checkProcessIs64Bit(const DWORD pid) | ||
{ | ||
// This function returns 0 if the process is 32-bit and 1 if it's 64-bit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be a method comment!?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from my minor comment LGTM. Please make sure to test on Windows and Linux but then I see no reason for you not to land it without another review iteration.
plugins/mumble_plugin_linux.h
Outdated
ifs.read(elf, LENGTH_OF(elf)); | ||
ifs.close(); | ||
|
||
if (ifs.gcount() != 5) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should also use the macro.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, right.
…cific 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.
This commit removes the legacy header, with the new one taking its name.
0656e1f
to
2a51c7b
Compare
No description provided.