информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Где водятся OGRыВсе любят мед
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Очередное исследование 19 миллиардов... 
 Оптимизация ввода-вывода как инструмент... 
 Зловреды выбирают Lisp и Delphi 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
если вы видите этот текст, отключите в настройках форума использование JavaScript
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
Поставим вопрос по другому 12.02.02 23:12  Число просмотров: 794
Автор: PS <PS> Статус: Elderman
Отредактировано 12.02.02 23:22  Количество правок: 2
<"чистая" ссылка> <обсуждение закрыто>
Каким макаром обеспечивается прерывание в моем примере,
> mov eax, 0
> mov [eax], 3

Я знаю только такие способы,
1 В селекторе индекс равен 0
2 Обращение к ридонли для записи (и наоборот)
3 Обращение не из того кольца

Теперь
char* p = 0;
*p = 3;

Генерится приведеный мной ассемблерный код. DS уже установлена и не подходит не под один из 3х пунктов (индекс !=0, для записи и чтения, в том же кольце).
Вся разница в нормальной и не нормальной программе только в строчке mov eax, XXX (вот тут я правда не уверен)
Так каким образом обеспечивается прирывание ?

PS
А с наездом на реальный я конечно погорячился. может подсознательно вспомнил РК на КР580ВМ80, где сразу безвозврано попадал на вектора прерываний... (или это было в спектруме...)
<programming>
Можете меня штрафовать, но я спрошу 12.02.02 18:31  
Автор: PS <PS> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Почему нельзя писать по нулю ?
Только не бейте ногами !
Итак:
mov eax, 0
mov [eax], 3

Последняя инструкция эквивалентна mov DS:[eax], 3
Все было бы прекрасно, если бы DS содержал 0 селектор, тогда бы исключение было бы понятным, но DS содержит не нулевой селектор. А в сегменте я могу смещатся на столько на сколько мне позволяет его длинна. Хоть на 0, хоть на 1. Мы же не в реальном режиме, где эти адреса забиты под прерывания.
Итак, почему эксептион ?
Поставим вопрос по другому 12.02.02 23:12  
Автор: PS <PS> Статус: Elderman
Отредактировано 12.02.02 23:22  Количество правок: 2
<"чистая" ссылка> <обсуждение закрыто>
Каким макаром обеспечивается прерывание в моем примере,
> mov eax, 0
> mov [eax], 3

Я знаю только такие способы,
1 В селекторе индекс равен 0
2 Обращение к ридонли для записи (и наоборот)
3 Обращение не из того кольца

Теперь
char* p = 0;
*p = 3;

Генерится приведеный мной ассемблерный код. DS уже установлена и не подходит не под один из 3х пунктов (индекс !=0, для записи и чтения, в том же кольце).
Вся разница в нормальной и не нормальной программе только в строчке mov eax, XXX (вот тут я правда не уверен)
Так каким образом обеспечивается прирывание ?

PS
А с наездом на реальный я конечно погорячился. может подсознательно вспомнил РК на КР580ВМ80, где сразу безвозврано попадал на вектора прерываний... (или это было в спектруме...)
Поставим вопрос по другому 13.02.02 12:52  
Автор: ih8u <i hate you> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
Микропроцессорный комплект 580 РУЛЕЗ!!!!!!!!!!!!!!!!
Поставим вопрос по другому 13.02.02 11:07  
Автор: Sandy <Alexander Stepanov> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
> Каким макаром обеспечивается прерывание в моем примере,
> > mov eax, 0
> > mov [eax], 3
>
> Я знаю только такие способы,
> 1 В селекторе индекс равен 0
> 2 Обращение к ридонли для записи (и наоборот)
> 3 Обращение не из того кольца

