Почему дельта при релокации разная? (переходники на импорт)

Тема в разделе "WASM.WIN32", создана пользователем Bitfry, 5 мар 2008.

  1. Bitfry

    Bitfry New Member

    Публикаций:
    0
    Регистрация:
    11 авг 2004
    Сообщения:
    54
    Адрес:
    Россия, Санкт-Петербург
    Для того чтобы дописать библиотеку обработки релоков, мне нужно понять один вопрос, над которым бьюсь уже 2 дня.
    Итак, есть одна простейшая библиотека в качестве примера (testRelocDLL.dll).
    В ней всего 2 релока.
    Есть процесс (testdll.exe) в котором будет 2 копии этой библиотеки (testRelocDLL.dll и testRelocDLL2.dll). Первая копия в импорте и мапится по оригинальному ImageBase (IB) (у меня, по крайней мере, с этим нет проблем), вторая копия добавляется через LoadLibrary (в моём случае она всегда мапится по смещению меньше IB (будем звать его Actual). Снимаю 2 дампа с этих копий (разумеется, после релокации).
    Сравниваю... и не понимаю, почему цель второго релока (по смещению 434h) во втором дампе выглядит именно так?

    В теории:
    Код (Text):
    1. Delta  = Actual-IB
    2. Fixup  = Target+Delta
    где:
    Target – цель релока до применения релока
    Fixup – цель релока после применения релока

    соответственно:
    Код (Text):
    1. Target == Fixup-Delta
    2. Delta  == Fixup-Target
    Вот что получается в прикреплённых дампах:
    Код (Text):
    1. Delta    = Actual-IB
    2. F08E0000 = 8E0000 - 10000000
    3. Delta = F08E0000
    Для первого релока (по смещению 407h) это правильно:
    Код (Text):
    1. Delta  == Fixup-Target
    2. Delta   = 008E3000-10003000
    3. Delta1  = F08E0000
    Но для второго релока (по смещению 434h) получается вот что:

    Код (Text):
    1. Delta  == Fixup-Target
    2. Delta   = 008E2000-2000
    3. Delta2  = 008E0000
    Выходит, что как-то значение "прокручивается", потому что:
    Код (Text):
    1. 8E0000 - F08E0000 =10000000
    2. То есть:
    3. Delta2 - Delta1   = IB
    Почему?!

    Другие эксперименты показали, что проблема связана именно с переходниками импорта (второй релок на jmp GetCommandLineA), но в чём именно суть так и не понял.

    Изучал код ntdll.dll, смотрел исходники Win2k. Смотрел разные загрузчики.
    Нигде про этот фокус не слова нет.
    Везде:
    Код (Text):
    1. Delta  = Actual-IB
    и никак иначе.
    Единственное что ещё не успел сделать, так это в Айсе отловить запись в память по цели релока. Завтра будет VMware + Айс, может быть, сообразим что-нибудь.
    А пока надеюсь на вас(м) ребята!
    Прикрепляю бинарники и исходники (3кб всего):
     
  2. Bitfry

    Bitfry New Member

    Публикаций:
    0
    Регистрация:
    11 авг 2004
    Сообщения:
    54
    Адрес:
    Россия, Санкт-Петербург
    Всё, допёрло, кстати, через час после того как вопрос сформулировал. =)
    Необратил внимания, что дамперы умные пошли.
    Выходит, что до релокации загрузчик прибавляет ImageBase к jmp-офсетам переходников (а дампер, умный, отнимает), потом уже релокация идёт.