MEMTEST.EFI

Тема в разделе "WASM.WIN32", создана пользователем Entropy, 11 сен 2020.

  1. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    Приветствую,тут под моё внимание попала одна виндовая прога под названием memtest.efi это прога для теста RAM,так вот возникают такие вопросы к каким сервисам или апи даннная прога обращается ?,что нужно что бы разработать такую же прогу ? задачу она будет решать совсем другую, не тест RAM.Я гуглил на тему разработки таких приложений мне так найти и не удалось ничего.
     
  2. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    *.efi это формат загрузочных файлов и модулей UEFI.
    Статей на эту тему мало. Вот к примеру
    https://habr.com/ru/post/274463/

    АПИ описан в спецификации
    https://www.uefi.org/sites/default/files/resources/UEFI Spec 2_6.pdf
    Первые версии попроще будут.
    https://www.intel.com/content/dam/www/public/us/en/zip/efi-110.zip

    Лучше смотреть исходный код биосов и загрузчиков.
    https://github.com/fpmurphy/UEFI-Utilities
    https://github.com/linuxboot/linuxboot
    https://github.com/pbatard/uefi-ntfs/blob/master/boot.c
     
  3. njeen

    njeen Active Member

    Публикаций:
    0
    Регистрация:
    26 мар 2017
    Сообщения:
    139
    Адрес:
    Ташлинск
    краткое вступление
    http://x86asm.net/articles/uefi-programming-first-steps/index.html

    Как писать - можно сразу на fasm'е . Если на C - нужен developement kit. Как сейчас не знаю - года 4 назад были самые используемые публичные это edk2 и Gnu efi. Первый заточен под студию, второй - под ГНУтое.
    Что в программе можно сделать - в функции main передаются параметры. Один из двух - это указатель на структуру EFI_SYSTEM_TABLE - что-то вроде рантайма + всяких структур. Через неё дергаются другие функции, работают с другими модулями и т.д. Про это надо читать соотв. доки по efi. Вообще, бОльшая часть кодинга под efi - чтение документации.

    Как это проверять.
    Если просто запустить приложение - из efi биоса загрузить EFI Shell (у вмвари есть вроде даже встроенная), из которой запустить приложение.
    А поотлаживать - на эмуляторе. Есть виндовый псевдоэмулятор ( но как-то имхо, не очень).
    Есть вариант встроить в efi биос vmware - выдрать из exe'шника её 'родной' биос виртуалки, добавить свое поделие чем-то вроде uefitool (тут надо понимать что и куда, а это читать оф. доки по efi) и дебажить по wmware gdb stub + Ida - реально почти как на реальном биосе ведет себя.
    Или qemu с ovmf bios .

    В реальный efi биос, скорее всего, просто встроить не получится - часто какая-то защита, нужно отключать.
     
  4. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    njeen, memtest.efi я уже пробовал запускать в efi shell,он не запускается,и вообще структура memtest.efi и того PE файла что генерит edk2 очень сильно отличается,к примеру тот PE файл что генерит edk2 у него поле ImageBase = 0,винда с нулевым ImageBase файл не запустит,и у меня возникает такое предположение что memtest.efi ни какого абсолютно отношения к UEFI не имеет,то есть это чисто виндовая прога.Я даже на реальной машине с UEFI пробовал запустить memtest.efi
     
  5. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    Если кто не понял,то я имел ввиду средство диагностики памяти Windows
     
  6. njeen

    njeen Active Member

    Публикаций:
    0
    Регистрация:
    26 мар 2017
    Сообщения:
    139
    Адрес:
    Ташлинск
    Если все еще интересно.
    Данные приложения boot application, вроде memtest, действительно не запускаются обычным образом.
    Подсистема установлена у них в 0x10.
    Но это efi приложения, только ожидающие в entry point другие параметры, которые скомпоновал виндовый boot manager. То есть, на точке входа такое приложение первым параметром ожидает указатель на структуру BOOT_APPLICATION_PARAMETER_BLOCK . Из нее можно получить стандартные efi'шные как-то так:
    Код (Text):
    1.  
    2.     BL_FIRMWARE_DESCRIPTOR* fwdesc =
    3.         (BL_FIRMWARE_DESCRIPTOR*)(((UINTN)BootAppParameters) + BootAppParameters->FirmwareParametersOffset);
    4.     EFI_HANDLE ImageHandle = fwdesc->ImageHandle;
    5. EFI_SYSTEM_TABLE* SystemTable = fwdesc->SystemTable;
    6.  
    Только в них как-то странно обстоят дела с выводом на экран - его при попытке вывести, например, строку не видно вообще. И запустить это приложение надо не просто так - либо подписать чем-то, либо отключить подпись для этого пункта загрузки.
    Например, так
    bcdedit.exe /set {MY_GUID} loadoptions DDISABLE_INTEGRITY_CHECKS
    где MY_GUID - гуид корректно добавленной записи типа boot application в windows boot manager.
    У меня пока вышло только заставить запуститься без ругательств со стороны windows boot manager'а.

    Например, вот товарищ сделал такое boot application приложение, только под ARM'овый виндофон https://github.com/imbushuo/boot-shim.git . Там сделано вне edk2, и подписывает к тому же.
    И дискуссия про это http://reboot.pro/index.php?showtopic=17655&page=3 .

    Где еще можно об этом узнать - товарищ Ионеску заикался про какие-то свои курсы, как писать такие приложения, но в доступе нигде не нахожу. Также он вносит вклад в reactos - может, там какие-то следы есть.
     
  7. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    njeen, я об этом с самого начала и толковал,к тому же у этого memtest предположительно имеются хардварные привелегии,глянул туда дизасмом обнаружил команды для отключения кэша процессора
     
  8. KPG

    KPG Member

    Публикаций:
    0
    Регистрация:
    13 янв 2021
    Сообщения:
    121
    Не совсем понял про какую версию Memtest.efi речь, но сам запускал такое приложение под Uefi на Atom буке.
    (входит, вроде, в сборку Strelec)
    Всё красиво выглядит в графике UEFI, но из проявившихся "шероховатостей" - медленное перемещение мыша (клавишами быстрее)
     
  9. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    речь идёт об этом C:\Windows\Boot\EFI\memtest.efi
    --- Сообщение объединено, 27 апр 2021 ---
    файл по пути C:\Windows\Boot\EFI\memtest.efi, в дизассемблере IDA Version 7.0.191002 Freeware
    --- Сообщение объединено, 27 апр 2021 ---
    Windows 7 x64
     

    Вложения:

    • dis.PNG
      dis.PNG
      Размер файла:
      79,7 КБ
      Просмотров:
      318
  10. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    Значица предоставляем себе возможность для запуска Windows boot приложений,за средство диагностики памяти отвечает загрузочная запись {memdiag},путём её модификации предоставим себе такую возможность,модифицировать будем следующим образом:

    1.Определяем раздел где находится приложение

    Код (Text):
    1.  
    2. bcdedit /set {memdiag} device PARTITION=C:
    2.Указываем путь к приложению с подсистемой 0x10

    Код (Text):
    1. bcdedit /set {memdiag} path \Windows\Boot\EFI\memtest.efi
    3.Вносим однократную запись в менеджер загрузок {bootmgr},эта запись будет использована всего 1 раз

    Код (Text):
    1. bcdedit /bootsequence {bootmgr} {memdiag}
    --- Сообщение объединено, 30 апр 2021 ---
    после того как внесли однократную запись перезагружаемся и должно запуститься это приложение,в заголовке должна быть правильная контрольная сумма
     
    q2e74 нравится это.
  11. njeen

    njeen Active Member

    Публикаций:
    0
    Регистрация:
    26 мар 2017
    Сообщения:
    139
    Адрес:
    Ташлинск
    Не выводились сообщения в моем тестовом boot application приложении вот почему. Потому, что boot application запускаются в protected mode, а работа с efi функционалом возможна только в real mode. И , например, чтобы вывести строку в консоль, они переключаются в real mode, дергают efi функции , затем возвращаются обратно.

    Моя догадка была правильной - тов. Ионеску сделал приложение в составе реактоси - аналог bootmgr. Можно даже изучать. https://doxygen.reactos.org/dir_e979f1c4d9aec725da11c29584d02043.html
     
  12. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    но есть системы где efi нет,тогда в этом случаи какое будет у них поведение ?
    --- Сообщение объединено, 2 май 2021 ---
    Мне всё таки удалось запустить boot application,но для этого его пришлось подписать тестовым сертификатом,и проделать вот это

    Код (Text):
    1. bcdedit /set {bootmgr} TESTSIGNING 1
    ну а далее это приложение я расположил в C:\Windows\Boot\EFI\

    разумеется я его назвал memtest.efi
     
    Последнее редактирование: 2 май 2021
  13. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    в файле memtest.efi заметил секцию .reloc,если делаем такое же приложение то скорее всего её надо сгенерировать
     
  14. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    И так я написал такое приложение на ассмеблере,оно ничего не делает,без секции .reloc оно запустилось

    вот код на MASM64:
    memtest.asm

    Код (ASM):
    1. public startup
    2.  
    3. .data            
    4.  
    5. argb db 0        
    6.  
    7.  
    8. .code            
    9.  
    10. startup:          
    11.  
    12. hlt
    13.  
    14. jmp startup
    15.  
    16.  
    17. end
    18.  
    компилим:
    Код (Text):
    1.  
    2. ml64 memtest.asm
    3.  
    линкуем:
    Код (Text):
    1. link memtest.obj /SUBSYSTEM:BOOT_APPLICATION /ENTRY:startup
    --- Сообщение объединено, 20 май 2021 ---
    запускал это приложение на Windows 7 x64 Корпоративная
     
  15. njeen

    njeen Active Member

    Публикаций:
    0
    Регистрация:
    26 мар 2017
    Сообщения:
    139
    Адрес:
    Ташлинск
    А чому б ему не запуститься? Это всего лишь pe dll с измененной точкой входа и без импорта. И с поменянным признаком подсистемы.
     
  16. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    Всем спасибо !
     
  17. njeen

    njeen Active Member

    Публикаций:
    0
    Регистрация:
    26 мар 2017
    Сообщения:
    139
    Адрес:
    Ташлинск
    Вдруг кому-то пригодится.

    Как написать рабочее windows boot application приложение, чтобы оно корректно
    работало под x86_64 как обычное efi приложение
    .

    1. Описание

    Windows efi boot appliation - это тоже efi приложение, то со своими
    "особенностями".
    Отличия от обычного efi app:
    - в опциональном PE заголовке поле subsystem должно быть установлено в 0x10
    - точка входа отличается - вместо привычной UefiMain, у которой 2 входных
    параметра EFI_HANDLE и EFI_SYSTEM_TABLE *, у этого типа прилложений точка
    входа имеет один параметр, который передает ей windows boot manager. И это
    указатель на недокументированную структуру BOOT_APPLICATION_PARAMETER_BLOCK.
    Из него можно, в том числе, добыть привычные нам EFI_HANDLE и
    EFI_SYSTEM_TABLE *.
    - Есть такое понятие у данных приложений, как "режим выполнения", или
    "контекст". Контекст бывает application context и firmware context.
    Firmware context - это контекст, в котором работают "обычные" efi
    приложения. Контекст application - это контекст, в котором изначально
    работают windows boot applications.
    Контекст определяется состоянием регистра cr3 и тем, разрешены ли
    прерывания.
    Можно переходить из одного режима в другой, переключая контекст.
    Это возможно, т.к при старте windows boot application мы имеем состояние
    регистра cr3 для контекста application context - и можем его где-то сохранить, а
    firmware context cr3 можно добыть посредством указателя на
    BOOT_APPLICATION_PARAMETER_BLOCK, полученном в entry point.
    Также в firmware context'е прерывания должны быть разрешены. В случае
    application context - запрещены.

    Если изменить контекст на firmware context, и добыть параметры EFI_HANDLE и
    EFI_SYSTEM_TABLE *, то можно вызывать "обычную" efi application entry point.
    Чтобы корректно "вернуться" после завершения программы, надо вернуть контекст
    в изначальное состояние.

    Зачем может понадобиться делать такие приложения - можно, например, сделать
    прокси загрузчик efi загрузчиков других ОС, которые не могут быть добавлены в
    windows boot menu непосредственно. Этот прокси загрузчик будет подгружать
    образ соотв. настоящего загрузчика и запускать его на выполнение.
    Либо можно прямо из опций загрузки windows запускать efi shell. Или вообще
    любое другое приложение.
    Либо подгружать загрузчик windows, делать небольшие, но очень необходимые
    патчи, и также запускать на выполнение.

    2. Пример реализации

    Данный пример просто переходит в контекст firmware, запускает "обычную" efi
    application entry функцию, выводит hello world на экран, корректно
    возвращается из нее, переключает контекст обратно.
    Текст выводится очень быстро, поэтому, чтобы увидеть, можно, например, сделать
    перед возвратом управления бесконечный цикл.

    Также нужно помнить, что у собираемого efi subsystem должна быть проставлена в
    0x10, иначе виндовый загрузчик не найдет приложение того типа, которое ищет.

    Текст программы усечен, реализация обычной efi части основана на
    http://x86asm.net/articles/uefi-programming-first-steps/index.html

    Код (ASM):
    1. format pe64 dll efi
    2. entry BaMain
    3.  
    4.  
    5. section '.text' code executable readable
    6.  
    7.  
    8. ; EFI_STATUS
    9. ; EFIAPI
    10. ; BaMain(BOOT_APPLICATION_PARAMETER_BLOCK * BootAppParameters)
    11. BaMain:
    12.     ;jmp short BaMain                   ; debug loop
    13.     ; get 'normal' efi entry parameters from boot parameters
    14.     mov [BootAppParameters], rcx        ; save address to boot parameters
    15.     mov r8d, dword [rcx+0x30]           ; get UINT32 FirmwareParametersOffset from BOOT_APPLICATION_PARAMETER_BLOCK
    16.     lea r8, [rcx+r8]                    ; get BL_FIRMWARE_DESCRIPTOR address
    17.     mov [firmwareDescriptorAddress], r8
    18.     mov rax, qword [r8+0x8]             ; get BL_FIRMWARE_DESCRIPTOR::ImageHandle by offset 0x8
    19.     mov [ImageHandle], rax
    20.     mov rax, qword [r8+0x10]            ; get BL_FIRMWARE_DESCRIPTOR::SystemTable address by offset 0x10
    21.     mov [SystemTable], rax
    22.  
    23.     ; we're in 'application context' and it stored now in cr3.
    24.     mov rax, cr3
    25.     mov [appContext], rax
    26.  
    27.     mov rax, qword [r8+0x1c]            ; saved firmware context is stored by
    28.                                         ; offset 0x1c in BL_FIRMWARE_DESCRIPTOR .
    29.                                         ; Seems to be undocumented.
    30.     mov [firmwareContext], rax
    31.  
    32.     call SwitchToFirmwareContext
    33.     mov rcx, [ImageHandle]
    34.     mov rdx, [SystemTable]
    35.     sub rsp, 4*8                        ; reserve space for 4 arguments for ms stdcall x64 function callings
    36.     call UefiMain
    37.     add rsp, 4*8
    38.     push rax                            ; save result from UefiMain
    39.     call SwitchToApplicationContext
    40.     pop rax
    41.  
    42. ;@@:                                    ; debug loop to show written text
    43.     ;jmp short @b
    44.  
    45.     retn
    46.  
    47. SwitchToFirmwareContext:
    48.     mov rax, [firmwareContext]
    49.     mov cr3, rax
    50.     sti
    51.     retn
    52.  
    53. SwitchToApplicationContext:
    54.     cli
    55.     mov rax, [appContext]
    56.     mov cr3, rax
    57.     retn
    58.  
    59. ; EFI_STATUS
    60. ; EFIAPI
    61. ; UefiMain (
    62. ;   IN EFI_HANDLE        ImageHandle,
    63. ;   IN EFI_SYSTEM_TABLE  *SystemTable
    64. ;   )
    65. UefiMain:
    66.     sub rsp, 4*8                ; reserve space for 4 arguments
    67.     mov [ImageHandle], rcx      ; ImageHandle
    68.     mov [SystemTable], rdx      ; pointer to SystemTable
    69.  
    70.     lea rdx, [_hello]
    71.     mov rcx, [SystemTable]
    72.     mov rcx, [rcx + 0x40]       ; [rcx + EFI_SYSTEM_TABLE.ConOut]
    73.     call qword [rcx + 8]        ; [rcx + SIMPLE_TEXT_OUTPUT_INTERFACE.OutputString]
    74.  
    75.     add rsp, 4*8
    76.     mov rax, 0                  ; EFI_SUCCESS
    77.     retn
    78.  
    79.  
    80. section '.data' data readable writeable
    81.  
    82. BootAppParameters   dq ?
    83. firmwareDescriptorAddress  dq ?
    84. appContext          dq ?
    85. firmwareContext     dq ?
    86.  
    87. ImageHandle      dq ?
    88. SystemTable      dq ?
    89.  
    90. _hello      du 'Hello World',0xd,0xa,'(From windows boot app written in FASM)',0xd,0xa,0x0
    91.  
    92. section '.reloc' fixups data discardable
    93.  
    3. Добавление пункта с приложением в список загрузки windows boot manager (пример)

    - Нужно смонтировать boot volume на какую-нибудь букву. Пусть это будет K:
    - скопировать наш efi (boothello.efi) в папку \EFI\Boot\
    - с помощью bcdedit.exe добавить соотв. запись в список загрузки:

    bcdedit /create /application bootapp /d "HelloBoot"
    Это создаст новую запись в бд boot manager'а, в результате выведется guid
    созданной записи. Дальше - <GUID>.

    bcdedit /set <GUID> path "\EFI\Boot\boothello.efi"
    Задаем путь к программе.

    bcdedit /set <GUID> device partition=k:
    Задаем раздел, к которому у нас сейчас примонтирован efi том

    bcdedit /displayorder <GUID> /addlast
    Добавим видимую строку в список загрузки

    bcdedit.exe /set <GUID> loadoptions DDISABLE_INTEGRITY_CHECKS
    Выключаем проверку crc приложения для данного guid

    bcdedit.exe /set {MY_GUID} nointegritychecks on
    Отключаем проверку того, подписано ли приложение.

    Если у вас crc корректный и вы сумели корректно подписать, то последние два
    пункта можно не делать ^^ .

    Ну и далее все - можно перезагружать и любоваться строчками текста, если все
    сделали правильно.
     
    Aiks нравится это.
  18. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    В Win10 наверно работать не будет