4. Защита страницы на уровне процессора. Твой процесс не имеет прав обращаться к нулевой странице памяти. При попытке обращения процессор генерирует исключительную ситуацию, ядро ее обрабатывает и в твоей проге вылезает эксепшн.
Т.е. 13.02.02 11:51  
Автор: PS <PS> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Логический адрес, в моем примере преобразуется в КОРРЕКТЫЙ линейный, но на этом не заканчивается и линейный преобразуется в физический, а т.к. винда и возможно линукс скорей всего в дескрипторах ставят нули, то линейный адрес тоже получается 00000000, и он не может преобразоваться в физический.
А что бы остановится на линейном, и оставить его как физический мне надо писать свою "операционку", в которой не будет страниц.
Так ?

Можно сказать, что есть два защищеных режима: с сегментной и со страничной адресацией. Так ?
почитал бы ты доки по процам что-ли 13.02.02 12:55  
Автор: z0 <z0> Статус: Member
Отредактировано 13.02.02 13:05  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
> Логический адрес, в моем примере преобразуется в КОРРЕКТЫЙ
> линейный, но на этом не заканчивается и линейный
> преобразуется в физический, а т.к. винда и возможно линукс
> скорей всего в дескрипторах ставят нули, то линейный адрес
> тоже получается 00000000, и он не может преобразоваться в
> физический.

неправильно.

вот правильный ответ:
в режиме защиты адреса (бит 0 = 1 в CR0) логический адрес является КОРРЕКТНЫМ если он не выходит за предел адреса (limit+granularity_bit) установленный в соответствующем сегментному индексу дескрипторе.

перед проверкой логического адреса на КОРРЕКТНОСТЬ процессор выполнит проверку дескриптора - 1) индекс дескриптора (селектор)(сегмент) не может быть равен 0; 2) права доступа на дескриптор должны СООТВЕТСТВОВАТЬ (тут много нюансов) правам кода т.е. правам дескриптора CS; 3) операция с памятью должна допускаться типом данного дескриптора; 4) переходные эффекты (чтение dword по адресу fffffffe etc (не у всех процов))
в случае ошибки генерируется GeneralProtectionFault или (при стековых командах но не всегда) StackFault или Double/TripleFault

к логическому адресу прибавляется база дескриптора и получается линейный адрес - он же физический если бит 1f = 0 в CR0

если установлен режим страничного преобразования адреса (бит 1f = 1 в CR0) то происходит преобразование линейного адреса в физический по двухуровневой таблице страниц. при этом на каждом уровне происходит проверка страницы на доступность (бит юзер/супервизор) и присутствие в памяти (бит present)
по неприсутствию всегда генерится PageFault но надо помнить что у нее приоритет ОЧЕНЬ низкий и до нее часто генерится еще что-нибудь
по недоступности тоже всегда должна генериться PageFault но тут есть процессорозависимые нюансы

> А что бы остановится на линейном, и оставить его как
> физический мне надо писать свою "операционку", в которой не
> будет страниц.
> Так ?

ОС с соответствием физического и линейного адреса - DOS без EMM/QEMM etc, Novel NetWare 2.x 3.x 4.x
причем в досе поскольку RealMode то таблиц страниц и самих страниц естественно нету, а в новеле есть и то и другое но таблицы страниц так построены что преобразуют линейный в физический БЕЗ ИСКАЖЕНИЯ

>
> Можно сказать, что есть два защищеных режима: с сегментной
> и со страничной адресацией. Так ?

есть режим защиты адреса (ProtectedMode) для которого существует возможность включить режим страничной переадресации (PagingEnabled)

ЗЫ: пропущено много тонкостей естественно
почитал бы ты доки по процам что-ли 14.02.02 01:42  
Автор: Sandy <Alexander Stepanov> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
> по неприсутствию всегда генерится PageFault но надо помнить
> что у нее приоритет ОЧЕНЬ низкий и до нее часто генерится
> еще что-нибудь

Ага, именно эта исключительная ситуация используется менеджером виртуальной памяти для переключения существующих страниц физической памяти и/или подкачки страниц из файла подкачки.
Может еще раз... 13.02.02 13:17  
Автор: PS <PS> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Вообще то я считал, что логический это сегмент:смещение
линейный - преобразованый логический
физический - либо логический, либо преобразованый логический

