【发布时间】:2016-07-25 02:15:04
【问题描述】:
可能已经在某个地方找到了答案,但我找不到。
正如这个问题中所述:Accessing an array out of bounds gives no error, why?,C++ 不强制数组边界,而是选择提供未定义的行为。我担心的是这种行为的威力。
所以假设我写了一些简单的程序:
#include <iostream>
int main() {
int* a = new int[1];
long large_number = 9223372036854775807l; //2**63 - 1
for (long i = 0l; i < large_number; i++) {
std::cout << i << " " << a[i] << std::endl;
}
return 0;
}
这将继续打印存储在我的系统上的下一个 32 位数字(显然,假设是 32 位大小的整数)。当我在我的机器上运行它时,当我大约 30,000 时,程序会出现段错误,我猜这大约是为我的程序分配的内存大小。这让我想到了我的问题,这是三个方面的:
是什么阻止我继续读取(而不是写入)超出此范围的值?这是防止阅读系统特定的吗?特定于编译器?
-
如果我能巧妙地操作指针,我是否可以在程序范围之外读取或写入值(显然,不能直接/正常访问这些值)?
我在虚拟机上运行所有这些。我可以访问主机上的读/写内存值吗? (如果 (2) 为否,那么这也是一个否)。
请注意,我在带有 Windows 主机的 ubuntu 虚拟机上运行 g++ 5.3.1,没有 c++11。
另外,我认识到这个问题可能被认为是一个安全问题(读/写内存)。我当然没有恶意,但如果这是一个问题,请告诉我,我很乐意结束这个问题。
编辑:以下问题似乎相关且有趣: Accessing outside the memory allocated by the program. (Accessing other app's memory) 不过,对于程序是否可以在其虚拟内存空间之外读取似乎并没有达成共识。
【问题讨论】:
-
查找虚拟内存。现代操作系统中的每个进程都有自己的内存空间,其他进程(或虚拟机上的主机)的内存是不可见的。
-
好的,有道理。出于好奇,所有现代操作系统都使用虚拟内存管理吗?您可以让程序访问其虚拟内存空间之外的信息吗?我找不到太多共识...
-
除非你是内核(或者内核的实现中存在错误),否则你无权在用户模式下访问其他程序的内存空间。
-
如果你是超级用户,你几乎可以做任何你想做的事。例如,在 Linux 下,root 用户可以通过 /dev/mem 设备直接读取或写入物理 RAM。美好时光!
-
Usermode 或 userspace 是程序运行的模式。它们通常在受限环境中运行(例如,无法访问硬件或其他进程的内存)并且必须与操作系统通信。相比之下,kernelspace 是内核运行的模式。它可以完全访问硬件。 (根程序不在内核模式下执行;它们是用户模式应用程序,操作系统将授予所有权限。只有内核代码可以在内核模式下运行)