2013-03-10 1 views
1

Несколько дней назад я начал играть в формате PE. Я сделал небольшой загрузчик PE, который может загружать разделы в память в соответствии с их виртуальными адресами. Например, у меня есть раздел .text по виртуальному адресу 0x1000, или раздел .data на 0x2000. С моим небольшим кодом сборки я загрузил файл PE на некоторое свободное место (0x10000), и я загрузил разделы PE из его позиций. Так, раздел .text на 0x11000 (0x10000 + 0x1000), .data на 0x12000 и т.д ... Но когда я ссылаться мои данные в сборке из .code месте, я обнаружил (в разборке), что это указывает на 0x402000. В Интернете я нашел что-то вроде базы изображений, которая специфична для каждого типа изображения ... Но я не понимаю, как может быть .exe, загруженный в 0x402000, когда есть много исполняемых файлов, запущенных в Windows, например. Кто-нибудь, почему это так, как это работает и как я могу теоретически реализовать его в моей самой базовой системе?Данные в исполняемом файле находятся в неизвестном положении

Пожалуйста, помогите.

ответ

3

Виртуальная память означает, что каждый отдельный процесс на вашем компьютере может использовать «одинаковые» адреса, поскольку адресные пространства каждого процесса независимы. 0x400000 для процесса A сопоставляется с другим физическим адресом, чем 0x400000 для процесса B операционной системой, даже если они представляют собой один и тот же виртуальный адрес (разные виртуальные адресные пространства).

По умолчанию базовый адрес для исполняемого файла - 0x400000. Ваш компоновщик жестко закодирует этот базовый адрес в исполняемом файле и соответствующим образом настроит адреса. Ваш исполняемый файл будет загружен по этому адресу при запуске программы. Ваш ассемблер или компоновщик должны дать вам способ изменить этот базовый адрес по умолчанию.

Обратите внимание, что библиотеки DLL, с другой стороны, должны быть загружены с уникальными адресами, потому что они должны сосуществовать в одном процессе. По этой причине DLL обычно являются relocatable, то есть они могут иметь любой базовый адрес при загрузке, чтобы справиться с требованием поместить их на уникальный адрес. (Наличие нескольких неперемещаемых DLL в системе может вызвать проблемы, но наличие нескольких неперемещаемых .exe в системе вообще не проблема).

+0

нормально, и как ОС, выполняющая эту обычную инструкцию по сборке, адресует другое местоположение? Как это возможно? – user35443

+0

Жаль, что все было неясно. Это функция компоновщика, а не ОС. Я обновил ответ. – nneonneo

+0

ОК, но все же. Если это не физический адрес, как ЦП знает, где он должен читать/писать байты с/на? – user35443

1

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

+2

Бесконечность до предела пространства VM, которое на самом деле не так уж и много для 32-битных процессов. – nneonneo

+0

ОК, и как ОС, выполняющая эту обычную инструкцию по сборке, адресует другое местоположение? Как это возможно? – user35443

+0

@ user35443 есть что-то, называемое рандомизацией макета адреса, которое загружает вещи по разному адресу каждый раз, когда загружается. –

3

Каждый исполняемый файл выполнен в собственном virtual address space. Таким образом, даже если два исполняемых файла имеют одну и ту же базу изображений 0x400000, они располагаются/используют другую физическую память. Подумайте об этом, так как база базы изображений отличается.

Чтобы получить базу изображений модуля, загруженного в ваш рабочий процесс, вы можете использовать GetModuleHandle. Он возвращает дескриптор модуля, который случайно равен основанию изображения. В качестве альтернативы вы можете получить базу изображений из поля ImageBase в структуре заголовков PE IMAGE_OPTIONAL_HEADER (see here).

+0

нормально, и как ОС, выполняющая эту обычную инструкцию по сборке, адресует другое местоположение? Как это возможно? – user35443