Есть ли какой-либо действительно низкоуровневый язык программирования, который может получить доступ переменная памяти непосредственно? Например, если у меня есть программа, имеют переменную i
. Может любой получать доступ к памяти для изменения моей переменной программы i
к другому значению?
В качестве примера того, как изменить переменную в программе «извне», рассмотрим использование отладчика. Пример программы:
$ 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 секунды.)
В другом терминале найдите идентификатор процесса запущенной программы и прикрепите 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
Итак, да, можно изменить переменную программы «извне», если у вас есть доступ к ее памяти. Здесь есть множество предостережений, например нужно определить, где и как хранится переменная. Здесь это было просто, потому что я скомпилировал программу с отладочными символами. Для произвольной программы на произвольном языке это намного сложнее, но все же теоретически возможно. Конечно, если бы я не был владельцем запущенного процесса, то операционная система с хорошим поведением не позволила бы мне получить доступ к своей памяти (без «взлома»), но это уже совсем другой вопрос.
Конечно, если, конечно, операционная система не защищает эту память от вашего имени. Машинный язык (язык программирования самого низкого уровня) всегда «обращается к памяти напрямую», и этого довольно легко добиться на C (например, путем преобразования какого-либо целого числа в указатель). Дело в том, что, если этот код не запущен в вашем процессе (или ядре), на каком бы языке он ни был написан, ОС обычно защищает ваш процесс от такого вмешательства (например, отображая память различными способами для разных процессов).
Если другой процесс имеет достаточные разрешения, он может изменить память вашего процесса. В Linux это так же просто, как чтение и запись псевдо-файла / proc / {pid} / mem
. Вот сколько эксплойтов работает, хотя они полагаются на некоторую уязвимость, которая позволяет им работать с очень высокими привилегиями (root в Unix).
Короткий ответ: да. Длинный ответ: это зависит от множества факторов, включая ваше оборудование (управление памятью?), вашу ОС (защищенные виртуальные адресные пространства? возможности обхода этих защит?) и детальное знание архитектуры языка и структуры приложения, которым может обладать или не обладать ваш оппонент.
Это зависит от обстоятельств. В общем, одна из функций операционной системы называется сегментация - это означает, что программы не должны лезть в память друг друга. Если я пишу программу, которая пытается получить доступ к памяти, принадлежащей вашей программе, ОС должна вывести меня из строя, поскольку я совершаю нечто, называемое segmentation fault.
Но есть ситуации, когда я могу обойти это. Например, если у меня есть привилегии root в системе, я могу получить доступ к вашей памяти. Или еще хуже - я могу запустить вашу программу внутри виртуальной машины, а затем сидеть вне этой виртуальной машины и делать с ее памятью все, что захочу.
В общем, вы должны предполагать, что злоумышленник может проникнуть в память вашей программы и поработать с ней, если очень постарается.