只是一个杂项问题。
我有一个 C++ 程序:
#include <stdio.h>
int main()
{
while (1) {
int value1 = 1;
printf("%p\n", (void *)&value1);
void* address = (void *)&value1;
int value2 = *(int*)address;
printf("%d\n",value2);
}
return 0;
}
它的作用是获取 value1 的地址,将其存储在 address 中,然后获取 address 中的变量并将其存储在 value2 中。这工作得很好,但是,我想从另一个 C++ 程序访问变量。我试过这个(这个文件中有两种方法):
#include<iostream>
#include <cstdint>
int main() {
std::cout << "before seg fault" << std::flush;
uintptr_t p = <address>;
int value = *reinterpret_cast<int *>(p);
int value2 = *(int*)<address>;
std::cout << "after seg fault"<< std::flush;
std::cout << value;
return 0;
}
这会在尝试访问该值时导致段错误,这可能是因为操作系统不希望我访问该值,或者因为它在此实例中不存在。无论这看起来多么不切实际和愚蠢,有没有办法克服这个问题?或者是不可能的?作为旁注,为什么应该/为什么我不应该这样做?
编辑:我已经批准了 Chris 的回答,因为当你在 linux 上使用 root 运行它时它工作得很好。要求同样适用于 Mac 和 Windows 的东西会不会太过分了?我曾尝试在 Mac 系统上运行 poke 程序,但它给出了错误:无法访问 pid 26112::No such file or directory,由行调用:
fprintf(stderr, "usage: %s pid address value\n", av[0]);
最佳答案
每个进程都有自己的地址空间,程序中的地址引用该地址空间,与任何其他地址空间中的地址无关。因此,当您将显式值放入这样的指针并使用它时,您将获得此进程中该地址的任何内容(这可能是无效的,因此您会收到 SEGFAULT 或类似错误),而不是访问其他进程.
在大多数操作系统上,有一些方法可以访问另一个进程的地址空间,但需要获得许可。例如,在 Linux 上,这个 poke
程序可以修改另一个进程的地址空间:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
int main(int ac, char **av) {
char name[64];
int fd;
if (ac != 4) {
fprintf(stderr, "usage: %s pid address value\n", av[0]);
exit(1); }
sprintf(name, "/proc/%.10s/mem", av[1]);
if ((fd = open(name, O_WRONLY)) < 0) {
fprintf(stderr, "Can't access pid %s", av[1]);
perror(":");
exit(1); }
lseek(fd, strtol(av[2], 0, 0), SEEK_SET);
if (write(fd, av[3], strlen(av[3]) + 1) < 0)
perror("write");
return 0;
}
如果你然后运行这个程序:#include <stdio.h>
#include <unistd.h>
int main() {
char data[16] = "test";
while (1) {
printf("pid = %d, &data = %p, data = %s\n", getpid(), &data, data);
sleep(2);
}
}
它将打印如下所示的行:pid = 6376, &data = 0x7ffe255f3190, data = test
pid = 6376, &data = 0x7ffe255f3190, data = test
如果你运行 ./poke 6376 0x7ffe255f3190 Hello
在另一个窗口/终端中,它将更改为pid = 6376, &data = 0x7ffe255f3190, data = Hello
pid = 6376, &data = 0x7ffe255f3190, data = Hello
关于c++ - 如果你知道地址,你能访问另一个程序的堆栈/堆吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68866194/