Board.KolibriOS.org

Официальный форум KolibriOS
Текущее время: Вт июн 19, 2018 4:36 am

Часовой пояс: UTC+03:00




Начать новую тему  Ответить на тему  [ 63 сообщения ]  На страницу 1 2 3 4 5 След.
Автор Сообщение
 Заголовок сообщения: Эмуляция KolibriOS API
СообщениеДобавлено: Вс мар 04, 2018 9:00 pm 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 1275
Эмулятор mike.dld MeOSEmul работает как интерпретатор, эмулятор diamond-a KlbrInWin — как дебаггер,
ну а я же хочу просто установить свой обработчик исключений и в нём обрабатывать вызовы KolibriOS.

Но для начала нужно загрузить приложение. В самой KolibriOS приложения грузятся по смещению 0.
У diamond-a реализовано с помощью SetLdtEntries, что позволяет грузить не по нулевому смещению.
Я не стану использовать такой способ, а буду загружать именно по нулевому смещению :)

Сперва посмотрим, а что у нас находится по смещению 0 в адресном пространстве приложения после его загрузки.
Посмотрим на скриншот распределения памяти(есть замечательная программа VMMap, спасибо Руссиновичу за это :) )
Спойлер: Показать
Вложение:
mem_map1.PNG
mem_map1.PNG [ 57.38 КБ | 730 просмотров ]
Кстати, хорошая статья про распределение памяти https://habrahabr.ru/post/202242/
Как видно, регион 0..64K свободен, значит мы можем его использовать, нужно только выделить память в нуле.
Я буду это делать вот так:
Код:
BaseAddress := Pointer(1); RegionSize  := 1024 * 64 - 1;
NtAllocateVirtualMemory(GetCurrentProcess, @BaseAddress, 0, @RegionSize, MEM_COMMIT Or MEM_RESERVE, PAGE_EXECUTE_READWRITE);   
Функция NtAllocateVirtualMemory из ntdll определена вот так:
Код:
Function NtAllocateVirtualMemory(ProcessHandle: THandle; BaseAddress: PPChar; ZeroBits: Dword; RegionSize: PDword; AllocationType: Dword; Protect: Dword): Pointer; StdCall; External 'ntdll';
Обнаружил ограничения этого:
Цитата:
NULL page mitigations for Windows 8 (both x86 and x64), and even backported the mitigation to Vista+
Я тут нашёл кое-что про EMET https://habrahabr.ru/company/eset/blog/184428/ там есть что-то про NullPage, судя по скриншотам это можно как включить, так и выключить.
То есть, если правильно понимаю, надо отключить NullPage в EMET чтобы выделение памяти в нуле заработало.
Вот здесь https://www.atraining.ru/emet-4-0-windo ... r-2012-r2/ кое-что объясняется:
Цитата:
Что такое Null Page Allocation (NPA)
Это защита от достаточно интересной атаки, базирующаяся на предположении, что зловредный код “займёт” для себя страницу с адресом 0x0 в адресном пространстве приложения.
Для этого сама программа – EMET – занимает адрес 0x0. Впрок, так сказать.
Что интересно, если вызвать VirtualAlloc с параметром 0, то VirtualAlloc (что, в общем-то, логично) выделит память по адресу, который выберет сама, а не по нулевому.
Для того, чтобы “застолбить” за собой такой адрес, как предполагается, применяется вызов NtAllocateVirtualMemory, у которой запрашивается адрес 0x1, при попытке выделения которого выделяется блок, начинающийся с 0x0.
На данный момент зловредов, использующих эту возможность, не обнаружено.
Включить NPA можно как и EAF – только для явно указанных приложений, а не на уровне системы.
Когда эта технология включена, “нулевая” страница при запуске приложения будет занята в профилактических целях.

