Страницы

Поиск по вопросам

воскресенье, 8 марта 2020 г.

Виртуальная память процесса в windows, что из неё видно и как меняются адреса?

#windows #память #pe


Вопрос по загрузке PE и распределению в адресов в режиме пользователя.
Насколько я знаю, PE-секции выгружаются в общую для всех пользовательских программ
область, в зависимости от доступности, и адреса задаются при загрузке в память, но
тут вопрос - как происходит адресация внутри программы, раз мы не меняя кода получаем
работоспособную программу и при этом можем через ту же память обращаться в адресное
пространство других процессов? К примеру, у меня в программе по адресу 0x1 лежит mov
ax,bx и когда происходит jmp 0x1 он перекидывает меня именно в мою программу, а не
в чужую, при этом я могу прочитать тот же 0x1 другой программы как?
И как бы мне выцепить user32 и kernel32 без таблицы импорта, но из своего pe-файла?
И чего там ещё интересного можно найти?
    


Ответы

Ответ 1



Насколько я знаю PE-секции выгружаются в общую для всех пользовательских программ область в зависимости от доступности и адреса задаются при загрузке в память Так было до Windows 3.1 включительно, когда виртуальной памяти попросту не существовало, и разделение производилось по отовсюду доступным сегментам. В современных же операционных системах каждый процесс находится в собственном, изолированном адресном пространстве («песочнице»). Согласен, если файл (в том числе исполняемый) отображается в несколько процессов в режиме только на чтение и без каких-либо изменений, то операционная система может (но не обязана) сэкономить немного ОЗУ и отобразить соответствующие страницы виртуальной памяти этих процессов в один и тот же регион памяти физической. Однако это всего лишь трюк на уровне отображения виртуальной памяти на физическую силами железа. С точки зрения самих программ никакого общего региона не существует. к примеру у меня в программе по адресу 0x1 лежит mov ax,bx и когда происходит jmp 0x1 он перекидывает меня именно в мою программу а не в чужую Перед тем, как переключить выполнение на какой-либо поток вашего процесса, операционная система производит определённую донастройку процессора. В частности, она извлекает из своих внутренних структур физический адрес карты отображения памяти и передаёт его специальному блоку процессора, мапперу. Маппер же использует указанную карту примерно следующим образом: (Иллюстрация взята из ответа на вопрос «Какую модель памяти сегментную или страничную использует windows, linux, macos?») при этом я могу прочитать тот же 0x1 другой программы как? Надо попросить операционную систему не выделять пустую страницу, как она это обычно делает, а создать привязку к уже существующей странице. Иными словами, как бы прорубить окно в чужое адресное пространство. Однако отображаемый блок не должен накладываться на уже занятый регион виртуальной памяти вашего процесса. С другой стороны, это окно можно создать в любом месте памяти вашей программы. Для этого необходимо вызвать системную функцию MapViewOfFileEx(), указав целевой процесс и адрес в его виртуальной памяти. И как бы мне выципить user32 и kernel32 без таблицы импорта но из своего pe-файла? LoadLibrary() + GetProcAddress(). Всё остальное — хаки и ненадёжно.

Комментариев нет:

Отправить комментарий