Relocation, .reloc. обнуление-проблема

Тема в разделе "WASM.BEGINNERS", создана пользователем Luzer, 9 сен 2009.

  1. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    dermatolog
    >Мой последний пост подтверждает мою же теорию
    Ты не находишь, что это было частью нашего утверждения #8?
    "при выставленном бите имадж будет пытаться загрузиться по базовому адресу, однако при неудаче загрузится по другому".

    Это, лайк:
         

    dermatolog
    >проги без релоков (с IMAGE_FILE_RELOCS_STRIPPED=1) будут тупо падать
    Почему? Они просто будут грузиться по базовому адресу. Если он не занят. Если занят, то по другому адресу – и вот в этом случае они будут падать. (Гнидосбор: Если, конечно, они не базонезависимы или не написаны специально для детекта подобных ситуаций – например, дочерний процесс нашей тестилки не падает, а вызывает пару нативных функций, получает APC и корректно завершается).

    Кстати, поступили сведения, что наши утверждения верны для XP SP2 x32. Кто-нибудь может подтвердить?

    l_inc
    Ты не мог бы показать вывод тестилки на висте32? Спасибо :)
     
  2. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    dermatolog
    Гм. Нет, не похоже что это как-то влияет. Кстати, почему верхние адреса? У нас грузится на 0x10000.
     
  3. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Sol_Ksacap
    Код (Text):
    1. WinVer: 6.0.6001  sp1, SuiteMask: 768, x64 process: 0, wow64: 0
    2.  
    3. Current process:
    4.         IMAGE_FILE_RELOCS_STRIPPED = 0
    5.         Default ImageBase: 00400000
    6.         ImageBase: 00A60000
    7.         Relocs applied: 1
    8.  
    9. Trying to create child process... SUCCESS
    10.  
    11. Child process:
    12.         IMAGE_FILE_RELOCS_STRIPPED = 1
    13.         Default ImageBase: 7FFE0000
    14.         ImageBase: 00010000
    15.         Relocs applied: 0
    16.  
    17. Crap, Sol_Ksacap just might be a genius!
    Хм... странно... я выставлял, кстати, другой базовый адрес. Если выставить адрес, равный базе kernel32.dll, то с флагом IMAGE_FILE_RELOCS_STRIPPED не грузится. А вот без него нормально грузится по другому адресу.
     
  4. dermatolog

    dermatolog Member

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    406
    Адрес:
    Екатеринбург
    Sol_Ksacap
    Это было не НАШЕ утверждение, а твоё. Почитай еще раз #9.
    Код (Text):
    1. Почему? Они просто будут грузиться по базовому адресу. Если он не занят. Если занят, то по другому адресу – и вот в этом случае они будут падать.
    Не будут они грузиться по другому адресу - я уже устал тебе об этом говорить :))
     
  5. dermatolog

    dermatolog Member

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    406
    Адрес:
    Екатеринбург
    Sol_Ksacap
    P.S. Завязывай играться со своими тестилками - я вообще не понимаю че ты там мутишь и что именно ты там делаешь. Для тестов вполне хватит юзермодного отладчика+PETools.
     
  6. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    dermatolog
    >Это было не НАШЕ утверждение, а твоё.
    Ну разумеется это было наше утверждение. Т.е. утверждение, которое высказал Sol_Ksacap. В посте #8. Лол. (Твоё утверждение мы процитировали (значком ">"), после чего высказали своё "wtf", а далее привёли в качестве аргумента это самое наше утверждение). Вот картинка:
    [​IMG]
    (Кстати, когда мы её рисовали, у нас упал дефолтный mspaint. Лол).

    dermatolog
    >Не будут они грузиться по другому адресу
    Нет будут. Лол. Ты идёшь против фактов же.

    >Для тестов вполне хватит юзермодного отладчика+PETools
    Ну это конечно да – и в посте #10 мы показали, что блокнот загружен не по базовому адресу при установленном флаге Relocs_Stripped. Но тестилка хороша тем, что её может запустить и увидеть результаты любая жизнеформа, даже гражданский. Она, лайк, статична и ошибки содержит тоже статичные.

    >че ты там мутишь и что именно ты там делаешь
    Ох, приносим извинения за код – мы слегка спешили, и, лайк, не выполняли какого-либо планирования в написании (ибо, лайк, одноразово). Сегодня ночью переделаем немного и добавим тест длл.

    l_inc
    >Если выставить адрес, равный базе kernel32.dll, то с флагом IMAGE_FILE_RELOCS_STRIPPED не грузится.
    Аа, огромное спасибо за этот кусок информации. Обязательно посмотрим, где именно происходит фейл инициализации. Хотя вообще говоря, сейчас нам кажется это странным – ведь kernel32 грузится уже позже, во время выполнения кода загрузчика в ntdll. В общем, посмотрим.
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Sol_Ksacap
    "Фейл инициализации" происходит при попытке спроецировать kernel32 (чисто исходя из текста ошибки). Но если сабжевый флаг сброшен, то загрузчик всё-таки догадывается сместить базу образа несмотря на то, что на момент проецирования образа в АП создаваемого процесса база kernel32 ещё не занята.
     
  8. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Интересный факт: kernel32 в таком случае таки проецируется, но загрузчик в ntdll детектирует, что это kernel32, спроецированный по небазовому адресу, и депроецирует его лол.
    Если чуть более подробно, то примерно так: kernel32 отображается на адресное пространство в процессе выполнения кода загрузчиком ntdll, вне зависимости от наличия ссылок на неё в каких-либо модулях:
    LdrInitializeThunk -> LdrpInitialize -> LdrpInitializeProcess -> LdrLoadDll -> LdrpLoadDll -> LdrpMapDll -> LdrpMapViewOfDllSection -> ZwMapViewOfSection
    В случае, если ZwMapViewOfSection спроецирует kernel32 не по дефолтному адресу (и, соответственно, вернёт не STATUS_SUCCESS, а 0x40000003 {Image Relocated}), то LdrpMapDll увидит это и проверит два условия: не совпадает ли базовое имя отображаемой длл со строкой ntdll!Kernel32String ("kernel32.dll") и не является ли это "известной длл" (KnownDlls). Если оба условия выполняются, то kernel32 анмапится (ZwUnmapViewOfSection) и возвращается статус 0xc0000018 {Conflicting Address Range}, что прекращает дальнейшую инициализацию процесса.
    Как сказал l_inc, если сабжевый флаг сброшен, то даже при потенциальном пересечении отображения образа, спроецированного по дефолтной базе с проекцией kernel32 процесс таки будет инициализирован – такая ситуация проверяется ядром и главный модуль проецируется по отличному адресу (опят-таки, для этого IMAGE_FILE_RELOCS_STRIPPED должен быть сброшен). Вообще говоря, если этот флаг сброшен, то длл будут грузится всегда (для любой выровненной базы), а инициализацию процесса всё же может постигнуть фейл в таком редчайшем случае: потенциальный клэш проекции главного модуля с ntdll -> проецирование ядром главного модуля по недефолтной базе и попадение главной проекции внутрь потенциального дефолт-отображения kernel32, что не даст в дальнейшем спроецировать kernel32 по дефолтной базе.

    Теперь ещё моменты. Наше утверждение в предыдущих постах о том, что релоки не фиксятся – неверное: если модуль промаплен, то релоки будут пофикшены (несмотря на флажок или что-нибудь). Кроме того, есть простой случай, когда никакие модули действительно не будут грузится: сабжевый флаг установлен И директория базовых релокаций обнулена.

    Окей, есть ещё куча нюансов, но текстария слишком узка – если вдруг кому-то интересно, он может поиграться с тестилкой или чем-нибудь: frilocs.exe    [default_address | dll_name_from_which_to_take_default_address]

    P.S.
    Всё тестировалось только на висте сп1 х64.