Да, как видно, память чуть выше уже занята, и её использовать сейчас не получится(хотя всё ещё можно аллоцировать её динамически из кучи, например)
У нас сначала идёт CODE из System, вот если бы можно было вставить в самое начало большой кусок ненужных данных или кода, которые можно было бы потом затереть...
Код:
Detailed map of segments

 0001:00000000 0000277B C=CODE     S=.text    G=(none)   M=System   ACBP=A9
 0001:0000277C 00000140 C=CODE     S=.text    G=(none)   M=SysInit  ACBP=A9
 0001:000028BC 00000038 C=CODE     S=.text    G=(none)   M=Types    ACBP=A9
 0001:000028F4 00000190 C=CODE     S=.text    G=(none)   M=Windows  ACBP=A9
 0001:00002A84 00000038 C=CODE     S=.text    G=(none)   M=Messages ACBP=A9
 0001:00002ABC 00001780 C=CODE     S=.text    G=(none)   M=KEm      ACBP=A9
 0002:00000000 00000088 C=DATA     S=.data    G=DGROUP   M=System   ACBP=A9
 0002:00000088 0000001C C=DATA     S=.data    G=DGROUP   M=SysInit  ACBP=A9
 0002:000000A4 0000000C C=DATA     S=.data    G=DGROUP   M=KEm      ACBP=A9
 0002:00001000 0000064C C=BSS      S=.bss     G=DGROUP   M=System   ACBP=A9
 0002:0000164C 00000010 C=BSS      S=.bss     G=DGROUP   M=SysInit  ACBP=A9
 0002:0000165C 00000004 C=BSS      S=.bss     G=DGROUP   M=Types    ACBP=A9
 0002:00001660 00000004 C=BSS      S=.bss     G=DGROUP   M=Windows  ACBP=A9
 0002:00001664 00000004 C=BSS      S=.bss     G=DGROUP   M=Messages ACBP=A9
 0002:00001668 0000FA34 C=BSS      S=.bss     G=DGROUP   M=KEm      ACBP=A9
Пока только пришло на ум следующее:
компилятор позволяет собрать приложение с ImageBase = 64 K:
Спойлер: Показать
Вложение:
mem_map.PNG
mem_map.PNG [ 56.89 КБ | 730 просмотров ]
тогда можно сделать сам эмулятор как библиотеку и запустить её из приложения с ImageBase = 64K(сам этот загрузчик можно искусственно раздуть до нужных размеров, чтобы потом после запуска самого эмулятора можно было благополучно затереть), загрузить kex, проверить сколько реально нужно, ненужное освободить.
Имею в виду, в Dll будет функция Main, а загрузчик:
Код:
.DATA
db MEM_SIZE dup ?
.CODE
jmp Main
Может быть кто-то знает более рациональный вариант? Пока что для тестов 64K должно хватить, а дальше дело техники :)

Итак, приложения у нас могут быть упакованные с помощью kpack.
Но не зря же я делал unpack viewtopic.php?f=46&t=355&p=69118#p69118 :)
То есть, запакованные kex-файлы тоже будут поддерживаться.

После загрузки приложения установим обработчик исключений, по умолчанию обнулим регистры и поехали!
Код:
Asm
  (* set our exception handler *)
    push Offset ExceptionHandler
    push Dword Ptr fs:[0]
    mov  fs:[0], esp 
  (* set registers and flags by default *) 
    xor eax, eax
    xor ebx, ebx
    xor ecx, ecx
    xor edx, edx
    xor esi, esi
    xor edi, edi
    xor ebp, ebp
    push 0; popfd
  (* goto entry point *) 
    jmp  eip
  End;   
     
В обработчике исключений мы проверяем, чем конкретно вызвано исключение, и если это вызов ядра KolibriOS, то соответственно обрабатываем его:
Код:
     If (ExceptionCode = EXCEPTION_ACCESS_VIOLATION) And (Word(ExceptionAddress^) = $40CD) Then


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Вс мар 04, 2018 10:43 pm 
Не в сети
Designer
Аватара пользователя

Зарегистрирован: Чт янв 25, 2007 3:33 pm
Сообщения: 4450
Жду продолжения этой детективной стории :)

_________________
Через тернии к звездам


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Пн мар 05, 2018 2:55 pm 
Не в сети

