首页 > 解决方案 > Process_vm_readv 返回随机值

问题描述

我正在尝试使用process_vm_readv系统调用从另一个 Linux 进程中读取值。尝试在已知位置读取幻数时,我收到一个随机值。

我曾尝试编写两个简单的程序,看看我是否可以让它工作,但我失败了。我检查了我的返回值,并且每次都成功,我只是将其省略以使代码更清晰。

主文件(读取)

const long val = 0xDEADBEEF;

int main(int argc, char** argv) {
    std::cin.get(); // keep process running so I can read from it
}

读者

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;
}

我用objdump发现'val'的正确地址是0x603120。我还打印了它的地址并尝试了同样的方法,只是为了确定。

我希望打印出 0xDEADBEEF (以及它的基本 10 版本),但发生的是每次调用 'reader' 时它都会打印出不同的值,即使针对同一个 'main' 程序运行它也是如此;“主”程序不应该在 .data 中进行任何更改,因为它只是在等待输入,所以我很困惑我做错了什么。

标签: c++linuxmemory

解决方案


使用std::cout << reinterpret_cast<long>(local.iov_base) << std::endl;,您实际上打印出缓冲区的地址,这就是它看起来像随机值的原因。

这应该可以解决您的问题
std::cout << *reinterpret_cast<long*>(local.iov_base) << std::endl;


推荐阅读