Эмуляция KolibriOS API

Running Kolibri and its programs in other OSes
  • Попробовал собрать последнюю ревизию у себя программы
    и получил такое сообщение

    Code: Select all

    /usr/bin/ld: /tmp/ccotqVjU.o: неопределённая ссылка на символ «dlopen@@GLIBC_2.1»
    //lib/i386-linux-gnu/libdl.so.2: error adding symbols: DSO missing from command line
    collect2: error: ld returned 1 exit status
    
  • 0CodErr wrote:
    tsdima wrote:
    0CodErr wrote:Интересно, кто-нибудь пробовал из-под Wine запускать?
    Я пробовал, всё тот же "Read File error".
    Значит в linux нельзя выделить память в нуле.
    А ведь раньше была возможность.
    Нашёл в модуле System такой код с комментариями:

    Code: Select all

    {$IFDEF LINUX}
    
    ................................................................................
    
    { The Win32 program loader sets up the first 64k of process address space
      with no read or write access, to help detect use of invalid pointers
      (whose integer value is 0..64k).  Linux doesn't do this.
    
      Parts of the Delphi RTL and IDE design environment
      rely on the notion that pointer values in the [0..64k] range are
      invalid pointers.  To accomodate this in Linux, we reserve the range
      at startup.  If the range is already allocated, we keep going anyway. }
    
    var
      ZeroPageReserved: Boolean = False;
    
    procedure ReserveZeroPage;
    const
      PROT_NONE = 0;
      MAP_PRIVATE   = $02;
      MAP_FIXED     = $10;
      MAP_ANONYMOUS = $20;
    var
      P: Pointer;
    begin
      if IsLibrary then Exit;  // page reserve is app's job, not .so's
    
      if not ZeroPageReserved then
      begin
        P := mmap(nil, High(Word), PROT_NONE,
          MAP_ANONYMOUS or MAP_PRIVATE or MAP_FIXED, 0, 0);
        ZeroPageReserved := P = nil;
        if (Integer(P) <> -1) and (P <> nil) then  // we didn't get it
          munmap(P, High(Word));
      end;
    end;
    
    procedure ReleaseZeroPage;
    begin
      if ZeroPageReserved then
      begin
        munmap(nil, High(Word) - 4096);
        ZeroPageReserved := False;
      end;
    end;
    {$ENDIF}
    Так как у linux исходный код открыт, то, думаю, при желании можно для себя любимого снова включить эту возможность.
    Kopa wrote:Попробовал собрать последнюю ревизию у себя программы
    Ошибся темой , да? :)
  • Всё-таки в некоторых Windows7 работать должно.

    По крайней мере в Windows7 SP1 до обновления безопасности это должно работать.
    Возможно, что и в Windows8 с ntvdm, но это только x86, а не x64, ведь в x64 ntvdm работать не будет.

    Например, я нашёл, где используется похожая функция: https://payatu.com/hacksys-extreme-vulnerable-driver/
    Там есть "Null Pointer Dereference"
    Поддерживаемые версии Windows:
    • Драйвер — Windows XP SP3 (x86), Windows 2003 SP3 (x86) и Windows 7 SP1 (x86), но может поддерживать Windows 8/8.1 (x86) тоже. Поддержка Windows 8/8.1 сейчас ещё не протестирована.
      Эксплойт был протестирован на Windows 7 SP1 (x86).
    Код на GitHub-е: https://github.com/hacksysteam/HackSysE ... ableDriver
    В папке Whitepaper есть pdf, вот картинка оттуда
    nullptrdrfrnc.PNG
    nullptrdrfrnc.PNG (19.46 KiB)
    Viewed 15856 times
    Вот тут https://osandamalith.com/2017/06/22/win ... reference/ кто-то описывает использование техники "null pointer dereference", используемой в этом проекте.
    Вот у него на GitHub-е: https://github.com/OsandaMalith/Exploit ... aster/HEVD
    Вот статья об этом на securitylab: https://www.securitylab.ru/analytics/494397.php
    Кстати, там же пишут:
    Начиная с Windows 8, выделение первых 64 Кбайт запрещено.
    Единственное исключение – если разрешен компонент NTVDM, который по умолчанию отключен.
    Насколько я понимаю, с включенным NTVDM должно работать? Кто-нибудь пробовал включать NTVDM?
    Также вот в этой статье https://www.securitylab.ru/news/495193.php есть ссылка на pdf, вот картинка оттуда
    win10mitigations.PNG
    win10mitigations.PNG (49.61 KiB)
    Viewed 15856 times
    как видно, выделение NullPage в Win7 ещё возможно. Значит, в Windows Vista тоже должно работать.

    В принципе, для тестирования своих приложений можно просто собирать их с подходящим ImageBase и грузить примерно так:
    KEm.exe -base 65536 test.kex
    Например, как тут http://board.kolibrios.org/viewtopic.ph ... =30#p70153
    Если же цель — использование для разработки программ, то на период тестирования\отладки своей программы можно её скомпилировать не с "org 0", а, скажем с 'org 64K' и грузить эмулятором по этому адресу.
    ......................
  • Технологии меняют мир, а я - меняю технологии.
  • Может быть добавить в KEm?:
    Если стартовый адрес в заголовке проги > 0x10000, то автоматом грузить с 0x10000
    Не выпиливая функционала возможности указать другую базу
  • Немного доработал эмулятор.
    Сделал файл настройки setting.ini, где можно по умолчанию задать такие настройки как:

    Code: Select all

    [General]
    ; Jmp default base address
    BaseAddress=0
    
    ; Theme KolibriOS Enable or Windows Disable
    Theme=Enable
    
    ; Console Show/Hide
    Console=Show
    
    ; Wait exit Enable/Disable
    WaitExit=Disable
    
    Также добавил несколько сис. функций. Пытаюсь добавить поддержку сис.ф-ций потоки.
    Можно достичь быстродействия, если поменять условие case для проверки сис.ф-ции на массив сис. ф-ций. Потому что сразу будет исполняться та ф-ция номер которой соответствует ключу, чем все перебирать.
    Программа если не находит default.skn грузит стандартную тему Windows. Это аналогия с настройками Theme=Disable
    Если программа не может загрузить по 0 адресу, то 2 раз пытается загрузить по 0x10000 адресу. Тем самым можно запускать и в Windows XP, и в Windows 7 и выше, без параметра -base
    Attachments
    Kem.rar (210.23 KiB)
    Downloaded 359 times
    Технологии меняют мир, а я - меняю технологии.
  • Кстати, говорят что по 0 адресу будет работать в windows 7 x32 битной, а в x64 не будет. В 32 битной будет работать если создать ярлык этого эмулятора и поставить в свойствах ярлыка запускать в отдельной области памяти, но сам я не проверял.
    Attachments
    Безымянный.png
    Безымянный.png (34.83 KiB)
    Viewed 15763 times
    Технологии меняют мир, а я - меняю технологии.
  • pavelyakov wrote:В 32 битной будет работать если создать ярлык этого эмулятора и поставить в свойствах ярлыка запускать в отдельной области памяти
    Насколько понимаю, это
    позволяет выполнить 16-разрядные приложения в отдельных виртуальных DOS-машинах
    Это для трюка с NTVDM что ли? Жаль, что микрософт считает выделение в 0 уязвимостью, а значит всё равно это будет закрыто рано или поздно. Нужен легальный способ. Хм.. а как виртуальные машины работают(не эмуляторы процессора)? Через драйвер может?
    pavelyakov wrote:Можно достичь быстродействия, если поменять условие case для проверки сис.ф-ции на массив сис. ф-ций. Потому что сразу будет исполняться та ф-ция номер которой соответствует ключу, чем все перебирать.
    :) Компиляторы для того и нужны, чтобы программист об этом вообще не беспокоился.
    Компилятор сам создаст таблицу переходов, если это будет необходимо, например, такой код

    Code: Select all

    Var X, Y: LongWord;
    
    Begin
      Case X Of
        1:      Y := 0;
        20:     Y := 1;
        3:      Y := 2;
        42:     Y := 3;
        5:      Y := 4;
        60:     Y := 5;
        7:      Y := 6;
        80:     Y := 7;
        9000:   Y := 8;
        100500: Y := 9;
      End;
    End.
    может быть оттранслирован примерно в это

    Code: Select all

      00407CE0: A1 98 97 40 00       mov         eax,[00409798]
      00407CE5: 83 F8 2A             cmp         eax,2Ah
      00407CE8: 7F 6A                jg          00407D54                    ; здесь прыжок на обработку без таблицы переходов
      00407CEA: 0F 84 9F 00 00 00    je          00407D8F                    ; здесь прыжок на обработку без таблицы переходов
      00407CF0: 83 F8 14             cmp         eax,14h
      00407CF3: 0F 87 E8 00 00 00    ja          00407DE1                    ; значение не попало в наш диапазон -> выход
      00407CF9: FF 24 85 00 7D 40 00 jmp         dword ptr [eax*4+00407D00h] ; прыжок на адрес из таблицы переходов
      
      00407D00: 
               таблица переходов
      
      00407DE1: 
               выход
    В зависимости от значений результат тоже будет разный, иногда использование таблицы переходов не оправданно, компилятор об этом знает и в этом случае не генерирует такую таблицу.
    Compiler generated branch tables
    pavelyakov wrote:Если программа не может загрузить по 0 адресу, то 2 раз пытается загрузить по 0x10000 адресу. Тем самым можно запускать и в Windows XP, и в Windows 7 и выше, без параметра -base
    Только надо помнить, что сама программа доолжна быть собрана с соответствующим ImageBase.
    lev wrote:Если стартовый адрес в заголовке проги > 0x10000, то автоматом грузить с 0x10000
    Но ведь он не пишется в заголовке.
    pavelyakov wrote:Пытаюсь добавить поддержку сис.ф-ций потоки.
    Для этого некоторые(но не все) глобальные переменные должны быть thread-local. То есть, вместо

    Code: Select all

    Var X: Dword;
    будет

    Code: Select all

    ThreadVar X: Dword;
    Также есть проблема со стеком, если использовать тот стек, который приложение KolibriOS указало в ThreadCreate:
    • Для Windows-функций, вероятно, требуется больший размер стека.
      В некоторых KolibriOS-программах стек не выравнен(это плохо, но это есть) — с этим тоже может быть проблема.
      Можно захотеть передать параметры в запускаемый поток, положив ему что-то на стек: выделили память под стек, положили туда значения, затем указали выделенную область в ThreadCreate. Тут можно попытаться копировать некоторое количество байт из KolibriOS в Windows стек.
      А ещё можно запустить поток без стека, а он уже сам его себе выделит: выделить память под стек, mov esp, ...
    В идеале, наверное, лучше иметь главный поток, а остальные ему только сигнализируют(как клиент-сервер), при этом сами вызовов Windows не выполняют.
    Но это будет сложнее реализовать, текущий вариант в подавляющем большинстве случаев должен и так работать.
  • Если стартовый адрес в заголовке проги...
    Но ведь он не пишется в заголовке
    Header - MENUET01
    OS version - 1 (или 2 для multithread)
    start address - ...
    Ок, если то, что идёт третьим пунктом в заголовке проги, ошибочно считаемое мной за стартовый адрес, больше 0х10000 ...
    Вариант с двойной загрузкой от pavelyakov тоже вполне подошел
    Кстати, возьмите подопытного. В данный момент падает на, видимо, ещё не реализованной загрузке курсора.
    Attachments
    hr.kex (3.3 KiB)
    Downloaded 340 times
  • lev wrote:Ок, если то, что идёт третьим пунктом в заголовке проги, ошибочно считаемое мной за стартовый адрес, больше 0х10000 ...
    А, так ты про Entry point(Точка входа). "Больше 0х10000" — это ещё не гарантия, ImageBase при этом вполне может быть и 0, а Entry point где-то гораздо дальше, другое дело, что таких относительно немаленьких программ под KolibriOS не так уж много.

    Вообще, думаю, после реализации вот этого http://board.kolibrios.org/viewtopic.ph ... 666#p69666 было бы проще, судя по http://ftp.kolibrios.org/users/CleverMouse/pe/pe.patch приложения также в формате StrippedPE. Там есть тестовый пример programs/system/test/trunk/test.asm
    Вот из процедуры map_pe_usermode

    Code: Select all

    +; 5. Allocate space in the address space.
    +; Prefer PEDESCR.defaultbase, but allow address anywhere else
    +; if allocation at PEDESCR.defaultbase is not possible.
    +        mov     edi, [esi+PEDESCR.size]
    +        shl     edi, 12
    +        stdcall user_alloc_at_nolock, [esi+PEDESCR.defaultbase], edi
    +        test    eax, eax
    +        jnz     @f
    +        stdcall user_alloc_nolock, edi
    +        test    eax, eax
    +        jz      .user_alloc_failed
    +@@:
    +        mov     [img_base], eax
    lev wrote:Header - MENUET01
    OS version - 1 (или 2 для multithread)
    Судя по http://websvn.kolibrios.org/filedetails ... %2Fapp.lds там должно быть MENUET02, а version = 1.
  • 0CodErr wrote:Leency, там всё та же SetLDTEntries, которая под x64 работать не будет.
    Leency wrote:Vista/7/10
    pavelyakov wrote:Из-за чего с windows 7 и выше не запускается? Это возможно из-за защиты windows?
    Насколько я смог нагуглить, это появилось в одном из обновлений безопасности на семёрке.
    То есть, теоретически, на каких-то семёрках оно может работать.
    Возможно на висте работает.
    Мой вариант не использует SetLDTEntries, и, по идее(если я ничего больше не упустил :roll: ) должен на x64 тоже запуститься.
    Из history.txt к KlbrInWin:
    25.07.2013 Поправлен код для работы после какого-то прилетевшего обновления Win7. Теперь для работы в реестре нужен параметр HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\KlbrInWin.exe\EnableLowVaAccess:DWORD = 1.
    0CodErr wrote:Значит в linux нельзя выделить память в нуле.
    https://wiki.debian.org/mmap_min_addr
    Сделаем мир лучше!
  • Уау, Мышь жива 0/
  • Больше проект не развивали?
  • Как понимаю, теперь развивается здесь. За регистрацией обращаться ко мне, если вдруг (закрыта из-за спамеров).
  • Who is online

    Users browsing this forum: No registered users and 2 guests