Что означает HIGHLOW в разобранном двоичном файле?

Я просто впервые использовал DUMPBIN и неоднократно вижу термин HIGHLOW в выходном файле:

BASE RELOCATIONS #7
11000 RVA,       E0 SizeOfBlock
...
3B5  HIGHLOW            2001753D  ___onexitbegin
3C1  HIGHLOW            2001753D  ___onexitbegin
...

Мне любопытно, что означает этот термин. Я не нашел ничего в Google или Stackoverflow по этому поводу.

2

Решение

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

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

  1. какая память должна быть изменена (поле «смещение»)
  2. какое значение необходимо для его перемещения (значение «дельта»)
  3. какие части перемещенных данных и значения дельты использовать (поле «тип»)

Вот некоторые возможные значения поля типа

  • HIGH — добавить старшее слово (16 бит) дельты к 16-битному значению со смещением
  • LOW — добавить нижнее слово delta к значению «offset»
  • HIGHLOW — добавить полную дельту к 32-битному значению в «смещении»

Другими словами, HIGHLOW type сообщает программе, что она выполняет исправление по смещению «offset» со страницы этого блока перемещения * и что существует двойное слово, которое необходимо изменить, чтобы иметь правильно работающий исполняемый файл.

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

Допустим, у вас есть эта инструкция в вашем коде:

section .data
message: "Hello World!", 0

section .code
...
mov eax, message
...

Вы запускаете ассемблер и сразу после него запускаете дизассемблер. Теперь ваш код выглядит так:

mov eax, dword [0x702000]

Вы сейчас любопытно, почему это 0x700000и когда вы смотрите в дамп файла, вы видите, что

ImageBase:      0x00700000

Теперь вы понимаете, откуда взялся этот номер, и вы готовы запустить исполняемый файл.
Загрузчик, который загружает исполняемые файлы в память и создает для них адресное пространство, обнаруживает, что память 0x700000 недоступен, и он должен поместить этот файл в другое место. Решает, что 0xf00000 будет в порядке и скопирует содержимое файла туда.

Но ваша программа была связана с работой только с данными о 0x700000 и у компоновщика не было возможности узнать, что его выходные данные будут перемещены. Из-за этого загрузчик должен делать свою магию. Это

  1. исчисляет дельта значение — старый адрес (база изображений) 0x700000 но хочет 0xf00000 (предпочтительный адрес). Вычитает одно из другого и получает 0x800000 в результате.
  2. добирается до .reloc раздел файла
  3. проверяет, есть ли еще одна страница (4 КБ данных) для перемещения. Если нет, то оно продолжается в направлении точки входа файла.
    4. для каждого перемещения для текущей страницы, это
  4. получает данные по смещению перемещения
  5. добавляет значение дельты (в виде состояний поля типа)
  6. помещает новое значение в смещение перемещения
  7. продолжается на шаге 3

Есть также больше типов записи перемещения, и некоторые из них зависят от архитектуры. Чтобы увидеть полный список, прочитайте «Формат исполняемых файлов Microsoft Common и Common Object File, раздел 6.6.2. Типы исправлений».

5

Другие решения

Здесь вы видите содержимое «Базовой таблицы перемещений» в исполняемых файлах Microsoft Windows.

Базовые таблицы перемещения необходимы в Windows для файлов DLL и являются необязательными для исполняемых файлов; они содержат информацию о расположении информации об адресе в файле EXE / DLL, которая должна обновляться, когда известен фактический адрес файла DLL в памяти (при загрузке библиотеки DLL в память). Windows использует информацию, хранящуюся в этой таблице, для обновления информации об адресе.

Таблица поддерживает разные типы адресов, в то время как присвоение имен зависит от Microsoft: ABSOLUTE (= dummy), HIGH, LOW, HIGHLOW, HIGHADJ и MIPS_JMPADDR.

Полное имя константы: «IMAGE_REL_BASED_HIGHLOW».

Тип «ABSOLUTE» обычно представляет собой фиктивную запись, вставляемую для обеспечения того, чтобы части таблицы были кратны 4 (или 8) байтам.

На процессорах x86 используется только тип «HIGHLOW»: он сообщает Windows о расположении абсолютного (32-битного) адреса в файле.

Некоторая справочная информация:

В вашем примере «База изображений» может быть 0x20000000, что означает, что файл EXE / DLL был скомпилирован для загрузки в адрес 0x20000000. По адресам 0x200113B5 (0x20000000 + 0x11000 + 0x3B5) и 0x200113C1 имеются абсолютные адреса.

Допустим, память в ячейке 0x200113B5 содержит значение 0x20012345, которое является адресом функции или переменной в программе.

Возможно, память по адресу 0x20000000 не может быть использована, и Windows решает вместо этого загрузить DLL в память по адресу 0x50000000. Затем 0x20012345 должен быть заменен на 0x50012345.

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

2

По вопросам рекламы [email protected]