Что находится выше 0x1000? В поле AddressOfEntryPoint опционального заголовка exe-файла находится значение 0x1000 - RVA первой инструкции. Что проецируется в память выше, на RVA 0x0-0x0FFF? И почему начало кода находится именно там? (BaseOfCode менял вручную - первая инструкция (и остальные, соответственно) адрес не меняет) Еще вопрос: участвует ли значение базы кода при выполнении инструкций в моей секции кода, или она необходима только для вычисления адреса перехода на внешних функций (в частости WinAPI)?
Выше адреса 0x1000. Под PE заголовок выделяется 4 Кб? Почему так много? Или это связано со страничной адресацией? Что такое релоки?
gh05t Не совсем. Напрямую это связано с полем SectionAlignment. Заголовок и все секции выравниваются в памяти на это значение. На винчестере они выравниваются на значение FileAlignment. Не забывайте не смешивать понятия адреса (абсолютного адреса, VA) и смещения (RVA). Поле BaseOfCode никакого значения не играет. Если речь не о поле BaseOfCode, а именно о базе загрузки кода, то может участвовать. Например, если в коде объявлены определённые данные, на которые ссылаются инструкции этого кода. К тому же теоретически (на практике редко) возможны также и прямые абсолютные прыжки/вызовы. А вот тут Вы неправы. Переход на внешние функции по стандартному сценарию не зависит и не определяется базой загрузки кода. Загрузчик заполняет IAT, к которой уже в свою очередь идёт обращение из кода через абсолютную адресацию. Т.е. важна база загрузки IAT, а не самого кода. Таблица поправок, позволяющая загрузчику разместить PE в памяти по удобному ему адресу, при необходимости отличающемуся от содержимого поля ImageBase. Практически жизненно необходима для DLL и довольно редко используется для EXE. Указатель на эту таблицу хранится в соответствующем поле таблицы с DataDirectory. А вообще почитайте статьи на сайте по этой теме. Это ИМХО лучшая, но не единственная. MSoft Интересно... Всегда думал, что в Европе люди читают и пишут слева направо и сверху вниз. Соответственно младшие адреса будут находиться именно выше. Хотя по сути это на вкус и цвет.
[offtop] _basmp_ Насколько мне известно и считают (хотя что есть "считают"? Это как раз и есть читают/пишут) тоже слева направо и сверху вниз: 0,1,2,3,4, ... или: 0000: 0001: 0002: 0003: и т.д. Но, как я уже сказал, это на вкус и цвет. Единственное что... по умолчанию, исходя именно из вышеуказанных соображений, логично считать, что младшие адреса выше. P.S. Мне вообще интересно, откуда такое мнение взялось, что младший адрес должен быть ниже. Не припомню ни одного отладчика, дизассемблера или HEX-редактора, который бы младшие адреса ниже старших показывал. [/offtop]
l_inc хорошо хорошо. Как скажете. Меньшие цифры - выше, а я для счета впредь буду запускать отладчик (или представлять его?), если не забуду. Тут нет повода для спора.
l_inc Я говорил об RVA. Спасибо за ответ, статью обязательно прочту. И все таки, где используется значение поля BaseOfCode, если адрес загрузки секции кода определяется в таблице секций?
gh05t Практически нигде, если не считать некоторые нерадивые программы, работающие с PE (антивирусы, отладчики и т.п.). Видимо, раньше использовалось загрузчиком.
Кое что проясняется... Небольшой практический вопрос: как работать с массивом DataDirectory в masm? Описание структуры следующее: Код (Text): IMAGE_OPTIONAL_HEADER32 STRUCT Magic WORD ? . . . NumberOfRvaAndSizes DWORD ? DataDirectory IMAGE_DATA_DIRECTORY IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup(<>) IMAGE_OPTIONAL_HEADER32 ENDS Адрес начала IMAGE_OPTIONAL_HEADER32 хранится в esi. Можно ли сделать что то вроде [esi].DataDirectory[ecx].VirtualAdress, где ecx перечисляет все доступные индексы? Или только вручную увеличивая адрес в esi?
mov eax, dword ptr [esi+ecx*8+IMAGE_DATA_DIRECTORY.VirtualAdress] чото типа этого.. вообще есть в масме assume, но как сторонник фасма, не помню уже как заюзать.
А без assume через точку (например, [esi].AddressOfEntryPoint) к полям структуры и не получится обратиться. Или assume еще для чего то нужен?
gh05t в масме получится и через точку [esi].IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSizes, но с assume удобнее assume esi: ptr IMAGE_OPTIONAL_HEADER32 ... [esi].NumberOfRvaAndSizes ... [esi].xxx ... другие поля структуры assume esi: nothing assume это директива компилятора и нужна только чтобы не писать каждый раз имя структуры кода ана никакого не генерирует.