Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Assembler > Как проверить поддержку расширенного режима работы с int 13h из-под Windows?


Автор: Jin X 28.06.18, 11:45
Всем привет.
Необходимо из-под Windows (включая x64) проверить - поддерживает ли BIOS'овский int 13h расширенные функции работы с дисками (ah=4xh... 64-битную LBA-адресацию, по сути). Можно ли это сделать? И как?

Т.е. пишется код для MBR, который будет использовать эти функции, но инсталлироваться он будет из-под Windows.
Соответственно, если BIOS не поддерживает такие функции, загрузка будет невозможна.
Поэтому нужна предварительная проверка.

Я понимаю, что такая поддержка появилась уже давным-давно, но всё же для надёжности хочется сделать проверку.
И я понимаю, что диск можно перенести на другой комп, где может быть по-другому, тем не менее.

Автор: core-i7 24.09.18, 12:45
Цитата Jin X @
проверить - поддерживает ли BIOS'овский int 13h расширенные функции работы с дисками (ah=4xh... 64-битную LBA-адресацию, по сути). Можно ли это сделать? И как?

можно попробовать считать SMBIOS/ACPI таблицы
бит 19 в разделе BIOS хранит инфу о поддержке EDD - Enhanced-Disk-Drive:
Скрытый текст
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    [BIOS Information] (Type 0)
    00 18 00 00 01 02 00 F0 03 07 80 9A 8B 7F 01 00 ................
    00 00 33 07 08 0C FF FF 41 6D 65 72 69 63 61 6E ..3.....American
    20 4D 65 67 61 74 72 65 6E 64 73 20 49 6E 63 2E  Megatrends Inc.
    00 50 31 2E 32 30 00 30 32 2F 30 35 2F 32 30 30 .P1.20.02/05/200
    39 00 00                                        9..            
     
    Type                    0x00 (0)
    Length                  0x18 (24)
    Handle                  0x0000 (0)
    BIOS Vendor         String1 - "American Megatrends Inc."
    BIOS Version            String2 - "P1.20"
    Start Address Segment   0xF000
    Release Date            String3 - "02/05/2009"
    ROM Size            0x07 (512KB)
    BIOS Characteristics    0x000000017F8B9A80
      Bit0                  Reserved - 0 (No)
      Bit1                  Reserved - 0 (No)
      Bit2                  Unknown - 0 (No)
      Bit3                  BIOS Characteristics Not Supported - 0 (No)
      Bit4                  ISA is supported - 0 (No)
      Bit5                  MCA is supported - 0 (No)
      Bit6                  EISA is supported - 0 (No)
      Bit7                  PCI is supported - 1 (Yes)
      Bit8                  PC Card (PCMCIA) is supported - 0 (No)
      Bit9                  Plug and Play is supported - 1 (Yes)
      Bit10                 APM is supported - 0 (No)
      Bit11                 BIOS is Upgradeable (Flash) - 1 (Yes)
      Bit12                 BIOS shadowing is allowed - 1 (Yes)
      Bit13                 VL-VESA is supported - 0 (No)
      Bit14                 ESCD support is available - 0 (No)
      Bit15                 Boot from CD is supported - 1 (Yes)
      Bit16                 Selectable Boot is supported - 1 (Yes)
      Bit17                 BIOS ROM is socketed - 1 (Yes)
      Bit18                 Boot From PC Card (PCMCIA) is supported - 0 (No)
      Bit19                 EDD (Enhanced Disk Drive) Specification is supported - 1 (Yes)
      Bit20                 Int 13h - Japanese Floppy for NEC 9800 1.2mb (3.5", 1k Bytes/Sector, 360 RPM) is supported - 0 (No)
      Bit21                 Int 13h - Japanese Floppy for Toshiba 1.2mb (3.5", 360 RPM) is supported - 0 (No)
      Bit22                 Int 13h - 5.25" / 360 KB Floppy Services are supported - 0 (No)
      Bit23                 Int 13h - 5.25" / 1.2MB Floppy Services are supported - 1 (Yes)
      Bit24                 Int 13h - 3.5" / 720 KB Floppy Services are supported - 1 (Yes)
      Bit25                 Int 13h - 3.5" / 2.88 MB Floppy Services are supported - 1 (Yes)
      Bit26                 Int 5h, Print Screen Service is supported - 1 (Yes)
      Bit27                 Int 9h, 8042 Keyboard services are supported - 1 (Yes)
      Bit28                 Int 14h, Serial Services are supported - 1 (Yes)
      Bit29                 Int 17h, Printer Services are supported - 1 (Yes)
      Bit30                 Int 10h, CGA/Mono Video Services are supported - 1 (Yes)
      Bit31                 NEC PC-98 - 0 (No)
    Characteristics Ext1    0x33
      Bit0                  ACPI supported - 1 (Yes)
      Bit1                  USB Legacy is supported - 1 (Yes)
      Bit2                  AGP is supported - 0 (No)
      Bit3                  I2O boot is supported - 0 (No)
      Bit4                  LS-120 boot is supported - 1 (Yes)
      Bit5                  ATAPI ZIP Drive boot is supported - 1 (Yes)
      Bit6                  1394 boot is supported - 0 (No)
      Bit7                  Smart Battery supported - 0 (No)
    Characteristics Ext2    0x07
      Bit0                  BIOS Boot Specification supported - 1 (Yes)
      Bit1                  Function key-initiated Network Service boot supported - 1 (Yes)
      Bit2                  Enable Targeted Content Distribution - 1 (Yes)
      Bit3                  UEFI Specification is supported - 0 (No)
      Bit4                  SMBIOS table describes a virtual machine - 0 (No)
    BIOS Release            8.12
    EC Release          0xFFFF - Not supported

только универсального метода подобраться к этим таблицам из юзер-моды вроде нет
до Win-XP включительно можно функцией NtOpenSection (Device\PhysicalMemory)
а начиная с висты уже легче.. там есть GetSystemFirmwareTable

Автор: Jin X 24.09.18, 14:50
GetSystemFirmwareTable (вместе с EnumSystemFirmwareTables) у меня не пашет, возвращает нули, а GetLastError = 1 (ERROR_INVALID_FUNCTION)
Win10 x64

Автор: core-i7 24.09.18, 15:42
а kernel32.dll вообще экспортирует эту функцию, проверял?
можно прямо в тотале открыть по [Ctrl+Q] кернел32, и посмотреть экспорт.
у меня ХР - FirmwareTable в списке нет, соответственно и проверить не могу

Автор: Jin X 24.09.18, 15:54
core-i7, конечно экспортирует, иначе прога не запустилась бы (или GetProcAddress выдал бы 0, если через него делать).

Автор: Славян 24.09.18, 15:58
Да, EnumSystemFirmwareTables и GetSystemFirmwareTable экспортируются в Win10 x64 из kernel32.dll.

Автор: core-i7 24.09.18, 15:58
в подвале этого линка есть пример (176 Kb), попробуй его запустить на своей десятке.
он открывает доступ к физ.памяти чз 'Device\PhysicalMemory'.. чем чёрт не шутит:
http://www.delphiplus.org/articles/api/mem_read/index.html

Добавлено
Цитата Jin X @
конечно экспортирует

тогда GetLastError не должен возвращать единицу INVALID_FUNCTION

Автор: Jin X 24.09.18, 16:44
Цитата core-i7 @
он открывает доступ к физ.памяти чз 'Device\PhysicalMemory'.. чем чёрт не шутит
Даже в описании функции GetSystemFirmwareTable написано:
Цитата
As of Windows Server 2003 with Service Pack 1 (SP1), applications cannot access the \Device\PhysicalMemory object. Access to this object is limited to kernel-mode drivers.
Но я попробовал, конечно (от админа). И ничего не вышло. Что неудивительно :)
Но там GetSystemFirmwareTable даже и не используется.

Цитата core-i7 @
тогда GetLastError не должен возвращать единицу INVALID_FUNCTION
Какая тут связь? Если функция не экспортируется, прога просто не запускается, а ошибка "invalid function" выдаётся во многих других случаях.

Автор: Славян 24.09.18, 16:59
У меня GetSystemFirmwareTable успешно отрабатывает.

Автор: core-i7 24.09.18, 17:26
Цитата Jin X @
Какая тут связь?

..прямая! если функция в библиотеке есть, она должна отработать.
в противном случае, вина лежит на программисте - возможно криво оформил или нет прав

Добавлено
Цитата Славян @
У меня GetSystemFirmwareTable успешно отрабатывает.

а можно посмотреть, что она возвращает в буфер?

Автор: Славян 24.09.18, 18:38
Конечно можно. Только я 'от балды' запилил в аргументы значения из справки:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    char pBufffer[512];
    unsigned ret = GetSystemFirmwareTable( 'ACPI', 'PCAF', pBufffer, sizeof(pBufffer));
Она и вернула 0xF4 байт всяких двоичных данных.

Автор: core-i7 24.09.18, 18:56
Славян буфер для данных smbios нужен как-мин 1000h, и дальше:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // Получить таблицу SMBIOS
    bytesWritten = GetSystemFirmwareTable ('RSMB', 0, smBiosData, smBiosDataSize);


Добавлено
размер буфера можно получить так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // Размер данных SMBIOS.
    smBiosDataSize = GetSystemFirmwareTable ('RSMB', 0, NULL, 0);

Автор: Славян 24.09.18, 18:58
Хор. Минутку.

Добавлено
Ну получил. Вагон двоичных данных. Там есть и этот Megatrends, название мат.платы и всё такое. Что именно надо?

Автор: core-i7 24.09.18, 19:07
в шапке там должно быть типа такого (по крайней мере у меня)..
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    [SMBIOS Entry]  0x000FAFF0
    5F 53 4D 5F C3 1F 02 04 BA 00 00 00 00 00 00 00 _SM_............
    5F 44 4D 49 5F C4 65 04 40 D6 0F 00 16 00 00    _DMI_.e.@......
     
    Anchor String              _SM_
    Checksum               0xC3
    Length                     0x1F
    Version                    2.4
    Maximum Structure Size     0x00BA
    Entry Point Revision       0x00
    Formatted Area             0x00 0x00 0x00 0x00 0x00
    Intermediate Anchor    _DMI_
    Intermediate Checksum      0xC4
    Structure Table Length     0x0465         <-- общий размер SMBIOS-таблицы
    Structure Table Address    0x000FD640     <-- адрес первой таблицы (данные BIOS)
    Number of Structures       0x0016         <-- всего структур
    wNumSMBStruc               0x00

Автор: Славян 24.09.18, 19:19
Всё, вкурил. Там почти как и в вашем примере. Только у вас хвост: 80 9A 8B 7F 01, а у меня 90 DA 8B 7F 01.
Т.е. у меня ISA Supported, и EDD тоже есть.

Автор: core-i7 24.09.18, 19:21
Славян ну вот.. значит фишка работает.. спасибо!

Автор: Славян 24.09.18, 19:22
А, ещё у меня (ибо DA, а не 9A):
Bit14 ESCD support is available - 1 (Yes)

Добавлено
Да, работает. Непонятно, всё же, почему у Jin X не пашет. :'(

Автор: core-i7 24.09.18, 19:37
а вообще, тут достаточно двух строк в консоли:
wmic partition get type

Автор: Jin X 24.09.18, 19:38
Да, это я прогнал :facepalm:
Короче, писал на Delphi 7 и на fasm.
В Delphi забыл поставить stdcall в определении функций. А в fasm указывал строкой, но она почему-то не заносилась в стек вообще (при подключении win32ax.inc, а вот с win32a.inc всё работает).
Конкретно этот бит пока не проверял, но думаю, всё сработает, спасибо за инфу ;)

