I am trying to use the process_vm_readv systemcall to read a value from another Linux process. When attempting to read a magic number at a known location, I receive a random value.
I have tried writing two simple programs to see if I can get it working but I have failed. I have checked my return values and they succeed every time, I just left it out to make the code clearer.
Main File (to read from)
const long val = 0xDEADBEEF;
int main(int argc, char** argv) {
std::cin.get(); // keep process running so I can read from it
}
Reader
int main(int argc, char** argv) {
pid_t pid = strol(argv[1], NULL, 10);
constexpr bufferLen = sizeof(long);
char buffer[bufferLen] { 0 };
struct iovec local, remote;
local.iov_base = buffer;
local.iov_len = bufferLen;
remote.iov_base = reinterpret_cast<void*>(0x603120);
remote.iov_len = bufferLen;
ssize_t bytesRead = process_vm_readv(pid, &local, 1, &remote, 1, 0);
std::cout << reinterpret_cast<long>(local.iov_base) << std::endl;
}
I have used objdump to find that the correct address of 'val' is 0x603120. I also printed out the address of it and tried the same, just to be sure.
I expect to print out 0xDEADBEEF (well the base 10 version of it) but what happens is that it prints out different values every time 'reader' is called, even when running it against the same 'main' program; the 'main' program shouldn't have anything in .data changing since it is just waiting for input so I am confused what I am doing wrong.
With std::cout << reinterpret_cast<long>(local.iov_base) << std::endl;
, you actually print out the address of buffer, which is why it looks like random value.
This should solve your problem
std::cout << *reinterpret_cast<long*>(local.iov_base) << std::endl;
User contributions licensed under CC BY-SA 3.0