2010-04-11 51 views
6

有沒有真正的低級編程語言可以直接訪問內存變量?例如,如果我有一個程序有一個變量i。任何人都可以訪問內存來將我的程序變量i更改爲另一個值嗎?程序可以直接分配內存嗎?

回答

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 
… 

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

在另一個終端,找到正在運行的程序的進程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

如果另一個進程有足夠的權限,那麼它可以改變你的進程的內存。在Linux上,它就像讀取和寫入僞文件/proc/{pid}/mem一樣簡單。這是多少漏洞的工作,雖然他們依賴於一些漏洞,允許他們以非常高的權限運行(Unix上的root)。

+2

@Marcelo - 你似乎暗示'proc'文件系統是一個安全漏洞。事實上,安全漏洞是允許壞人獲得root權限的。 – 2010-04-11 06:01:21

+0

我完全同意@Stephen,這就是爲什麼我在我的回答中明確表達了這一點(「......他們確實依賴於某個漏洞......」)。 – 2010-04-11 06:40:42

4

當然,除非操作系統代表您保護內存。機器語言(最低級的編程語言)總是「直接訪問內存」,並且在C中很容易實現(例如,通過將某種整數轉換爲指針)。要點是,除非你的程序(或內核)中運行這些代碼,不管它寫入什麼語言,操作系統通常都會保護你的進程免受這種干擾(例如通過以不同方式爲不同進程映射內存)。

+1

你可能想看看那裏的各種調試API。您可能會對現實世界中「不安全」的「受保護」內存的安全程度感到驚訝。 – 2010-04-11 05:36:51

+0

@ttmrichter:重點不是安全,它的穩定性。 – 2010-04-11 05:41:00

+3

那些相同的調試API有時也會帶來穩定性問題。特別是當牛仔編碼器使用它們來解決設計問題時。 – 2010-04-11 05:57:22

1

簡答:是的。長的回答:它取決於很多因素,包括硬件(內存管理?),操作系統(受保護的虛擬地址空間?繞過這些保護的功能?)以及您的對手可能具有或可能不具備您的語言架構和您的應用程序結構。

0

這取決於。一般來說,操作系統的功能之一叫做分段 - 這意味着讓程序保持彼此的內存不變。如果我編寫一個試圖訪問屬於你的程序的內存的程序,操作系統應該會讓我崩潰,因爲我提交了一個名爲分段錯誤的問題。

但有些情況下我可以解決這個問題。例如,如果我擁有系統上的root權限,我可以訪問你的內存。或者更糟 - 我可以在虛擬機中運行程序,然後坐在該虛擬機外部並執行任何我想要的內存。

因此,一般情況下,如果有足夠的努力,你應該假設惡意的人可以進入並擺弄程序的內存。