Сегментные регистри и 386

Тема в разделе "WASM.BEGINNERS", создана пользователем DeHunter, 18 июл 2005.

  1. DeHunter

    DeHunter New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2005
    Сообщения:
    80
    Адрес:
    Ukraine/Kiev
    Здраствуйте.

    При разборе инструкций возник вопрос по поводу Segment override prefixes. Под винду я писал немного. В досе понятно вроде было с сегментами, а в вин чтото не очень. Как я понимаю нам даётся 4 виртуальных гига. Эти 4 гига разбиваются на разделы(для оси, для проги и прочее). Я делаю допустим команду

    mov eax, dword ptr DS:[ebx]

    Тестирую под OllyDbg. Всё работает. Делаю тоже самое с GS(ставлю префикс 65H) и получаю еррор. Обьясните пожалуста в чём разница и как эти сегментные регистры используются в вин ? Они ведь вроде как были размером в слово так и остались. Тоесть указывать на сегмент они уже не могут. Да и нет вроде никаких сегментов в вин.
     
  2. Draw

    Draw New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2005
    Сообщения:
    4
    4 гига разбиваются на разделы. Конкретно в винде есть 2 большие зоны: до 2-х Гб, для приложений, и после 2-х Гб, для ядра, драйверов и т.д. Каждому приложению выделяется память из первой зоны. Смежение и размер выделенного фрагмента заноситься в табличку, где ещё куча таких же элементов от других приложений. DS - смещение в этой табличке. GS, насколько я знаю, винда не пользует. Поэтому надо забыть про содержимое сегментных регистров. Кол-во выделеной памяти меняешь ТОЛЬКО через сервисы системы. Единственное, что пожалуй может потребоваться - FS, там находятся секции исключений.
     
  3. DeHunter

    DeHunter New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2005
    Сообщения:
    80
    Адрес:
    Ukraine/Kiev
    Проблема собствено в том что я пишу эмулятор.

    И меня интересует как расчитывать смешение если у меня вместо DS стоит CS ?
     
  4. Draw

    Draw New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2005
    Сообщения:
    4
    Место, на которое указывает элемент таблички дескрипторов, на который указывает CS, помечено как исполняемый код. Читать его строго запрещено. Способ обхода - создать ещё один элемент, который будет указывать на то же самое место, но при этом иметь атрибут данных вместо атрибута кода. В винде такое можно сделать, поковырявшись в PE экзешника. Надо поставить у секции права на исполнение и права на чтение/запись. Обычно такими вещами вирусы любят заниматься). Но это не работает, если код уже загружен в оперативку. А других спрособов я не знаю(. Возможно в винде есть функции.
     
  5. DeHunter

    DeHunter New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2005
    Сообщения:
    80
    Адрес:
    Ukraine/Kiev
    Спасиб. Пойду разбиратся.
     
  6. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    >помечено как исполняемый код. Читать его строго запрещено

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

    >Но это не работает, если код уже загружен в оперативку

    Можно у страниц параметры поменять, как не помню

    вот только по памяти WriteProcessMemory, ReadProcessMemory
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Не надо путать понятие секции или региона памяти и сегмента.

    В защищенном режиме процессор позволяет организовать два уровня защиты памяти: один на уровне страниц, другой на уровне сегментов.

    Когда мы говорим о секциях или регионах памяти (код, данные, стек, куча), то защита осуществляется на уровне установки и контроля атрибутов чтения\записи страниц памяти. В частности, чтобы разрешить запись в секцию кода можно либо на этапе компиляции установить атрибут секции writeable, либо подправить PE заголовок откомпилированного файла, либо на этапе исполнения вызвать VirtualProtect и установить атрибут PAGE_EXECUTE_READWRITE на нужное число страниц секции кода.



    Защита на уровне (логических) сегментов это несколько другое. В защищенном режиме процессор позволяет использовать как плоскую, так и сегментированную модель памяти и дело разработчиков ОС какую модель выбрать и какие задействовать элементы защиты, предоставляемые процессором. Но сам проц всегда различает (логические) сегменты данных и кода, всегда выполняет соответствующие проверки и генерирует исключения в случае ошибок. В частности, запись в кодовый сегмент адресуемый селектором CS строго запрещена, т.е. mov CS:[eax],edx не прокатит несмотря на то, что секция кода имеет атрибут writeable (даже mov edx,CS:[eax] может не прокатить если дескриптор кодового сегмента не помечен как readable). Точно также нельзя совершить far jmp или call в сегмент данных, нельзя загрузить в регистры DS-GS селектор кодового сегмента, а в SS селектор сегмента с атрибутом readonly. Т.е. защита памяти на уровне страниц\секций это одно, а защита на уровне описания сегментов - это другое.

    Ну и как эти ограничения обходятся в плоской модели памяти ? Да просто ось устанавливает базовые адреса сегментов данных, кода и стека в 0 и задает соответствующий размер сегментов (до 4Гб) - в результате все сегменты указывают на одну и ту же область памяти, т.е. логически сегменты разные (как требует того процессор), а кусок памяти один. Поэтому если позволяют атрибуты страниц, можно читать и писать в секцию кода обычными мувами через селектор сегмента данных (DS и т.п.) или исполнять код в области стека или данных не меняя селектора сегмента кода CS.



    Подробности в IA-32,volume 3, Chapter 3: Protected-Mode Memory Management