Почему вы не можете получить доступ к адресному пространству другого процесса, начиная с Windows 95? - PullRequest
7 голосов
/ 05 ноября 2011

Скажем, я посылаю указатель в качестве аргумента другой программе:

program.exe -mypointer

и попробуйте использовать его в этой программе, он не будет работать. После некоторых исследований (например, в Lounge C ++) я обнаружил, что, начиная с Windows 95, вы не можете получить доступ к адресному пространству другой программы. В старых версиях Windows это было разрешено. Мой вопрос: почему Microsoft запретила это? Каковы были проблемы или недостатки этого?

P.S. Возможно ли все-таки обойти это в новых версиях Windows?

Ответы [ 5 ]

14 голосов
/ 05 ноября 2011

Поскольку возможность доступа к адресному пространству других процессов означает, что вы можете аварийно завершить их, например, путем случайного изменения содержимого их памяти.

Целая точка защищенного режимазащищать процессы друг от друга.См. Страницу защиты памяти для более подробной информации.В старые добрые времена, предшествовавшие защите, было намного проще писать код, который работал с другими процессами.

Недостатком этого было то, что некоторым ошибкам в MS Word было гораздо проще не просто аварийно завершить работу.MS Word, а также Excel, Borland C, калькулятор цифр PI, который работал последние шесть недель, и даже сама операционная система.

Вы все еще можете получить доступ к другому процессуадресное пространство, но для этого вам нужно работать с более высокими привилегиями.Например, именно так отладчики позволяют вам запускать процесс и получать доступ ко всей его памяти для целей отладки.

Вызовы ReadProcessMemory и WriteProcessMemory позволяют вам сделать это, наряду со многими другими функции отладки .

9 голосов
/ 05 ноября 2011

16-битная Windows сделала некоторые действительно удивительные подвиги управления памятью, но это было затруднено тем, что она была разработана для процессора без управления памятью, а именно i8086 оригинального ПК (аппаратные средства могут не совпадать с тем, что оригинальный ПК использовал i8088 который был идентичен, за исключением ширины шины данных).

Итак, в 16-битных процессах Windows общий доступ к памяти одинаков.

Одна из проблем заключается в том, что общее адресное пространство памяти не так уж велико, на самом деле, когда многочисленные процессы хотят иметь свои собственные куски.

Кроме того, процессы могут слишком легко споткнуться о ноги друг друга.

Windows предложила некоторые частичные решения, такие как возможность для процесса информировать Windows о том, когда она фактически использует некоторую память (процесс затем «заблокирует» эту область памяти), что означало, что Windows может перемещать содержимое памяти в освободите место, когда это необходимо, но все это было добровольно и не очень безопасно.

Итак, 32-битная Windows, Windows NT, использовала управление памятью более нового процессора, чтобы автоматизировать лучшие практики, которые должны были использовать 16-битные программы Windows. По сути, процесс имеет дело только с логическими адресами , которые процессор автоматически преобразует до физических адресов (которые процесс никогда не видит). Что ж, на 32-битном ПК перевод выполняется в два этапа, т. Е. Есть внутренняя промежуточная форма адреса, но это сложность, о которой вам не нужно знать.

Одним приятным следствием этой аппаратно-поддерживаемой трансляции адресов является то, что процесс может быть полностью изолирован от знания того, какие физические адреса он использует. Например, легко иметь два процесса в одной программе. Они думают, что имеют дело с одними и теми же адресами, но это только логические адреса; на самом деле их логические адреса преобразуются в разные физические адреса, чтобы они не топали области памяти друг друга.

И одно последствие, которое мы с 20-20 лет назад можем сказать, не очень приятно, это то, что схема перевода позволяет виртуальную память , например. моделировать оперативную память с использованием дискового пространства. Windows может скопировать содержимое памяти на диск, а затем использовать эту область физической памяти для чего-то другого. Когда процесс, который использовал эту область памяти, записывает или читает из нее, Windows выполняет некоторую неистовую деятельность, чтобы загрузить данные обратно с диска в некоторую область памяти (может быть той же или другой) и отобразить логические адреса процесса там. Результатом этого является то, что в условиях низкой памяти ПК превращается из электронного зверя в механического зверя, выполняя затухание в тысячи и миллионы раз. Нехорошо - но когда размеры оперативной памяти были небольшими, люди думали, что виртуальная память аккуратна.

Основная проблема с виртуальной памятью в современной Windows заключается в том, что на практике практически невозможно отключить эту чертову штуку. Даже если запущена только одна «основная» программа и доступно гораздо больше, чем достаточно физической ОЗУ, Windows будет активно обмениваться данными на диск, чтобы подготовиться к ним, когда, возможно, этому процессу понадобится еще больше логической памяти. Однако, если бы это было исправлено, то, скорее всего, вместо него появилось бы что-то еще; Такова природа Вселенной.

Приветствия и hth.,

6 голосов
/ 05 ноября 2011

Ваша предпосылка неверна. Вы наверняка можете прочитать память другого процесса в Windows. Вы просто не можете сделать это разыменованием указателя, потому что у каждого процесса свой взгляд на память. Это необходимо по ряду причин, но наиболее важной из них является предотвращение повреждения одной исполняемой программы другими исполняемыми программами. (Еще один способ - предотвратить дефицит адресного пространства.)

4 голосов
/ 05 ноября 2011

Ты говоришь так, будто считаешь, что защита памяти - это плохо !?

Неконтролируемый доступ к памяти одного процесса из другого обычно приводит к ошибкам, сбоям, неопределенному поведению и, что более критично, может стать открытой дверью для вредоносных программ и вирусов.Вы можете написать два процесса, которые хорошо взаимодействуют через разделяемую память, но в равной степени любой другой процесс либо по ошибке, либо злонамеренно может получить к нему доступ.Более того, было бы очень просто уничтожить само ядро ​​ОС.

Win16 изначально работал как графическая среда, а не как настоящая ОС поверх MS-DOS, и был разработан для работы на ранних 16-битных процессорах x86 безMMU для защиты памяти.Win32S API был введен позже в Windows 3.x, которая предоставляла подмножество функций Win32 на Win16.Windows32 (первоначально Windows NT, а затем Windows 95) использует преимущества функций, представленных в 80386, для обеспечения каждого процесса своей собственной средой памяти, невидимой для других, кроме как по приглашению.

Это то, что сделало Windows NT более надежной, чемWin3.x.Windows 95 не в полной мере использовала механизмы защиты, предположительно для некоторой обратной совместимости, поэтому, будучи более надежным, чем Win3.x, она не была почти такой же защищенной от сбоев, как NT.Windows XP была первой «потребительской» ОС Windows, которая использовала кодовую базу Windows NT / Windows 2000 и выбрасывала большую часть (но не все) багажа, совместимого с Windows 95 / MS-DOS.

Если вы хотитеделить данные между процессами правильно, используя любой признанный механизм IPC .Один из таких методов на самом деле заключается в отображении файла памяти, который является в точности блоком общей памяти, но с элементами управления доступом, поэтому не только любой процесс может видеть память.

2 голосов
/ 05 ноября 2011

Хорошо, если вы можете возиться в области оперативной памяти других процессов, легко сломать его.Например, вам просто нужно установить указатель на NULL, и процесс исчезнет.И, конечно же, ОЗУ являются «частными» частями каждого процесса, и вы не хотите, чтобы кто-то имел к ним доступ, не так ли?Да, есть некоторый способ получить к нему доступ, если вы выполните отладку ядра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...