> вот правильный ответ:
> в режиме защиты адреса (бит 0 = 1 в CR0) логический адрес
> является КОРРЕКТНЫМ если он не выходит за предел адреса
> (limit+granularity_bit) установленный в соответствующем
> сегментному индексу дескрипторе.
>
> перед проверкой логического адреса на КОРРЕКТНОСТЬ
> процессор выполнит проверку дескриптора - 1) индекс
> дескриптора (селектор)(сегмент) не может быть равен 0;

Селектор в моем примере не 0.
2) права доступа на дескриптор должны СООТВЕТСТВОВАТЬ (тут
> много нюансов) правам кода т.е. правам дескриптора CS;

Соответствуют

3)> операция с памятью должна допускаться типом данного
> дескриптора;
Допускается

4) переходные эффекты (чтение dword по адресу
> fffffffe etc (не у всех процов))
> в случае ошибки генерируется GeneralProtectionFault или
> (при стековых командах но не всегда) StackFault или
> Double/TripleFault
>
> к логическому адресу прибавляется база дескриптора и
> получается линейный адрес - он же физический если бит 1f =
> 0 в CR0
>
Может к смещению ?
Хорошо, прибавили. Получили... что ? Мы в виндах.

> если установлен режим страничного преобразования адреса
> (бит 1f = 1 в CR0) то происходит преобразование линейного
> адреса в физический по двухуровневой таблице страниц. при
> этом на каждом уровне происходит проверка страницы на
> доступность (бит юзер/супервизор) и присутствие в памяти
> (бит present)
> по неприсутствию всегда генерится PageFault но надо помнить
> что у нее приоритет ОЧЕНЬ низкий и до нее часто генерится
> еще что-нибудь
> по недоступности тоже всегда должна генериться PageFault но
> тут есть процессорозависимые нюансы
>

Так на каком этапе проц генерит эксептион в примере
mov eax, 0
mov [eax], 1

?????
Может еще раз... 14.02.02 01:54  
Автор: Sandy <Alexander Stepanov> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
> Вообще то я считал, что логический это сегмент:смещение
> линейный - преобразованый логический
> физический - либо логический, либо преобразованый
> логический

Здесь надо учитывать, что значение в сегментном регистре в реальном и защищенном режимах сильно отличаются: в реальном там хранится сегмент памяти в пределах 1М памяти, а в защищенном - селектор, т.е. смещение в локальной/глобальной таблице дескрипторов.

> > перед проверкой логического адреса на КОРРЕКТНОСТЬ
> > процессор выполнит проверку дескриптора - 1) индекс
> > дескриптора (селектор)(сегмент) не может быть равен 0;

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

> Так на каком этапе проц генерит эксептион в примере
> mov eax, 0
> mov [eax], 1

Именно здесь! Делается попытка записи в память в нулевой странице процесса.

>
> ?????
Может еще раз... 14.02.02 14:50  
Автор: z0 <z0> Статус: Member
Отредактировано 14.02.02 15:38  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
> Здесь надо учитывать, что значение в сегментном регистре в
> реальном и защищенном режимах сильно отличаются: в реальном
> там хранится сегмент памяти в пределах 1М памяти, а в
> защищенном - селектор, т.е. смещение в локальной/глобальной
> таблице дескрипторов.

значения-то сами могут и не отличаться а вот смысл их конечно разный

>
> > > перед проверкой логического адреса на
> КОРРЕКТНОСТЬ
> > > процессор выполнит проверку дескриптора - 1)
> индекс
> > > дескриптора (селектор)(сегмент) не может быть
> равен 0;
>
> Если честно, не вижу причин, почему бы ему не мочь быть
> равным нулю. Особенно если таблица дескрипторов локальная.

хорошо поправлю себя: старшие 14 битов сегмента/селектора
ты же наверняка знаешь что равный нулю сегмент/селектор относится именно к GDT

