Не Win-процесс: Изоляция и контроль
Задумано: Windows-приложение - оболочка для обработки звука и графики на уровне скриптов;
Скрипты: Пишутся в оболочке QView на уровне обыкновенного 32-битного машинного кода x86;
Особенности: Win-API полностью недоступны скрипту, так как его задача - лишь обработать массив, а после - HLT;
Реализовано: Простой парсер x86-OpCode с неполным набором эмулируемых инструкций и очень медленный. Хотя скрипты в нём вполне исполняемы и имеется демо-скрипт с диалогом и анимацией, серъёзные вычисления там невозможны в виду отсутствия обработки x87-инструкций и всего набора 0F ...;
Цель: Заменить парсер на обработчик исключений, загрузить скрипт-код как отдельный процесс, перекрыть ему всякий доступ к Win-API и другим средствам системы, обрабатывать все ситуации моим обработчиком исключений.
mov ax, 0x2D00 ; Режим - 2D-графика, поверхность окна
mov es, ax ; Исключение! Подставить под сегмент приёмника ячейки изображения №1
mov ax, 0x2D01 ; Режим - 2D-графика, Bitmap#01
mov ds, ax ; Исключение! Подставить под сегмент источника ячейки изображения №2
movsd ; Исключение! Приёмник и источник корректируются в размере, а ECX=Height*65536+Width
L1: lodsd ; Исключение? См.*1 Работает как Win-API GetPixel(hBmpdc, LOWORD(ESI), HIWORD(ESI))
neg eax ; Операция
stosd ; Исключение? См.*2 Работает как Win-API SetPixel(hWindc, LOWORD(EDI), HIWORD(EDI), EAX)
loop L1 ; Цикл
hlt ; Готово!
; *1: Данное исключение срабатывает не постоянно. Первое обращение LODSD к памяти
; вырабатывает исключение и подставляет под чтение первую строку пикселей
; Bitmap с ограничением до Ширины Bitmap. Всё последующее чтение происходит
; напрямую процессором, пока указатель не выйдет за Ширину. После чего будет
; подставлена следующая строка и ECX также будет откорректирован.
; *2: То же самое, что и *1, но после заполнения буффера строки пиксели выводятся
; на экран.
Вопрос: Думаю, уже становится понятным, какая у меня проблема с реализацией проекта. Мне надо лишь сделать два шага:
1) Загрузив x86-скрипт в память как простые данные, нужно оформить этот блок памяти как процесс, перекрыть ему доступ к Win-API функциям, назначить обработчик исключений и запустить на исполнение;
2) Собственно, построить обработчик исключений.
Эпилог: Как я уже сказал, всё это уже работает, но очень медленно и ограниченно. Мне лишь нужно сделать шаги 1) и 2), и подменить дубовый мой парсер-эмулятор на обработчик исключений.
Спасибо!
Вот результат работы в этой области: Проект.
Доступны: Он-лайн дизассемблер и исходный текст оболочки.
Скрипты: Пишутся в оболочке QView на уровне обыкновенного 32-битного машинного кода x86;
Особенности: Win-API полностью недоступны скрипту, так как его задача - лишь обработать массив, а после - HLT;
А почему бы не воспользоваться средой с управляемым кодом?
Сразу решатся многие вопросы, связанные с безопасностью.
Писать скрипты придется в CIL или Java Bytecode.
Вопрос "Какую дурь вы курили?" здесь неуместен, так как дело явно идет о вещах посерьезнее. Чего только стоит выбор в качестве скриптового языка мнемоник x86. Можно конечно предположить, что планировалась комппиляция скрипта с последующим запуском на выполнение, однако с таким же успехом можно было использовать любой другой язык высокого уровня (C/C++). Здесь могут последовать возражения, что написанная на ассемблере прога быстрее, меньше, и тд и тп... Это мы опустим, ибо начинает пованивать идиотизмом.
Повеселился, спасибо.
Vertecs Думаю некоторые функции системы модулю могут всё-таки понадобиться, что если ему например памяти побольше захочется для обработки? А это будет, ибо вы хотите сопроцессор, а все форматы данных целочисленые, поэтому у модуля должны быть свои области памяти. Как осуществляется взаимодействие модуля и основной программы?
Простейшим способом контроля может, например, быть разбор таблицы импорта ехешника модуля, для этого нужно чтобы он был ехешником или библиотекой.
А в не простейшем случае, запускаем наш модуль на пошаговое выполнение и обработчиком проверяем, входит ли следующая инструкция в список разрешённых. Правда это всё равно сильно замедлит работу модуля, но не так, как полный эмулятор.
Поищи для примера доку по плагинан фотошопа.
Да и вообще, если модули - не вендовые ехе-файлы, то как они могут добраться до выньАПИ? Разве что сканированием всего адресного пространства на наличие сигнатур ;-)
То, что вы делаете в qView можно писать на нормальном ассемблере (ассемблируем в бинарник без заголовка)
Вы не совсем меня поняли. Скрипты в CIL или Java коде - это совсем не подходит, так как с таким же успехом можно использовать MAX-scripts и язык VRML. Языков много и стандарты у всех свои. А меня интересует один старый, но проверенный временем язык - машинный код x86. И будет ли использоваться QView или Asm - дело вкуса. Моя идея не нова, так как её механизм простой как и режим Crypt в Hiew, с описанием алгоритма напрямую x86-операциями. Так что я не нашёл новый путь, а лишь расширяю чей-то.
Vov4ik Понадобиться дополнительная память, в принципе, не может. А если даже понадобится, то Win-API VirtualAllocate будет вызываться исключением.
mov ecx,1048576; Требуется ровно 1Мб
mov ax, 0x1234 ; Страница № 0x1234
mov es, ax ; Исключение!
lock rep cmpsb ; Исключение! Недопустимая инструкция. Обрабатываем как buf[ES] = VirtualAlloc(NULL, ECX, MEM_COMMIT, ...
jnc Err ; Jmp if Not Complete, так как успешное VirtualAlloc выделение памяти мой менеджер установит как CF-флаг скрипт-процесса
Т.е. всё продуманно и документация не описывает новый язык, так как для этого существует документации по Assembler'у, написанные грамотными людьми. Я лишь описываю в ней маленькие механизмы генерации исключений для достижения того или иного. Так, например:
; ES = 0x2D?? - 256 страниц управления GDI-графикой
; ES = 0x3D?? - 256 страниц управления OpenGL-средствами
; ES = 0x2C?? - 256 страниц управления потоком 2Channels-Audio
; ES = 0xCB?? - 256 страниц управления Console Buffer
; ES = 0xFE?? - 256 страниц управления FilE system
- здесь это я и показываю: Каждый зарезервированный сегмент работает окном к API определённой категории. Документации CreateProcess умалчивает про механизмы, такие, как скрытие Win-API (процесс в карцере)...
PS: При разработке фильтров VirtualDub можно было бы написать один, но универсальный фильтр, загружающий x86-скрипт как процесс и кидая ему кадр за кадром. Тут, API и вовсе скрипту не нужны, так как ему нужно лишь входящий буффер обработать и заполнить итоговый буффер. Просто и безопасно...
Вы не совсем меня поняли..... так как ему нужно лишь входящий буффер обработать и заполнить итоговый буффер. Просто и безопасно...
Эмм. А зачем весь этот цирк с ассемблером?
Вы когданить Paint.NET вдиели? Там можно вставить в специальное окошко код на C# и он обработает изображение. Гораздо удобнее мозгоиссушающего написания хрен знает чего на ассмеблере, еще не факт что скрипт приложение в нокаут не отправит.
З.Ы. Скрипту нужно задачу выполнять, а не память выделять и заботиться о состоянии стека вызовов.
Вы когданить Paint.NET вдиели? Там можно вставить в специальное окошко код на C# и он обработает изображение. Гораздо удобнее мозгоиссушающего написания хрен знает чего на ассмеблере, еще не факт что скрипт приложение в нокаут не отправит.
З.Ы. Скрипту нужно задачу выполнять, а не память выделять и заботиться о состоянии стека вызовов.
Эм-ммм... Ну, т.е. Вы предлагаете готовое? А если я пожелаю, чтобы мой x86-скрипт принимал видеопоток напрямую через сеть, обрабатывал его и выдавал TXT-таблицу со списком статистики RGB-составляющих? Какрас-таки моя задумка - идея универсальной оболочки управления данными и сложными структурами языком переключения сегментов...
Хм, я и так тут много лишнего понаписал про суть идеи...
Скажу прямо: Допустим, я - не пользователь, желающий строить графику, синтезировать звук, перенаправлять сетевые потоки. Допустим, я - начинающий программист, которому конечный пользователь(друг, знающий ассемблер, но не понимающий API) заказал подобную программу-универсал, чтобы короткими фрагментами кода(в 10-30 байт) совмещать не совместимое без страха уронить систему(или сервер, если он хочет сделать сервер)... Значит, по Вашему я ему скажу "есть вот такая-то софтюлина" и он просто уйдёт к другому?
Понимаете, к чему я клоню? ;)
Совсем не обязательно для решения такой задачи писать код на ассемблере.
Ох уж мне эта универсальность.
Интересно, это как? Хотя вопрос в том, какой он ассемблер знает...
Короткими фрагментами кода можно и в С/С++ asm-вставки делать. Это гораздо удобнее и практичнее, чем создавать специальный хост (песочницу) для выполнения асм-скрипта. У вас не получится полностью изолировать его исполнение, для этого придется собственный JIT-компилятор создавать.
Значит, на мой взгляд, нужно искать более эффективное решение.
Вот мне нужно найти простенькую документацию построение скелета своей голой машины, на подобии VMWare...
Вот мне нужно найти простенькую документацию построение скелета своей голой машины, на подобии VMWare...
Динамическая трансляция кода, несколько примитивная реализация которой есть в QEMU.
PS: 1:1 - это миф
PS2: Не занимайтесь ерундой.
PS: 1:1 - это миф
PS2: Не занимайтесь ерундой.
1:1 - миф, но не в случае, если фрагмент переваривает данные в огромных таблицах. В таком периоде он ничем не тормозится...
Всё было бы хорошо, если бы Google выдал материал на тему контроля дочернего процесса на уровне исключений. В лучшем случае нахожу статьи о контроле исключений в рамках одного процесса через FS:[0]...
Удивлён в недостатке информации на простую ситуацию с исключениями... А значит это не ерунда, а проблема поисковых машин или недостаток опыта у разработчиков вообще...
Спасибо...
Подобные виртуальные машины используются в Антивирусах и эмуляторах типа VMWare.
Эти современные виртуальные машины не транслируют машинный код, а исполняют его непосредственно процессором, перехватывая различные обращения к внешним ресурсам. Т.о. обеспечивая инкапсуляцию исполнения.
Это сложные коммерческие продукты и информация о применяемых механизмах представляет коммерческий интерес. И не особо распространяется в сети.
Однако, я думаю что-то можно найти в проектах с открытым кодом.
У меня есть несколько нароботок в этой области, но это будет стоить дорого :)
Подобные виртуальные машины используются в Антивирусах и эмуляторах типа VMWare.
Эти современные виртуальные машины не транслируют машинный код, а исполняют его непосредственно процессором, перехватывая различные обращения к внешним ресурсам. Т.о. обеспечивая инкапсуляцию исполнения.
Это сложные коммерческие продукты и информация о применяемых механизмах представляет коммерческий интерес. И не особо распространяется в сети.
Однако, я думаю что-то можно найти в проектах с открытым кодом.
У меня есть несколько нароботок в этой области, но это будет стоить дорого :)
Да, Вы поняли меня на 100% верно. Хм, не знал, что это на столько серъёзно и закрыто... А жаль... Во всяком случае,
Спасибо!
Всё стало на свои места...
Спасибо!
Всё стало на свои места...
Да не закрыто, а не очень открыто.
А открытые проекты есть. Вот, например:
http://sourceforge.net/projects/bochs/
http://sourceforge.net/projects/dosbox/
Sun xVM VirtualBox Open Source Edition(OSE) tarball -> https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_SMI-Site/en_US/-/USD/ViewFilteredProducts-SingleVariationTypeFilter;pgid=01RgaHqkAdxSR0EUQncsoQ3D0000eRRc3Zt2;sid=nKm1FI238li1FMXViEP9EWIeSKtVI0DyyUt61ZCpxIzRtA==
Бесплатно и открыто
Однако в их исходниках я давно копался и заметил одну вещь...
На сколько я понял, вся основная сложность не сколько в эмуляции железа, а в эмуляции виртуализации. То есть переключения между реальным и защищённым режимами, управление дискрипторами и т.д. Короче, сложность - в эмуляции привелегированных инструкций и механизмов защищённого режима... Поэтому многие эмуляторы - интерпретаторы, а не полноценные инкапсуляторы средствами процессора...
А если, скажем, я поставлю вопрос следующим образом?
"Нужно реализовать x86 чисто вычислительной модели. Моим x86-сценариям не надо же переключать режимы и управлять дискрипторами, а привелегированные инструкции и вовсе не нужны"
Мой собственный интерпретатор x86-кода так и устроен: Аналог первобытного i8086 с той разницей, что доступны 32-битные регистры и многие операции, за исключением привелегированной группы.
В таком фокусе можно найти открытые алгоритмы?
Спасибо!
Спасибо, но категорически не подходит в качественном плане. В моём случае http://www-sop.inria.fr/geometrica/team/Sylvain.Pion/progs/mmx-emu/ (жалко, не под Windows) имеет больше отношения к проблеме, нежели подобные антивирусные механизмы. Тем более, легче написать полный x86-парсер (я написал за 9 часов), чем разбираться и отлаживать полудизассемблерный гибрид с флагом отладки, что проигрывает в защите и скорости даже моей версии, когда процессор предоставляет проработанные аппаратные средства куда совершеннее "дедушкиного TF"...
Доступно: Исходный текст оболочки+демо-код, он-лайн дизассемблер, краткое описание. К тому же сегодня добавил форум и скудную документацию.
Будут идеи, вопросы и предложения - спасибо!
виртуальная машина типа Вари работает по принципу отладчика ядра .
у 486+ процессоров есть четыре отладочных регистра , исключения по обращению к памяти и в защищённом режиме виртуальный 86 .
при правильной настройке всё будет работать . единственно на что надо обратить внимание , так это на код подменяющий биос и на адреса таблицы прерываний для v86 .
виртуальная машина типа Вари работает по принципу отладчика ядра .
у 486+ процессоров есть четыре отладочных регистра , исключения по обращению к памяти и в защищённом режиме виртуальный 86 .
при правильной настройке всё будет работать . единственно на что надо обратить внимание , так это на код подменяющий биос и на адреса таблицы прерываний для v86 .
VMware работает не совсем так или даже совсем не так, впрочем как и иные.
На странице закачек есть исходный текст. Чтобы увидеть всё в действии, достаточно откомпилировать и запустить.
В том скопище букв периодически тускло поблескивают зачатки бинарной трансляции, да и только.
это с появлением аппаратной виртуализации они не так стали работать .
А так же и до этого они не так работали за исключением одной поделки на коленке, которая жутко глючила, тормозила и была дырявой как дуршлаг, а в конце концов перешла на аппаратную поддержку. Ибо проблем в вышеизложенном методе как г*на в городской канализации.
PS: Кстати, поделка использовала данную методику в виду ряда исторических причин.
Оно и есть. Как я и задумывал изначально.
Обыкновенный код x86-инструкций парсится на выявление опасных-безопасных инструкций. Т.е. чисто вычислительные операции отдаются процессору как есть. А вот доступ к памяти перерабатывается в безопасный и т.д.
Т.е. всё это нужно в очень узких местах. Например, бывает в LightAlloy плеере картинка перевёрнута или цвета смещены: BGR вместо RGB. Редко, но я сталкивался.
В таких случаях цвета очень быстро поменять местами можно BSWAP EAX и SHR EAX,8. Т.е. всего двумя инструкциями. А лучшее, что в таком случае предлагается, это искать SDK и писать плагин.
А общая идея такая: Допустим я написал свой плеер с поддержкой этих самых x86-скриптов. И чтобы "профильтровать" кадр при выводе на экран, достаточно написать такой скрипт:
0005: 8C D8 MOV EAX,Z
0007: 0F C8 BSWAP EAX
0009: 8E D8 MOV Z,EAX
000B: F4 HLT
000C: 2F 61 70 70 2E ...
Т.е. имено такие мелочные проблемы заставили меня задуматься о такой технологии скриптов. Всякие Lua, Java и Flash скрипты очень ресурсоёмкие как в парсере, так и в коде.
А поддержка технологии x86-скриптов очень проста как в парсировании, так и в итоговом коде.
Чем это лучше любого шейдерного языка?
Хм. По сути говоря - ничем. Только тем, что операции - x86. Т.е. на PC выполняются команды процессора без эмуляции или компиляции. Тем самым, кто знает специфику программирования на x86, тому не надо углубляться в специфику x86-скриптов.
Я вот подумал, в качестве демки попробовать написать эмулятор Z80 полностью в x86-скрипте. Будет наглядным примером по-идее:)