Зарегистрирован: Ср мар 26, 2008 12:44 pm
Сообщения: 167
Leency писал(а):
Жду продолжения этой детективной стории :)

В качестве продолжения.

В конце прошлого года я наткнулся на тему "Простой загрузчик ELF для Колибри" и там была ссылка на тему "Эмулятор под Linux", на которую я 10 лет назад не обратил внимание. А поскольку пару лет назад я пересел на Linux, то с интересом посмотрел на изыскания diamond-а и Ghost-а. Посмотрев на примеры и добившись их работы на 64-битной Ubuntu, мне показалось, что сделать эмулятор будет несложно. На деле же я столкнулся с массой проблем, так что разработка эмулятора растянулась на несколько месяцев (свободного от работы времени).

На данный момент большинство программ с образа флоппи-диска уже запускается и работает, однако есть достаточное количество багов, поэтому я пока не решился выкладывать свои наработки. Но я обещаю, что в скором времени выложу свой проект на GitHub.


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Вт мар 06, 2018 10:40 am 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 1275
Сейчас приложения действительно грузятся по нулевому смещению, вот в Borland debugger
Спойлер: Показать
Вложение:
KexInBORdbg.PNG
KexInBORdbg.PNG [ 68.29 КБ | 666 просмотров ]
а вот в Olly debugger
Спойлер: Показать
Вложение:
KexInOllydbg.PNG
KexInOllydbg.PNG [ 54.43 КБ | 666 просмотров ]
При включенном DEBUG_OUTPUT(раскомментированном {$DEFINE DEBUG_OUTPUT}) в исходнике, происходит отладочный вывод в консоль: это значения регистров на момент вызова, а также названия вызываемых функций и переданные параметры, это преобразуется в такой вид, как если бы была вызвана соответствующая функция из KolibriOS.lib(её можно найти в теме Delphi7 examples viewtopic.php?f=33&t=3469):
Спойлер: Показать
Вложение:
test_console.PNG
test_console.PNG [ 41.02 КБ | 666 просмотров ]
Внутри сами эти функции имеют такой же интерфейс, например вот вызов DrawRectangle, параметры извлекаются из регистров:
Код:
13: DrawRectangle(Ebx Shr 16, Ecx Shr 16, Ebx And $0000FFFF, Ecx And $0000FFFF, Edx);
Вот так выглядят вызовы программы Pipet(viewtopic.php?f=38&t=3546&p=68926#p68926):
Спойлер: Показать
Вложение:
pipet_console.PNG
pipet_console.PNG [ 47.56 КБ | 666 просмотров ]
После того, как вызов функции KolibriOS отработал, нужно увеличить адрес на длину соответствующей инструкции:
Код:
Inc(Eip, SizeOf(Word($40CD)));
Так как я с загрузкой скинов ещё не работал, то в данный момент они не поддерживаются, я знаю, что скины могут быть сжаты kpack-ом, но распаковка таких файлов уже поддерживается для самих приложений, можно будет сделать это и для скинов.

Сейчас программа при запуске грузит файл, переданный в качестве параметра командной строки(например, можно перетащить мышкой значок kex на значок эмулятора)
Код:
  If ParamCount > 0 Then
    FileName := PChar(ParamStr(1))
Также можно загрузить файл, выбранный из OpenDialog(на самом деле приложение перезапускается, в качестве параметра командной строки передаётся путь из OpenDialog(а всё из-за того, что OpenDialog не завершает свои потоки и не освобождает ресурсы)):
Код:
If CommDlg.GetOpenFileName(OpenFile) Then


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Пт мар 09, 2018 2:16 pm 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 1275
Для теста сейчас я взял пример SetPixel из темы Delphi7 examples viewtopic.php?f=33&t=3469

Сейчас скины не поддерживаются, также не учитываются клиентские координаты окна,
но таскать окно за заголовок можно, можно использовать двойной щелчок по заголовку,
ещё можно изменять размеры окна с помощью мыши(хотя это и не очевидно в отсутствие скинов).

Вот для сравнения с KlbrInWin
Спойлер: Показать
Вложение:
KEm_KIW(SetPixel).PNG
KEm_KIW(SetPixel).PNG [ 10.76 КБ | 603 просмотра ]
Было бы интересно узнать, как это работает на разных версиях Windows(и работает ли вообще).

Некоторые демо программы работают(bcdclk, cslide);
Спойлер: Показать
Вложение:
bcdclk+setpixel+cslide.PNG
bcdclk+setpixel+cslide.PNG [ 18 КБ | 603 просмотра ]
Вот magnify и iconedit:
Спойлер: Показать
Вложение:
magnify+iconedit.PNG
magnify+iconedit.PNG [ 33.45 КБ | 603 просмотра ]
В подавляющем большинстве приложения KolibriOS имеют сигнатуру MENUET01, но некоторые старые — MENUET00, некоторые новые — MENUET02, так вот, на текущий момент они не поддерживаются.

В папке Tests есть некоторые примеры, их исходники или на svn, или на форуме(SetPixel viewtopic.php?f=33&t=3469#p68384, GetScreenImage viewtopic.php?f=33&t=3469#p69039), поэтому не стал их туда включать.
Вложение:
KEm.7z [35.4 КБ]
17 скачиваний


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Пт мар 09, 2018 3:00 pm 
Не в сети

Зарегистрирован: Пн мар 27, 2006 6:33 am
Сообщения: 594
0CodErr писал(а):
Было бы интересно узнать, как это работает на разных версиях Windows(и работает ли вообще).

В XP работает. Попробовал запустить Tetris. Запустился, но управления от клавиш нет.
В Win8.1 при попытке загрузить программу в консоле пишет "Read File error"

P.S. В принципе - работает. :)


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Пт мар 09, 2018 3:07 pm 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 1275
Kopa, я писал в первом сообщении про EMET.
Не в курсе просто, как оно там в Win8.1 устроено, может на уровне системы заблокировано, а может быть можно в настройках регулировать.
"Read File error" — значит, что не загружен файл куда надо(по смещению 0).


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Пт мар 09, 2018 3:12 pm 
Не в сети

Зарегистрирован: Пн мар 27, 2006 6:33 am
Сообщения: 594
Проверил ещё в ReactOS,тоже принципиально работает.

P.S. Какие то файлы не проходят верификацию загрузки.


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Пт мар 09, 2018 3:16 pm 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 1275
Kopa писал(а):
Какие то файлы не проходят верификацию загрузки.
0CodErr писал(а):
В подавляющем большинстве приложения KolibriOS имеют сигнатуру MENUET01, но некоторые старые — MENUET00, некоторые новые — MENUET02, так вот, на текущий момент они не поддерживаются.


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Сб мар 10, 2018 2:30 am 
Не в сети

Зарегистрирован: Пн мар 27, 2006 6:33 am
Сообщения: 594
Из игрушек запустилась и играбельна marblematch.
Pong3 запустилась, но без управления.

P.S. Чаще всего происходит крэш программы, как с возможностью сохранить дамп так и без каких либо сообщений.


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Вс мар 11, 2018 11:50 am 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 1275
Kopa писал(а):
Из игрушек запустилась и играбельна marblematch.
Эта игра почему-то создаёт окно с заголовком Heliothryx :?:
Код:
EIP    = $0000007B; EAX    = $00000000; EBX    = $00640209; ECX    = $00640213
EDX    = $74DDDDFF; ESI    = $34DDDDFF; EDI    = $00005C18; EBP    = $0412FE60
ESP    = $0412FE10; EFLAGS = $00010202
DrawWindow(Left:100, Top:100, Width:521, Height:531, Caption:"Heliothryx", BackC
olor:$ddddff, Style:$74000000, CapStyle:$34ddddff)
Наверное, они просто друг у друга код скопировали :lol:
Kopa писал(а):
Pong3 запустилась, но без управления.
Ввод с клавиатуры сейчас не поддерживается(вообще, думаю, по исходнику это заметно).
Kopa писал(а):
Чаще всего происходит крэш программы
Многие приложения используют библиотеки(соответственно, пытаются вызвать функции из них), их загрузка сейчас не поддерживается.
Некоторые приложения пишут\читают изображения "directly to\from LFB" — это тоже не поддерживается.

Сделал DLL-версию.
"Загрузчик", резервирующий 64 мегабайта памяти(константа MEM_SIZE в исходнике), загружается по адресу 64K.
С помощью VirtualProtect устанавливаются атрибуты PAGE_EXECUTE_READWRITE. После чего управление передаётся в Main, которая находится в DLL.
В дальнейшем "загрузчик" можно затереть кодом или данными загруженного KolibriOS приложения.

Теперь поддерживаемых приложений стало чуть больше, например, работает FREE3D04(Fisheye Raycasting Engine Etc. by Dieter Marfurt).
Загружается стартовый экран игры INVADERS, если бы системная функция SysFn2:GetKey поддерживалась, то можно было бы и поиграть :)
Работают демки 3DWAV, TRANTEST, TUBE.
Вложение:
KEm.7z [57.04 КБ]
13 скачиваний


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Вс мар 11, 2018 12:48 pm 
Не в сети