по поводу твоего слова "особенно" - вспоминаются дебаты на каком-то западном форуме - фравии что-ли - по поводу ИСПОЛЬЗОВАНИЯ нулевого индекса в GDT. честно сказать кроме того что это удобное место для хранения 8 байт полезной информации я для себя ничего не использовал - да, есть процессорозависимые глюки но и только
я так понимаю интел сделал селектор 0 по аналогии с сишным нулевым указателем - чтобы было чем загрузить неиспользуемый сегментный регистр
Может еще раз... 14.02.02 16:45  
Автор: Sandy <Alexander Stepanov> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
> > Здесь надо учитывать, что значение в сегментном
> регистре в
> > реальном и защищенном режимах сильно отличаются: в
> реальном
> > там хранится сегмент памяти в пределах 1М памяти, а в
> > защищенном - селектор, т.е. смещение в
> локальной/глобальной
> > таблице дескрипторов.
>
> значения-то сами могут и не отличаться а вот смысл их
> конечно разный

Ага, именно это я и хотел сказать.

> по поводу твоего слова "особенно" - вспоминаются дебаты на
> каком-то западном форуме - фравии что-ли - по поводу
> ИСПОЛЬЗОВАНИЯ нулевого индекса в GDT. честно сказать кроме
> того что это удобное место для хранения 8 байт полезной
> информации я для себя ничего не использовал - да, есть
> процессорозависимые глюки но и только
> я так понимаю интел сделал селектор 0 по аналогии с сишным
> нулевым указателем - чтобы было чем загрузить
> неиспользуемый сегментный регистр

Это не совсем очевидно, но мне тоже на ум ничего другого не приходит.
...И еще вопрос. 13.02.02 18:54  
Автор: Chingachguk <Chingachguk> Статус: Member
Отредактировано 13.02.02 18:56  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
> Так на каком этапе проц генерит эксептион в примере
> mov eax, 0
> mov [eax], 1 <<< Тута.
> ?????

Вообще-то z0 все уже написал.
Просто хотел дополнить и спросить. Если посмотреть, как выполняется самая простая прога под вин, то вот что видать:

- код начинается ВСЕГДА с смещения 401000h.(возможно, это зависит от компилятора(я имею в виду +1000h));
- если выполнить инструкцию вида:

mov al,ds:[400000h] ; все работает OK

Но вот если выполнить эту:

mov al,ds:[400000h-1] ; То возникает исключение 0Eh - PageFault.

Итак, доступ куда нам дает селектор в ds. Смотрим:

ldt ds ; Выдать описалово на локальный дескриптор(в ds):

Sel ... Base Limit DPL Attr
0167 ... 0000 0000FFFF 3 P RW ED

Я полагаю, используется страничное преобразование линейного адреса.
В данном случае 400000h - это не минимальный физ. адрес, по которому можно читать/писать (это не так, ибо, например Base+Limit меньше+бит гранулярности вроде выставлен).
Пусть используются 4-х килобайтные страницы, тогда физический адрес формируется вроде так:

Биты 12-21 используются как индекс в таблице "базовых" физических адресов, оттуда берем базу, смещение берем(уже в ней) из битов 0-11, биты >=22 - индекс в каталоге страниц.

Я правильно понял ? Ж)
Может еще раз... 13.02.02 14:14  
Автор: z0 <z0> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
> Вообще то я считал, что логический это сегмент:смещение
> линейный - преобразованый логический
> физический - либо логический, либо преобразованый
> логический

ну это конечно вопрос терминологии
давай придерживаться чего-то
например:
ЛОГИЧЕСКИЙ - смещение внутри сегмента
ЛИНЕЙНЫЙ - смещение внутри адресного пространства процессора
ФИЗИЧЕСКИЙ - адрес на шине процессора

> Может к смещению ?
> Хорошо, прибавили. Получили... что ? Мы в виндах.

значит прибавили 0

> Так на каком этапе проц генерит эксептион в примере
> mov eax, 0
> mov [eax], 1
>
> ?????

