Process_vm_readv Returning Random Values

0

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.

c++
linux
memory

1 Answer

0

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;

answered on Stack Overflow Feb 26, 2021 by Bui Quang Minh

User contributions licensed under CC BY-SA 3.0