Зарегистрирован: Пн мар 27, 2006 6:33 am
Сообщения: 594
Здесь какое то видео.
Using EMET to Disable EMET

P.S. Да, поддерживаемых приложений стало гораздо больше. :)
Можно начать перечислять.
Под ReactOS эти тесты не заработaли. Выводит ошибку доступа к памяти Write only.
Можно, наверное, разработчмикам ReаctOS сделать баг-репорт. :)
Где то на Read память ругается.


Последний раз редактировалось Kopa Вс мар 11, 2018 3:13 pm, всего редактировалось 7 раз.

Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Вс мар 11, 2018 1:02 pm 
Не в сети
Аватара пользователя

Зарегистрирован: Ср апр 15, 2015 11:13 pm
Сообщения: 182
Из-за чего с windows 7 и выше не запускается? Это возможно из-за защиты windows?


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Вс мар 11, 2018 3:28 pm 
Не в сети
Designer
Аватара пользователя

Зарегистрирован: Чт янв 25, 2007 3:33 pm
Сообщения: 4450
JFYI: KlbrInWin x64, не тестировал.
http://kolibriosandfasm.mybb.ru/viewtopic.php?id=11

_________________
Через тернии к звездам


Вернуться к началу
 Заголовок сообщения: Re: Эмуляция KolibriOS API