Автор: core-i7 24.09.18, 19:40
возвращает тип разделов, среди которых должен быть и 'Extended int-13'

Добавлено
Цитата
но думаю, всё сработает, спасибо за инфу

я - так вообще не проверял.. (у меня XP 32-бит)
чисто в теории должно было работать

Автор: Jin X 24.09.18, 20:15
Какие-то странноватые данные выходят. Я же правильно понял, что "BIOS Characteristics" находится по смещению 0Ah?
У меня там 7F03F00002010000h (00 00 01 02 00 F0 03 7F), т.е. 19-й бит сброшен. Хотя EDD однозначно поддерживается.
А по смещению 2 байт = 2 (а это как бы размер форматированных данных, включая заголовок). При этом первый байт (тип структуры) = 0 (т.е. должно быть всё ок).

Добавлено
Опа, а вот по смещению 8 начинается нормальный заголовок: тип 0, размер 18h и дальше по смещению 0Ah (относительно 8-го байта) идёт число 13F8B9880h (80 98 8B 3F 01 00 00 00), 19-й бит стоит! Ура!
Осталось теперь разобраться, почему у меня первые 8 байт – какая-то лажа...

Добавлено
Первые 8 байт: 00 02 07 00 2B 0C 00 00, а дальше уже 00 18 00 00 01 02 00 F0
Если это всё массив структур, то почему второй байт (размер) = 2 ?
Если размер этого блока = 2 байтам, то далее идёт тип 7 и размер 0, но как размер может быть 0 ???
И как вообще понять, где нужный мне блок начинается (может, по сегменту F000)? Жесть какая-то... :wacko:

Добавлено
Цитата core-i7 @
в шапке там должно быть типа такого (по крайней мере у меня)
В какой шапке?
А вообще, эта таблица (в таком виде) из какой программы сграблена?

Добавлено
На всякий случай инфа из RBIL:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    Format of SMBIOS data structure:
    Offset  Size    Description     (Table F0059)
     00h  4 BYTEs   structure header
                    BYTE structure type (see #F0060)
                            80h-FFh available for system/OEM-specific data
                    BYTE length of formatted data, including header
                    WORD structure handle (a unique value 0000h-FEFFh [v2.0 allows
                              up to FFFEh])
                            handles FF00h-FFFFh are reserved for use by the SMBIOS
                              specification
                            handles need not be contiguous -- a handle might not
                              exist any more after a configuration change, but the
                              BIOS may not re-assign that handle number to another
                              structure
    ---type 00h---
     04h    BYTE    string number of the vendor name (string numbers are 1-based)
     05h    BYTE    string number of the version string (00h if not present)
     06h    WORD    starting segment of runtime BIOS
     08h    BYTE    string number of BIOS release date
     09h    BYTE    size of BIOS ROM (stored as one less than number of 64K units)
     0Ah    QWORD   BIOS characteristics (see #F0061)
     12h    var     optional space for BIOS characteristics extension
                      (see #F0062,#F0063)
                    (size of optional space is implied by header's length field)
     var    var     free-form ASCIZ strings (max 64 bytes per string)


Добавлено
Хотя, некоторая картинка вырисовывается, но как-то очень странно это.

(тут первые 2 цифра – смещение от начала)
00: тип = 0 (инфа о биосе(?))
01: размер = 2 (тут этот блок и закончился)
Далее пошли ASCIIZ-строки (в конце двойной ноль):
02: 07 00
04: 2B 0C 00 00

Новый блок:
08: тип = 0 (снова инфа о биосе)
09: размер = 18h (24)
0A: данные (22 оставшихся байта)
20: пошли строки

Новый блок (тут строки закончились):
48: тип = 1 (системная инфа)
49: размер = 1Bh (27 байт)
4A: данные (25 оставшихся байт)
63: начались строки (пока всё чётко)

Новый блок:
F5: тип = 2 (материнка)
F6: размер = 0Fh (15)
F7: данные (13 оставшихся байт)
104: начались строки...
и т.д.

Вроде как всё сходится.
Смущает только первый блок – нафига он? Почему у меня 2 блока инфы о биосе?

Автор: core-i7 25.09.18, 04:21
Jin X, мои логи из программы rw: http://rweverything.com/download/
я не вижу, что возвращает эта функция, ..но вы можете сравнить выхлоп функции "GetSystemFirmwareTable" с данными этой проги. По сути, там сперва должен идти заголовок (см.мой лог), а потом - сами структуры. В заголовке указывается кол-во структур в таблице.

RBIL (как я понял) это хелп Ральфа Брауна что-ли?
Лучше покурить SMBIOS/DMI спецификацию:
https://www.dmtf.org/sites/default/files/st...P0134_3.2.0.pdf

Автор: core-i7 25.09.18, 06:00
на всякий.. приведу расклад DMI-таблицы
по моим расчётам, GetSystemFirmwareTable должна была сбросить в буфер всю таблицу, включая заголовок, иначе разобраться в куче данных будет проблематично (нет описания таблицы). То-есть данные в буфере должны начинаться с сигнатуры _SM_. Ну и где-то должна валяться база таблицы [SMBIOS-Entry], чтобы дальше плясать от неё. Например вот лог, где указана линейная база 0x000FAFF0 (FAFF:0000) - дзебуг подтверждает Entry-Point:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    [SMBIOS Entry]  0x000FAFF0
    5F 53 4D 5F C3 1F 02 04 BA 00 00 00 00 00 00 00   _SM_............
    5F 44 4D 49 5F C4 65 04 40 D6 0F 00 16 00 00      _DMI_.e.@......
     
    Anchor String             _SM_
    Checksum                  0xC3
    Length                    0x1F
    Version                   2.4
    Maximum Structure Size    0x00BA
    Entry Point Revision      0x00
    Formatted Area            0x00 0x00 0x00 0x00 0x00
    Intermediate Anchor       _DMI_
    Intermediate Checksum     0xC4
    Structure Table Length    0x0465
    Structure Table Address   0x000FD640     <--- указатель на структуру 'BIOS-Info'
    Number of Structures      0x0016
    wNumSMBStruc              0x00

дальше, ..в заголовке видим адрес 0x000FD640 - это и есть адрес первой структуры 'BIOS-Info'.
Соответственно разница между ними: 0xFD640 - 0xFAFF0 = 0x2650 (~9K). Делаю вывод, что сама DMI-таблица находится в другом/свободном месте физ.памяти и не прижата к заголовку:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    [BIOS Information] (Type 0)
    00 18 00 00 01 02 00 F0 03 07 80 9A 8B 7F 01 00   ................
    00 00 33 07 08 0C FF FF 41 6D 65 72 69 63 61 6E   ..3.....American
    20 4D 65 67 61 74 72 65 6E 64 73 20 49 6E 63 2E   Megatrends Inc.
    00 50 31 2E 32 30 00 30 32 2F 30 35 2F 32 30 30   .P1.20.02/05/200
    39 00 00                                          9..            
     
    Type                      0x00 (0)
    Length                    0x18 (24)
    Handle                    0x0000 (0)
    BIOS Vendor               String1 - "American Megatrends Inc."
    BIOS Version              String2 - "P1.20"
    Start Address Segment     0xF000
    Release Date              String3 - "02/05/2009"
    ROM Size                  0x07 (512KB)
    BIOS Characteristics      0x000000017F8B9A80
      Bit0                    Reserved - 0 (No)
      Bit1                    Reserved - 0 (No)
      Bit2                    Unknown  - 0 (No)
      Bit3                    BIOS Characteristics Not Supported - 0 (No)


user posted image

Автор: Jin X 25.09.18, 11:13
core-i7, да, это Ralf Brown, но в спецификации SMBIOS такая же фигня, ничего про эту канитель со странными первыми 8-ю байтами я не нашёл.
В общем, я накатал вот такую прогу для проверки поддержки EDD:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ; fasm 1 (Windows Vista/XP Pro x64 +)
    format  PE Console 5.0
     
    include 'win32axp.inc'
    include 'simport.inc'
     
    ;-- CODE SECTION -------------------------------------------------------------------------------------------------------
     
    FirmText    equ 'RSMB'
    FirmSign    =   FirmText shr 24 + (FirmText shr 8) and 0xFF00 + (FirmText shl 8) and 0xFF0000 + (FirmText shl 24) and 0xFF000000
    FirmTable   =   0
     
    BUFFER_SIZE =   65536
    SHOW_READ_OK    =   1
    SAVE_TO_FILE    =   1
    SHOW_FLAG_QWORD =   1
     
    .code
     
    start:
     
            ; Read raw SMBIOS firmware table
            invoke  GetSystemFirmwareTable, FirmSign, FirmTable, Table, BUFFER_SIZE
            test    eax,eax
            jz  .readerror
            cmp eax,BUFFER_SIZE
            ja  .toolarge
            mov [TableSize],eax
    if defined SHOW_READ_OK & SHOW_READ_OK
            cinvoke printf, <FirmText,' table is read (size = %d bytes)!',10>, eax
    end if
     
    if defined SAVE_TO_FILE & SAVE_TO_FILE
            ; Save table to file
            stdcall SaveToFile
    end if
            ; Check of EDD support and show results
            stdcall GetBIOSChars
            jc  .notfound
     
    if defined SHOW_FLAG_QWORD & SHOW_FLAG_QWORD
            push    eax
            cinvoke printf, <'BIOS Characteristics QWORD = %08X%08X',10>, edx, eax
            pop eax
    end if
            btc eax,19
            jnc @F
            cinvoke printf, <'EDD is supported!',10>
            jmp .finish
        @@: cinvoke printf, <'EDD is NOT supported :(',10>
     
            ; Finalization
        .finish:
            cinvoke printf, <'Press a key to exit...',10>
            cinvoke getch
            invoke  ExitProcess, 0
        .readerror:
            cinvoke printf, <FirmText,' table read error :(',10>
            jmp .finish
        .toolarge:
            cinvoke printf, <FirmText,' table too large (%d bytes)',10>, eax
            jmp .finish
        .notfound:
            cinvoke printf, <'No correct BIOS Information structure is found :(',10>
            jmp .finish
     
    ; Get BIOS Characteristic QWORD (EDX:EAX, CF=0) or CF=1 on error
    proc        GetBIOSChars    uses esi
            ; Search for BIOS Information structure
            cld
            mov esi,Table
            mov edx,[TableSize]
            add edx,esi         ; table end
        .next:
            mov ecx,esi         ; structure start
            xor eax,eax
            lodsb               ; structure type
            cmp al,127
            je  .notfound       ; jump if end-of-table type
            test    al,al
            lodsb               ; structure size
            lea esi,[eax+ecx]       ; structure end, start of strings
            jnz .skipstrings        ; jump if type <> 0 (BIOS Information)
            cmp al,2
            jb  .notfound       ; WTF???
            cmp al,12h
            jnb .ok         ; no jump if bad structure (no BIOS Characteristics qword in this structure)
        .skipstrings:
        @@: mov ah,al           ; al <> 0 for the first time
            lodsb
            test    eax,eax
            jnz @B          ; searching for strings end (double 0)
            cmp esi,edx
            jb  .next           ; check next structure
            ; Structure is NOT found
        .notfound:
            stc             ; CF=1 (error)
            ret
        .ok:    ; Structure is found (CF=0, because jumped here by jnb = jnc)
            mov eax,[ecx+0Ah]       ; BIOS Characteristics low dword
            mov edx,[ecx+0Eh]       ; BIOS Characteristics high dword
            ret
    endp
     
    ; Save table to file
    proc        SaveToFile  uses ebx
            invoke  CreateFile, <FirmText,#'.bin'>, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
            cmp eax,INVALID_HANDLE_VALUE
            je  .createerror
            mov ebx,eax
            invoke  WriteFile, ebx, Table, [TableSize], Written, 0
            test    eax,eax
            jz  .writeerror
            cmp [Written],ebx
            jb  .writeerror
            cinvoke printf, <'Table is saved to file!',10>
        .continue:
            invoke  CloseHandle, ebx
            ret
        .createerror:
            cinvoke printf, <'File create error :(',10>
            ret
        .writeerror:
            cinvoke printf, <'File write error :(',10>
            jmp .continue
    endp
     
    ;-- DATA SECTION -------------------------------------------------------------------------------------------------------
     
    .data
     
    Written     rd  1
    TableSize   rd  1
    Table       rb  BUFFER_SIZE
    ZeroWord    rw  1
     
    simport     kernel32, GetSystemFirmwareTable
     
    slibrary    msvcrt, 'msvcrt.dll'
    simport     msvcrt,\
            printf, ,\
            getch, '_getch'
     
    .end        start

simport.inc:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ; WinAPI function import (written by Tomasz Grysztar, square brackets [] added by Jin X)
    ; usage:
    ;   simport kernel32, GetFirmwareEnvironmentVariableA  ; function name string can be omitted (like here)
    ;   api GetFirmwareEnvironmentVariable  ; only for functions with 'A' or 'W' suffix
    macro   simport library_label*, [label*, string]
    {
        match ,string \{ define library_label#.collection label,`label \}
        match any, string \{ define library_label#.collection label,string \}
    }
     
    ; wrapper of import macros (written by Tomasz Grysztar)
    macro   import  library_label*, list&
    {
        common
            local all
            define all
            irpv a, library_label#.collection \{ all equ all , a \}
            match a, list \{ all equ , list all \}
            match complete, all \{ import library_label complete \}
    }
     
    ; DLL library import (written by Tomasz Grysztar)
    ; usage:
    ;   slibrary msvcrt  ; dll name string can be omitted (like here)
    ;   simport msvcrt, printf  ; function name string can be omitted (like here)
    ;  or:
    ;   simport msvcrt, printf,, getch, '_getch', scanf
    macro   slibrary    library_label*, string
    {
        match ,string \{ define import_library library_label,`library_label#'.DLL' \}
        match any, string \{ define import_library library_label,string \}
    }
     
    ; wrapper of library macros (written by Tomasz Grysztar)
    macro   library list&
    {
        common
            local all
            define all
            irpv a, import_library \{ all equ all , a \}
            match complete, list all \{ library complete \}
            irpv a, import_library \{ match library_label=,string, a \\{ import library_label \\} \}
    }


Добавлено
Нашёл эи 8 байт!
Оказывается GetSystemFirmwareTable возвращает структуру:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct RawSMBIOSData
    {
        BYTE    Used20CallingMethod;
        BYTE    SMBIOSMajorVersion;
        BYTE    SMBIOSMinorVersion;
        BYTE    DmiRevision;
        DWORD    Length;
        BYTE    SMBIOSTableData[];
    };

Автор: Jin X 25.09.18, 12:31
Итого имеем...
EDDSupportCheck.fasm:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ; fasm 1 (Windows Vista/XP Pro x64 +)
    format  PE Console 5.0
     
    include 'win32axp.inc'
    include 'simport.inc'
     
    ;-- CODE SECTION -------------------------------------------------------------------------------------------------------
     
    FirmText    equ 'RSMB'
    FirmSign    =   FirmText shr 24 + (FirmText shr 8) and 0xFF00 + (FirmText shl 8) and 0xFF0000 + (FirmText shl 24) and 0xFF000000
    FirmTable   =   0
     
    MAX_TABLE_SIZE  =   65536
    BUFFER_SIZE =   MAX_TABLE_SIZE+8    ; 8 bytes of header
    SHOW_READ_OK    =   1
    ;SAVE_TO_FILE   =   1
    SHOW_FLAG_QWORD =   1
     
    .code
     
    start:
     
            ; Read raw SMBIOS firmware table
            invoke  GetSystemFirmwareTable, FirmSign, FirmTable, Buffer, BUFFER_SIZE
            test    eax,eax
            jz  .readerror
            cmp eax,BUFFER_SIZE
            ja  .toolarge
    if defined SHOW_READ_OK & SHOW_READ_OK
            movzx   ecx,[Buffer+1]
            movzx   edx,[Buffer+2]
            sub eax,8
            cinvoke printf, <'SMBIOS table is read (size = %d bytes + 8 bytes of raw data header)!',10,\
                     'SMBIOS version %d.%d',10>, eax, ecx, edx
    end if
     
    if defined SAVE_TO_FILE & SAVE_TO_FILE
            ; Save table to file
            stdcall SaveToFile
    end if
            ; Check of EDD support and show results
            stdcall GetBIOSChars
            jc  .notfound
     
    if defined SHOW_FLAG_QWORD & SHOW_FLAG_QWORD
            push    eax
            cinvoke printf, <'BIOS Characteristics QWORD = %08X%08X',10>, edx, eax
            pop eax
    end if
            btc eax,19
            jnc @F
            cinvoke printf, <'EDD is supported!',10>
            jmp .finish
        @@: cinvoke printf, <'EDD is NOT supported :(',10>
     
            ; Finalization
        .finish:
            cinvoke printf, <'Press a key to exit...',10>
            cinvoke getch
            invoke  ExitProcess, 0
        .readerror:
            cinvoke printf, <'SMBIOS table read error :(',10>
            jmp .finish
        .toolarge:
            cinvoke printf, <'SMBIOS raw table is too large (%d bytes)',10>, eax
            jmp .finish
        .notfound:
            cinvoke printf, <'BIOS Information structure is not found :(',10>
            jmp .finish
     
    ; Get BIOS Characteristic QWORD in EDX:EAX and address of structure start in ECX if CF=0 or CF=1 on error
    proc        GetBIOSChars    uses esi
            ; Search for BIOS Information structure
            cld
            mov esi,Table
            mov edx,[TableSize]
            add edx,esi         ; table end
        .next:
            mov ecx,esi         ; structure start
            xor eax,eax
            lodsb               ; structure type
            cmp al,127
            stc             ; CF=1 if next just will occur
            je  .finish         ; jump if end-of-table type
            test    al,al
            lodsb               ; structure size
            lea esi,[eax+ecx]       ; structure end, start of strings
            jz  .oktype         ; jump if type = 0 (BIOS Information)
            ; Skip strings
        @@: mov ah,al           ; AL <> 0 for the first pass
            lodsb
            test    eax,eax
            jnz @B          ; searching for strings end (double 0)
            cmp esi,edx
            jb  .next           ; check next structure (of continue with AL = 0)
        .oktype:
            cmp al,12h
            jb  .finish         ; jump if bad structure (structure must be at least 12h bytes in size) [CF=1]
            ; Structure is found [CF=0]
            mov eax,[ecx+0Ah]       ; BIOS Characteristics low dword
            mov edx,[ecx+0Eh]       ; BIOS Characteristics high dword
        .finish:
            ret             ; CF=0 if ok, CF=1 on error
    endp
     
    ; Save table to file
    proc        SaveToFile  uses ebx
            invoke  CreateFile, <'SMBIOSTable.bin'>, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
            cmp eax,INVALID_HANDLE_VALUE
            je  .createerror
            mov ebx,eax
            invoke  WriteFile, ebx, Table, [TableSize], Written, 0
            test    eax,eax
            jz  .writeerror
            cmp [Written],ebx
            jb  .writeerror
            cinvoke printf, <'Table is saved to file!',10>
        .continue:
            invoke  CloseHandle, ebx
            ret
        .createerror:
            cinvoke printf, <'File create error :(',10>
            ret
        .writeerror:
            cinvoke printf, <'File write error :(',10>
            jmp .continue
    endp
     
    ;-- DATA SECTION -------------------------------------------------------------------------------------------------------
     
    .data
     
    Buffer      rb  4
    TableSize   rd  1
    Table       rb  MAX_TABLE_SIZE
    ZeroWord    rw  1           ; just in case
     
    virtual at Buffer
      Written   rd  1
    end virtual
     
    simport     kernel32, GetSystemFirmwareTable
     
    slibrary    msvcrt, 'msvcrt.dll'
    simport     msvcrt,\
            printf, ,\
            getch, '_getch'
     
    .end        start

simport.inc:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ; WinAPI function import (written by Tomasz Grysztar, square brackets [] added by Jin X)
    ; usage:
    ;   simport kernel32, GetFirmwareEnvironmentVariableA  ; function name string can be omitted (like here)
    ;   api GetFirmwareEnvironmentVariable  ; only for functions with 'A' or 'W' suffix
    macro   simport library_label*, [label*, string]
    {
        match ,string \{ define library_label#.collection label,`label \}
        match any, string \{ define library_label#.collection label,string \}
    }
     
    ; wrapper of import macros (written by Tomasz Grysztar)
    macro   import  library_label*, list&
    {
        common
            local all
            define all
            irpv a, library_label#.collection \{ all equ all , a \}
            match a, list \{ all equ , list all \}
            match complete, all \{ import library_label complete \}
    }
     
    ; DLL library import (written by Tomasz Grysztar)
    ; usage:
    ;   slibrary msvcrt  ; dll name string can be omitted (like here)
    ;   simport msvcrt, printf  ; function name string can be omitted (like here)
    ;  or:
    ;   simport msvcrt, printf,, getch, '_getch', scanf
    macro   slibrary    library_label*, string
    {
        match ,string \{ define import_library library_label,`library_label#'.DLL' \}
        match any, string \{ define import_library library_label,string \}
    }
     
    ; wrapper of library macros (written by Tomasz Grysztar)
    macro   library list&
    {
        common
            local all
            define all
            irpv a, import_library \{ all equ all , a \}
            match complete, list all \{ library complete \}
            irpv a, import_library \{ match library_label=,string, a \\{ import library_label \\} \}
    }

EDDSupportCheck.zip (, : 153)

Добавлено
Можно, конечно, так не заморачиваться, а просто проверять первый байт (вернее, 9-й, т.е. со смещением 8, если брать Raw SMBIOS table) на значение 0, а второй - на значение 12h+ (чтоб был не меньше), а дальше уже по смещению 0Ah берём 19-й бит (а точнее test byte [Buffer+0Ch],8).

Добавлено
Хоть в спецификации и не сказано, что структура BIOS Information (тип 0) должна быть первой, наверняка всегда (или почти всегда) так и есть. Но я бы лучше подстраховался и сделал нормально (как в коде выше).

Автор: core-i7 25.09.18, 12:55
Jin X, прикольно.. закинем в сундучок.
а для систем ХР можно реализовать так-же, и читать SMBIOS хоть ком-файлом чз NTVDM

Автор: Jin X 25.09.18, 13:12
Так же, наверное, не выйдет, т.к. заветной функции нет в XP (32-битной, по крайней мере).
Можно попробовать через \\Device\PhysicalMemory. И там искать сигнатуру _SM_ или _SM3_ (я пока не понял, есть ли в SMBIOS 3.0 _SM_ тоже или только _SM3_) и дальше выходить на таблицу.

Добавлено
Ну или WMI как универсальный способ...

Автор: Jin X 25.09.18, 21:20
Короче, сделал я так, что теперь всё работает и на Windows XP, и на более свежих.
Правда, я не проверял, можно ли заменить NtOpenSection на CreateFile + CreateFileMapping, но не думаю, что тут будет какой-то профит (по размеру файла).
Ну и ещё, конечно, можно заменить MapViewOfFile на NtMapViewOfSection (чтобы раз начали с натива, то и дальше в том же духе), но пока заморачиваться не хочется, а хочется спать :)
Исходники в аттаче (постить в лом).
EDDSupportCheck.zip (, : 141)

Автор: core-i7 26.09.18, 06:10
Цитата Jin X @
теперь всё работает и на Windows XP, и на более свежих.

..у меня почему-то выдаёт эррор:
Цитата
SMBIOS table read error :(
Press a key to exit...

Автор: Jin X 26.09.18, 09:18
Хм, у меня на виртуалке работает.
Будем разбираться тогда. Запустите дебаг-версию, какие данные она выдаст?
EDDSupportCheckDEBUG.zip (, : 154)

Автор: Jin X 26.09.18, 10:28
Меня ещё смущает текст в спецификации SMBIOS:
Цитата
On non-UEFI systems, the 32-bit SMBIOS Entry Point structure, can be located by application software by searching for the anchor-string on paragraph (16-byte) boundaries within the physical memory address range 000F0000h to 000FFFFFh. This entry point encapsulates an intermediate anchor string that is used by some existing DMI browsers.

On UEFI-based systems, the SMBIOS Entry Point structure can be located by looking in the EFI Configuration Table for the SMBIOS GUID (SMBIOS_TABLE_GUID, {EB9D2D31-2D88-11D3-9A16-785 0090273FC14D}) and using the associated pointer. See section 4.6 of the UEFI Specification for details. See section 2.3 of the UEFI Specification for how to report the containing memory type.

Не совсем понятно: в UEFI-системах можно искать и так, и так? Потому что у меня UEFI, и сигнатура '_SM_' есть в диапазоне 0xF0000..0xFFFF0. А вот слова "also" в тексте "On UEFI-based systems, the SMBIOS Entry Point structure can be located" я что-то не вижу.

И ещё интересует момент: может ли эта таблица SMBIOS (где хранятся структуры с информацией типа BIOS Information, строки разные) находиться вне диапазона физ. адресов 0xF0000..0xFFFF0 ?
Может, встречаются такие случаи?

Автор: core-i7 26.09.18, 10:39
Jin X,

Цитата

>> $DEBUG: CF=1, EAX=0, EBP=101, NTSTATUS=0 (hex), GetLastError=487 (dec)
SMBIOS table read error :(
Press a key to exit...


Добавлено
Цитата Jin X @
Не совсем понятно: в UEFI-системах можно искать и так, и так?

UEFI эмулирует биос, поэтому вполне возможно..

Добавлено
Цитата Jin X @
И ещё интересует момент: может ли эта таблица SMBIOS находиться вне диапазона физ. адресов 0xF0000..0xFFFF0 ?

думаю, что только ниже первого мега.
точка входа указывается в заголовке, после сигнатуры _SM_
и лично мне не встречался адрес выше 1М

Автор: Jin X 26.09.18, 11:32
Цитата core-i7 @
EBP=101, ..., GetLastError=487 (dec)
MapViewOfFile выдаёт ошибку "Attempt to access invalid address."
Не понимаю, чего там инвалидного?
Сейчас попробуем читать не весь мегабайт, а 0xC0000..0xFFFFF.
Попробуйте ещё раз. Если будет опять ошибка, попробуйте запустить от админа (если там есть такая функция).

Цитата core-i7 @
думаю, что только ниже первого мега.
Про ниже 1 МБ логично (и я почти уверен, что так всегда).
Я сейчас посмотрел что происходит в VMware, там адрес таблицы – 0xE0010, так что, видимо, с 0xC0000 нужно начинать...
EDDSupportCheckDEBUG2.zip (, : 166)

Добавлено
Кстати, а у вас вот эта прога нормально работает?
http://www.delphiplus.org/articles/api/mem_read/index.html
Попробуйте прочитать адреса 0, 0xC0000, 0xF0000, 0xFF000.

Автор: core-i7 26.09.18, 12:29
Jin X, NtOpenSection выдаёт на экспорт файл 'ntoskrnl.exe'
у меня он экспортирует только WzOpenSection, а Nt в списке нет.
видимо в этом проблема..
система XP-SP3

Добавлено
Цитата Jin X @
Попробуйте ещё раз.

эта работает вроде..
Цитата
>> $DEBUG: CF=0, EAX=1125, EBP=105, NTSTATUS=0 (hex), LastError=127 (dec)
SMBIOS table is read (size = 1125 bytes)!
SMBIOS version 2.4
Table is saved to file!
>> $DEBUG: CF=0, EAX=2139855488, EBP=202, NTSTATUS=0 (hex), LastError=0 (dec)
BIOS Characteristics = 000000017F8B9A80 (hex)
EDD is supported!
Press a key to exit...


Добавлено
Цитата Jin X @
Кстати, а у вас вот эта прога нормально работает?

да.. нормально читает

Автор: Jin X 26.09.18, 16:53
Цитата core-i7 @
да.. нормально читает
В общем, почему-то MapViewOfFile не даёт доступа к физ. адресам 0-0x100000, но даёт к 0xC0000-0x100000. В общем-то, нам больше и не надо.

Цитата core-i7 @
эта работает вроде..
Работает на всём диапазоне?
Можете проверить диапазон первого МБ с интервалом 0x10000 ? :)

Проверил ещё в 2000 – всё нормально, а NT выдаёт ошибку 0xC000000D (STATUS_INVALID_PARAMETER). Прога mem_read.exe там тоже не работает.

В общем, сделал очередную версию с учётом исправлений.
EDDSupportCheck.zip (, : 160)

Автор: core-i7 26.09.18, 18:10
дебуг версия из последнего архива:
Цитата
>> $DEBUG: CF=0, EAX=1125, EBP=105, NTSTATUS=0 (hex), LastError=127 (dec)
SMBIOS table is read (size = 1125 bytes)!
SMBIOS version 2.4
Table is saved to file!
>> $DEBUG: CF=0, EAX=2139855488, EBP=202, NTSTATUS=0 (hex), LastError=0 (dec)
BIOS Characteristics = 000000017F8B9A80 (hex)
EDD is supported!
Press a key to exit...

..и релиз:
Цитата
SMBIOS table is read (size = 1125 bytes)!
SMBIOS version 2.4
Table is saved to file!
BIOS Characteristics = 000000017F8B9A80 (hex)
EDD is supported!
Press a key to exit...



если-бы мне приспичило, то я бы сделал конечно проще..
прописал-бы в тело программы батник, который сгенерит текстовый файл средствами WMI. В нём таже-самая инфа, что и получаем чз нативной API. Останется распарсить текст в бинарник, и просканить биты. Вот пример..
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    format   PE console
    include 'win32ax.inc'
    ;-------------------------
    .data
    rawName     db  'smbios.txt',0
    batName     db  'run.bat',   0
    batFile     db  'wmic.exe /Output:smbios.txt /Namespace:\\root\WMI Path MSSmBios_RawSMBiosTables Get /Format:LIST'
    batSize     dd   $ - batFile
     
    ;-------------------------
    .code
    start:
    ;-- создать BAT-файл (получим 'run.bat' для запуска WMI)
                invoke   _lcreat, batName, 0
                push      eax
                invoke   _lwrite, eax, batFile, [batSize]
                pop       eax
                invoke   _lclose, eax
     
    ;-- запустить батник на исполнение (получим таблицу SMBIOS.TXT)
                invoke    WinExec, batName, 0
                invoke    ExitProcess,0
    .end start

если компилить в лом, то для эксперимента можно оформить эту строку в батник, и посмотреть на результат:
wmic.exe /Output:smbios.raw /Namespace:\\root\WMI Path MSSmBios_RawSMBiosTables Get /Format:LIST

Добавлено
Цитата Jin X @
В общем, почему-то MapViewOfFile не даёт доступа к физ. адресам 0-0x100000, но даёт к 0xC0000-0x100000.

так в доках вроде сказано: -"Только первый мегабайт"

Автор: Jin X 26.09.18, 18:25
Тоже вариант :)
Интересно бы реализацию использования WMI на асме глянуть.
Я вот этим не занимался ни разу...

Автор: core-i7 26.09.18, 18:43
думаю API-шпион 'Kerberos' сможет тебе в этом помочь.. (хотя не проверял).

Добавлено
WMI чем удобный - он точно кроссплатформенный

Автор: Jin X 26.09.18, 18:57
Кстати...
Цитата Jin X @
Можете проверить диапазон первого МБ с интервалом 0x10000 ?
В проге mem_read.

Автор: core-i7 26.09.18, 19:07
Jin X, 0x10000 надо, или выше мега?
user posted image

Добавлено
так она и выше метра бурится без проблем!
кстати там оказывается начинается ещё одна-крутая таблица - ACPI

user posted image

Автор: Jin X 26.09.18, 19:15
Цитата core-i7 @
0x10000 надо, или выше мега?
До мега (0 - тоже, 0x10000, 0x20000...).
Мне интересно, почему мой предыдущий код, который берёт область от 0 до 0x100000 ошибку выдаёт? Что не может взять? Может, просто первые 64 Кб или ещё что-то...

Добавлено
Хотя вполне возможно, что граничные области нормально будут читаться, а где-то внутри - нет.

Добавлено
Со скринами можно не заморачиваться...

Автор: core-i7 26.09.18, 19:26
она читает от 0x9000 и по самые помидоры (в зависимости от установленной)

Добавлено
8FFF уже не читает

Автор: Jin X 27.09.18, 04:50
core-i7, понял, спасибо.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)