程序可以直接分配内存吗?

时间:2010-04-11 05:25:41

标签: security memory programming-languages

是否有任何真正的低级编程语言可以直接访问内存变量?例如,如果我有一个程序有一个变量i。任何人都可以访问内存以将我的程序变量i更改为其他值吗?

5 个答案:

答案 0 :(得分:7)

作为如何从“外部”更改程序中的变量的示例,请考虑使用调试器。示例程序:

$ cat print_i.c
#include <stdio.h>
#include <unistd.h>

int main (void) {
    int i = 42;
    for (;;) { (void) printf("i = %d\n", i); (void) sleep(3); }
    return 0;
}
$ gcc -g -o print_i print_i.c
$ ./print_i
i = 42
i = 42
i = 42
…

(程序每隔3秒打印i的值。)

在另一个终端中,找到正在运行的程序的进程ID并将gdb调试器附加到它:


$ ps | grep print_i
 1779  p1  S+     0:00.01 ./print_i
$ gdb print_i 1779
…
(gdb) bt
#0  0x90040df8 in mach_wait_until ()
#1  0x90040bc4 in nanosleep ()
#2  0x900409f0 in sleep ()
#3  0x00002b8c in main () at print_i.c:6
(gdb) up 3
#3  0x00002b8c in main () at print_i.c:6
6           for (;;) { (void) printf("i = %d\n", i); (void) sleep(3); }
(gdb) set variable i = 666
(gdb) continue

现在程序的输出发生了变化:

…
i = 42
i = 42
i = 666

所以,是的,如果您有权访问其内存,则可以从“外部”更改程序的变量。这里有很多警告,例如人们需要找到变量存储的位置和方式。这很简单,因为我用调试符号编译了程序。对于任意语言的任意程序来说,它要困难得多,但理论上仍然可行。当然,如果我不是正在运行的进程的所有者,那么一个表现良好的操作系统将不允许我访问其内存(没有“黑客”),但这是另一个问题。

答案 1 :(得分:4)

当然,除非操作系统代表您保护该内存。机器语言(最低级编程语言)总是“直接访问内存”,并且在C中很容易实现(例如,通过将某种整数转换为指针)。重点是,除非此代码在您的进程(或内核)中运行,无论它编写什么语言,操作系统通常都会保护您的进程免受此类干扰(例如,通过以不同方式为不同进程映射内存)。 / p>

答案 2 :(得分:1)

如果其他进程具有足够的权限,则可以更改进程的内存。在Linux上,它就像读取和写入伪文件/proc/{pid}/mem一样简单。这是有多少漏洞可用,但它们确实依赖于一些漏洞,允许它们以非常高的权限运行(Unix上的root用户)。

答案 3 :(得分:1)

简短回答:是的。答案很长:它取决于很多因素,包括您的硬件(内存管理?),您的操作系统(受保护的虚拟地址空间?绕过这些保护的功能?)以及您的对手可能会或可能没有您的语言的详细知识架构和您的应用程序结构。

答案 4 :(得分:0)

这取决于。通常,操作系统的一个功能称为分段 - 这意味着将程序保持在彼此的内存之外。如果我编写一个试图访问属于你的程序的内存的程序,操作系统应该让我崩溃,因为我提交了一个叫做分段错误的东西。

但有些情况我可以解决这个问题。例如,如果我在系统上拥有root权限,我可以访问你的内存。或者更糟 - 我可以在虚拟机中运行你的程序,然后坐在那个VM之外,做我想做的任何内存。

所以一般来说,你应该假设一个恶意的人如果努力了就可以进入你的程序并调整你的记忆。