Memory::ReadData failing
Hey, using the Mouse and Keyboard functionality of Robot thus far has been a great success, I'm now trying to use Memory::ReadData to read a specific address from a process that I have obtained through scanmem / gameconquerer on Arch Linux 64bit, kernel release 4.1.21.
I use the following code:
// ..
std::cout<<"Found window, "<<window.GetPID()<<"\n";
Memory reader(window.GetProcess());
if(!reader.IsValid()) { return 0; }
// Read
for(auto &i : reader.GetRegions()) {
if(i.Contains( ADDR )) {
reader.SetAccess(i,true,false,false); // Doesn't do anything on Linux :(
std::cout<<"Valid: "<<i.Valid<<"\n";
std::cout<<"Read: "<<i.Readable<<"\n";
std::cout<<"Write: "<<i.Writable<<"\n";
std::cout<<"Private: "<<i.Private<<"\n";
std::cout<<"Access: "<<i.Access<<"\n";
std::cout<<"Guarded: "<<i.Guarded<<"\n";
int32 max;
std::cout<<"Success: "<<reader.ReadData( ADDR ,&max,4,Memory::Flags::AutoAccess)<<"\n";
std::cout<<"Data: "<<max<<"\n";
}
}
Found window, 26367 Valid: 1 Read: 0 Write: 0 Private: 0 Access: 0 Guarded: 0 Success: 4 Data: 0
Using Flags::AutoAccess makes the ReadData call return 4, without it the call fails; returning 0. Running this as root has no effect, it fails every time. I'm expecting Data to be about 600.
I've tried running the tests of the Memory segment of Robot through compiling the tests,
make test Binaries/Linux/Test.bin memory Although when attaching gdb to a the running process robot seemingly fails to see the debugger. p.IsDebugged() Failed Memory.cc:647 Debug p1 Failed
Am I using the ReadData function wrong? I've checked the examples on the API, it looks OK.
Hey, so right up front, I'm not a Linux expert. I tried my best to get a Linux implementation working but I can't guarantee that it'll work across all distributions. I only developed and tested this on Ubuntu 12.04 and up.
That being said, the function SetAccess is not available because I couldn't actually figure out how to implement it. Everywhere I looked it said that it was either impossible or required hacking the kernel. Maybe somebody can tell me. But because of that, Flags::AutoAccess will do nothing and instead, fall back to Flags::SkipErrors, which just fills the output buffer with zeroes when it detects an error (but it'll appear as though it read it successfully).
As for ReadData, currently it's implemented by reading and writing the /proc/mem file. If that file can't be opened at construction time, then ReadData and WriteData will automatically fail. Currently IsValid doesn't check if that file is opened, maybe it should? So my guess is that either the /proc/mem file can't be accessed or the region of memory you're reading isn't readable. I suggest debugging SysRead to see what's actually happening. If the method I'm using isn't compatible with your distribution of Linux then I'm not sure what else I could do, again, maybe somebody can tell me.
The test cases are not very "user friendly", they're good but require you to understand how the test cases work. I don't know how I would even approach documenting something like that. Anyways, keep me updated on this issue and I hope you're able to figure out how to make it work.