СообщениеДобавлено: Вс мар 11, 2018 7:30 pm 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 1275
Leency писал(а):
KlbrInWin x64
В каком месте там x64? Обычный же :)
ALEXS1983 писал(а):
Проверка работоспособности и настройки KlbrInWin и использование проводились в Windows XP.

Есть такой эмулятор Cxbx.
Цитата:
Cxbx is an emulator for the Xbox video game console that allows users to enjoy Xbox games from their home PCs.
Там использовалось SetLDTEntries(то же, что использовал diamond).
Но там решалась задача с регистром FS.
Потом на 64 bit возникли проблемы с этой функцией(она там просто как заглушка, ничего не делает). У KlbrInWin тоже проблемы с x64.
Трудно сказать, как именно они их решили. Вот тут http://qpdownload.com/cxbx/ написано, что, под все Windows.
Раньше был такой файлик https://github.com/ILOVEPIE/Cxbx-Reloaded/blob/master/src/CxbxKrnl/EmuFS(64).cpp#L51
Кому интересно, вот тут функция EmuAllocateLDT https://github.com/ILOVEPIE/Cxbx-Reloaded/blob/master/src/CxbxKrnl/EmuLDT.cpp#L84
Сейчас вот поновее(форк вроде) https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/tree/master/src/CxbxKrnl
:) Там в шапке каждого файла: Dear PVS-Studio, please check it :)


Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 63 сообщения ]  На страницу 1 2 3 4 5 След.

Часовой пояс: UTC+03:00


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB