ВА (виртуальный адрес) и RVA (относительный виртуальный адрес)

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

Аннотация от "Microsoft Portable Executable и Спецификации Общего формата объектных файлов"

RVA (относительный виртуальный адрес). В файле изображения, адресе объекта после того, как это загружается в память с базовым адресом файла изображения, вычтенного из него. RVA объекта почти всегда отличается от своего положения в файле на диске (указатель файла).

В объектном файле RVA менее значим, потому что ячейки памяти не присвоены. В этом случае RVA был бы адресом в разделе (описанный позже в этой таблице), к которому перемещение позже применяется во время соединения. Для простоты компилятор должен просто установить первый RVA в каждом разделе для обнуления.

ВА (виртуальный адрес). То же как RVA, за исключением того, что базовый адрес файла изображения не вычтен. Адрес называют œVA†â€? потому что Windows создает отличное пространство ВА для каждого процесса, независимого от физической памяти. Почти во всех целях ВА нужно считать просто адресом. ВА не так предсказуем как RVA, потому что загрузчик не мог бы загрузить изображение в своем предпочтительном местоположении.

Даже после чтения этого, я все еще не получаю его. У меня есть партия вопросов. Может любой объяснять это практическим способом. Придерживайтесь терминологии Object File & Image File как указано.

Все, что я знаю об адресах, это

  • Ни в Объектном файле, ни в Файле изображения, мы не знаем местоположения хорошей памяти так,
  • Ассемблер при генерации Объектного файла вычисляет адреса относительно разделов .data & .text (для имен функций).
  • Компоновщик, берущий несколько объектных файлов в качестве входа, генерирует один Файл изображения. При генерации это сначала объединяет все разделы каждого объектного файла и в то время как слияние его повторно вычисляет смещения адреса снова относительно каждого раздела. И, нет ничего как глобальные смещения.

Если существует некоторая вещь неправильно в том, что я знаю, исправьте меня.

Править:

После того, чтобы читать ответ, данный Francis, я соглашаюсь с тем, что является Physical Address, VA & RVA и что является отношением между ними.

RVAs всего variables&methods должен быть вычислен Компоновщиком во время перемещения. Так, (значение RVA метода/переменной) == (его смещение с начала файла)? должен верный. Но удивительно, нет.Как же так?

Я проверил это при помощи PEView на c:\WINDOWS\system32\kernel32.dll и найденный, что:

  1. RVA & FileOffset - то же до начала Разделов. (.text первый раздел в этом dll).
  2. С начала .text через .data,.rsrc до последнего байта последнего раздела (.reloc) RVA & FileOffset отличается. И также RVA первого байта первого раздела "всегда" показывают как 0x1000
  3. Интересная вещь состоит в том, что байты каждого раздела непрерывны в FileOffset. Я подразумеваю, что другой раздел начинается на уровне следующего байта последнего байта раздела. Но если я вижу то же самое в RVA, это огромный разрыв промежуточный RVAs последнего байта раздела и первого байта следующего раздела.

Мое предположение:

  1. Все, байты данных, которые были перед первым (.text здесь) раздел на самом деле не загружается в пространство ВА процесса, эти байты данных просто используются, чтобы определить местоположение и описать эти разделы. Их можно назвать, "meta разделяют данные".

    Так как они не загружаются в пространство ВА процесса. использование термина RVA также бессмысленно, это - причина почему RVA == FileOffset для этих байтов.

  2. С тех пор,

    • Термин RVA допустим только для тех байтов, которые будут на самом деле загружены в пространство ВА.
    • байты .text, .data, .rsrc, .reloc такие байты.
    • Вместо того, чтобы начать с RVA 0x00000 Программное обеспечение PEView запускает его с 0x1000.
  3. Я не могу понять почему 3-е наблюдение. Я не могу объяснить.

47
задан Cœur 16 April 2017 в 07:02
поделиться

2 ответа

Большинство процесса Windows (* .exe) загружаются в (пользовательский режим) адрес памяти 0x00400000, вот что мы называем «виртуальный адрес» (VA) - потому что они видны только для каждого процесса и будет преобразован в различные физические адреса ОС (видимым на уровне ядра / драйвера).

Например, возможный адрес физической памяти (видимый CPU):

0x00300000 on physical memory has process A's main
0x00500000 on physical memory has process B's main

и ОС может иметь таблицу сопоставления:

process A's 0x00400000 (VA) = physical address 0x00300000
process B's 0x00400000 (VA) = physical address 0x00500000

, затем, когда вы пытаетесь прочитать 0x004000000 в процессе A, вы получите контент который расположен на 0x00300000 физической памяти.

Относительно RVA, это просто предназначено для облегчения перемещения. При загрузке перемещенных модулей (например, DLL) система постарается сдвинуть его через пространство процесса памяти. Таким образом, в макете файлов он ставит «относительный» адрес, чтобы помочь вычислению.

Например, DLL C может иметь этот адрес:

 RVA 0x00001000 DLL C's main entry