1) CPU: DS <> 0 CPU: Ok
2) CPU: PL (DS) >= PL (CS) CPU: Ok
3) CPU: DS writable CPU: Ok
4) CPU: eax < segment_size CPU: Ok
5) CPU: segment_size-eax >= operator_size CPU: Ok
eax=eax+0 пропускаем вижу что тебе это понятно
6) CPU: page_table_directory(eax).[bit_present] CPU: Ok
7) CPU: page_table_directory(eax).[bit_user] CPU: Ok
8) CPU: page_table(page_table_directory(eax)).[bit_present] CPU: No
9) CPU: exception(PageFault, Address)
10) OS: check_page_user_rights(Process, Address) OS:NoAccess
11) OS: RaiseException(AccessViolation, Process, Address)
12) OS: Kill(Process)

то что от ОС зависит - это для виндов (смотрел в НТ)
для линуха может ты нам расскажешь
думаю приблизительно так же
в linux точно также 13.02.02 16:04  
Автор: ukv Статус: Незарегистрированный пользователь
<"чистая" ссылка> <обсуждение закрыто>
И в виндах, и в линуксе изрядная часть защиты сделана не на уровне сегментов, а на уровне страниц. Сегментация фактически подавляется. Неявно предполагается, что приложение работает в flat-модели, ds и cs адресуют все 4 Гб одного и того же виртуального адресного пространства. На уровне страничной организации в этом пространстве будут в основном лакуны - и в частности нулевая страница. Неприсутствие нулевой страницы в памяти - просто черта операционок - для отлова ошибок обращения по нулевому указателю. Ну а из тех страниц, которые в адресном пространстве есть - некоторые могут быть защищены от записи (и тогда, например, можно отображать одну физическую копию ядра в адесное пространство всех процессов сразу). С точки зрения сегментов все выглядит нормально - сегмент есть (на все 4Гб), и запись в него вроде бы разрешена, а модифицировать ядро не получится - не позволит менеджер страниц.
почему нельзя? 12.02.02 21:56  
Автор: z0 <z0> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
> Мы же не в реальном режиме, где эти адреса забиты под
> прерывания.
> Итак, почему эксептион ?

во-первых в реальном режиме как раз можно, как ты сам знаешь
во-вторых это зависит от карты распределения памяти для проги, которая в свою очередь зависит от ОС
для чикаги - примерчик
.386

code32 segment use32 para private 'code'
assume cs:code32
assume ds:data32
entry_point:
call check_OS
cmp eax,WIN9X
jne exit
call goto_ring0
call set_page0_present_and_user
call goto_ring3
mov eax,0
mov [eax],3 ; no exception
call goto_ring0
call restore_all_hacked_above
call goto_ring3
exit:
push dword 0
call ExitProcess

code32 ends

data32 segment use32 para private 'data'
db 'some data here'
data32 ends

end entry_point

почему нельзя? можно...
Можете меня штрафовать, но я спрошу 12.02.02 21:45  
Автор: Sandy <Alexander Stepanov> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
> Почему нельзя писать по нулю ?
> Только не бейте ногами !
> Итак:
> mov eax, 0
> mov [eax], 3
>
> Последняя инструкция эквивалентна mov DS:[eax], 3
> Все было бы прекрасно, если бы DS содержал 0 селектор,
> тогда бы исключение было бы понятным, но DS содержит не
> нулевой селектор. А в сегменте я могу смещатся на столько
> на сколько мне позволяет его длинна. Хоть на 0, хоть на 1.
> Мы же не в реальном режиме, где эти адреса забиты под
> прерывания.
> Итак, почему эксептион ?

Чтобы легче было отлавливать ошибки в программах, связанные с неинициализированными указателями, Винда запрещает обращение к адресам из первой страницы адресного пространства процесса.
Все указатели сегментов указывают на одно и то же адресное пространство. Т.е. CS:0 и DS:0 указывают на одну и ту же ячейку памяти, которая находится по адресу 0.
Из-за этого ЛЮБЫЕ обращения процесса к адресам в первой странице, не важно, что это за обращение: выполнение кода, стек, данные - возникает исключение Access violation.
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2025 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach