【问题标题】:C++ read/write to array out of boundsC ++读/写数组越界
【发布时间】: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 时,程序会出现段错误,我猜这大约是为我的程序分配的内存大小。这让我想到了我的问题,这是三个方面的:

  1. 是什么阻止我继续读取(而不是写入)超出此范围的值?这是防止阅读系统特定的吗?特定于编译器?

  2. 如果我能巧妙地操作指针,我是否可以在程序范围之外读取或写入值(显然,不能直接/正常访问这些值)?

  3. 我在虚拟机上运行所有这些。我可以访问主机上的读/写内存值吗? (如果 (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。美好时光!
  • Usermodeuserspace 是程序运行的模式。它们通常在受限环境中运行(例如,无法访问硬件或其他进程的内存)并且必须与操作系统通信。相比之下,kernelspace 是内核运行的模式。它可以完全访问硬件。 (根程序在内核模式下执行;它们是用户模式应用程序,操作系统将授予所有权限。只有内核代码可以在内核模式下运行)

标签: c++ pointers memory


【解决方案1】:
  1. 操作系统。操作系统仅将一定范围的虚拟地址映射到物理地址。到达映射的虚拟地址范围的末尾后,尝试访问不存在的虚拟地址会生成SIGSEGV

  2. 没有。至少在任何现代操作系统上都没有。

  3. 除非您能在主机操作系统的虚拟机中找到错误并加以利用,否则不会。

【讨论】:

    猜你喜欢
    • 2019-05-03
    • 2012-10-28
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多