А>Если бы для ntdll не применялась ASLR, то ASLR бы эффективно отсутствовала – какой смысл рандомизировать что-то, если известна база хоть одного исполняемого модуля? Да ещё такой модуль как ntdll, ух.
Хм, ntdll и правда релокейтится. Но вообще сама идея ASLR под винду полный уг, учитывая что список модулей с базами и именами вычитывается из PEB'а кодом в несколько десятков строчек, без использования каких либо API.
А>Дело в другом. При создании секции для образов применяется ASLR и фиксятся релоки. Кроме того, соответствующим образом изменяется база в заголовке (для секции!). Когда такая секция мапится, система пытается отобразить её по выбранному ранее адресу (который редко совпадает с адресом в PE-хидере в файле на диске). Если это удаётся, возвращается STATUS_SUCCESS, а если нет, то маппирование происходит по другому адресу – и возвращается STATUS_IMAGE_NOT_AT_BASE (говорящий о том, что нужно пофиксить релоки перед использованием имаджа).
Спасибо, я сам когдато писал загрузчик PE имаджей который делал все вышеописанное.
А>Так что способ узнать дефолтный рандомизированный адрес "промапить и прочитать из хидера" полностью валиден. Кстати, юзермодный загрузчик проверяет необходимость применения релоков к первичному модулю процесса именно таким способом – сравнивает базу в заголовке с заполненным ядром полем Peb->ImageBase.
Редко какой ехе имеет таблицу релоков.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, Аноним, Вы писали:
А>Если бы для ntdll не применялась ASLR, то ASLR бы эффективно отсутствовала – какой смысл рандомизировать что-то, если известна база хоть одного исполняемого модуля? Да ещё такой модуль как ntdll, ух. А>Дело в другом. При создании секции для образов применяется ASLR и фиксятся релоки. Кроме того, соответствующим образом изменяется база в заголовке (для секции!). Когда такая секция мапится, система пытается отобразить её по выбранному ранее адресу (который редко совпадает с адресом в PE-хидере в файле на диске). Если это удаётся, возвращается STATUS_SUCCESS, а если нет, то маппирование происходит по другому адресу – и возвращается STATUS_IMAGE_NOT_AT_BASE (говорящий о том, что нужно пофиксить релоки перед использованием имаджа). А>Так что способ узнать дефолтный рандомизированный адрес "промапить и прочитать из хидера" полностью валиден. Кстати, юзермодный загрузчик проверяет необходимость применения релоков к первичному модулю процесса именно таким способом – сравнивает базу в заголовке с заполненным ядром полем Peb->ImageBase.
не смотрел как в других процессов, но на начальной стадии загрузки (Phase1Initialization) если промапить что-то другое на ImageBase ntdll — то будет бсод с кодом PROCESS1_INITIALIZATION_FAILED (6b).
>не смотрел как в других процессов
Мы смотрели дизасм когда-то – создание объекта "процесс" окончиться неудачей. Ntdll должна быть промаплена во всех процессах по одному и тому же адресу (основная причина, как нам кажется – ядерные колбеки). (Здесь нет противоречий – относительно указанной в дисковом файле базы образ может быть релоцирован).
>Редко какой ехе имеет таблицу релоков.
Готовы поспорить, что если сейчас пропарсить %windir% и %ProgramFiles% на нашей системе, то окажется, что более 91.21% экзешников имеют релоки ;)
>Но вообще сама идея ASLR под винду полный уг, учитывая что список модулей с базами и именами вычитывается из PEB'а кодом в несколько десятков строчек, без использования каких либо API.
Нет-нет-нет. Само собой разумеется, что локально можно узнать базы модулей (в т.ч. ядерных). ASLR не предназначена (никогда не предназначалась!) против локальных атак. Но она является бампером для удалённых попыток выполнить код (т.е. она должна предотвратить возникновение ситуации, когда один сможет вот так вот начать листать базу данных лоадера). И в этом плане здесь всё ok.