при нагрузке в процесс A при базовом адресе 0x10000000, основной вход C становится

 VA = 0x10000000 + 0x00001000 = 0x10001000
 (if process A's VA 0x10000000 mapped to physical address was 0x30000000, then 
  C's main entry will be 0x30001000 for physical address).

, когда его загружаются в процесс B при базовом адресе 0x32000000, главная запись C

 VA = 0x32000000 + 0x00001000 = 0x32001000
 (if process B's VA 0x32000000 mapped to physical address was 0x50000000, then 
  C's main entry will be 0x50001000 for physical address).

Обычно RVA в файлах изображений относительно обработки базового адреса при нагрузке в память, но некоторая RVA может быть относительно адреса «раздела» в начальном адресе в изображениях или объектах (вы должны проверить спецификацию формата PE для деталей ). Неважно, что RVA относительно «какая-то» базы VA.

Для суммирования

  1. Адрес физической памяти - это то, что CPU видит
  2. Virtual Addreess (VA) относительно физического адреса, на процесс (управляется ОС)
  3. RVA относится к VA (файловая база или раздел База), на файл (управляется линкером и погрузчиком)

(редактирование), касающиеся нового вопроса Claw:

значение RVA метода / переменной не всегда его смещение от начала файла. Они обычно относительны к некоторым VA, что может быть базовым адресом по умолчанию по умолчанию или раздел Base VA - вот почему я говорю, что вы должны проверить спецификацию формата .

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

Что касается ваших догадок, они очень близки к правильным ответам:

  1. Обычно мы не будем обсуждать «RVA» перед разделами, но заголовок PE все равно будет загружен до конца заголовков секции. Зазор между заголовком раздела и корпусом секции (если таковая имеется) не будет загружена. Вы можете изучить это отладчиками. Тофоре, когда между разделами есть разрыв между разделами, они могут быть не загружены.

  2. Как я уже сказал, RVA - это просто «относительно некоторого VA», независимо от того, что VA есть (хотя при разговоре о PE, VA обычно относится к базу нагрузки). Когда вы читаете спецификацию Формата Thet PE, вы можете найти некоторую «RVA», которое относительно некоторого специального адреса, такого как адрес для начала ресурсов. Список PEView RVA от 0x1000 заключается в том, что этот раздел начинается с 0x1000. Почему 0x1000? Поскольку линкер слева от 0x1000 байтов для заголовка PE, поэтому RVA начинается с 0x1000.

  3. То, что вы пропустили, - это концепция «раздела» в стадии погрузки PE. PE может содержать несколько «разделов», каждая секция отображается на новый запуск VA. Например, это сброшено из Win7 Kernel32.dll:

     # Name Virtsize RVA Phangsize Offset
    1 .text 000C44C1 00001000 000C4600 00000800
    2 .DATA 00000FEC 000C6000 00000E00 000C4E00
    3 .rsrc 00000520 000C7000 00000600 000C5C00
    4 .Reloc 0000B098 000C8000 0000B200 000C6200
     

    Существует невидимый «0 заголовок RVA = 0000, размер = 1000», который заставил .Text начать на RVA 1000. Разделы должны быть непрерывными при нагрузке в память (I.E., VA), поэтому их RVA является непрерывным. Однако, поскольку память выделяется страницами, она будет несколько размеров страницы (4096 = 0x1000 байтов). Вот почему раздел № 2 начинается при 1000 + C5000 = C6000 (C5000 поставляется из C44C1).

    Для того, чтобы обеспечить сопоставление памяти, эти разделы все еще должны быть выровнены некоторыми размерами (размер выравнивания файлов - решить по линкеру. В моем примере выше это 0x200 = 512 байт), который контролирует поле Physsize. Смещение означает «компенсирование для начала файла PE PE PE».

    Итак, заголовки занимают 0x800 байтов файла (и 0x1000 при сопоставлении к памяти), что является смещением раздела № 1. Затем, выравнивая свои данные (байты C44C1), мы получаем Physsize C4600. C4600 + 800 = C4E00, который именно смещение второго сечения.

    Хорошо, это связано с целыми загрузками PE, так что может быть немного трудно понять ...

(редактировать) Позвольте мне снова сделать новое простое резюме.

  1. Файлы «Формат RVA» в DLL / EXE (PE) обычно относится к «адресу базы нагрузки в памяти» (но не всегда - вы должны прочитать спецификацию)
  2. Формат PE содержит «раздел» Структура сопоставления для отображения содержания физического файла в память.Таким образом, RVA на самом деле не относится к смещению файла.
  3. Чтобы рассчитать RVA некоторых байтов, вы должны найти его смещение в разделе и добавить секционную базу.
62
ответ дан 26 November 2019 в 19:47
поделиться

Относительный виртуальный адрес - это смещение с адреса, на котором загружен файл. Вероятно, самый простой способ получить идею с примером. Предположим, у вас есть файл (например, DLL), который загружен по адресу 1000h. В этом файле у вас есть переменная в RVA 200H. В этом случае VA этой переменной (после того, как DLL сопоставлен на память) составляет 1200 ч (то есть базовый адрес 1000 часов dll Plus 200h RVA (смещение) в переменной.

11
ответ дан 26 November 2019 в 19:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: