Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.119.131.178] |
|
Сообщ.
#1
,
|
|
|
Всем привет.
Необходимо из-под Windows (включая x64) проверить - поддерживает ли BIOS'овский int 13h расширенные функции работы с дисками (ah=4xh... 64-битную LBA-адресацию, по сути). Можно ли это сделать? И как? Т.е. пишется код для MBR, который будет использовать эти функции, но инсталлироваться он будет из-под Windows. Соответственно, если BIOS не поддерживает такие функции, загрузка будет невозможна. Поэтому нужна предварительная проверка. Я понимаю, что такая поддержка появилась уже давным-давно, но всё же для надёжности хочется сделать проверку. И я понимаю, что диск можно перенести на другой комп, где может быть по-другому, тем не менее. |
Сообщ.
#2
,
|
|
|
Цитата Jin X @ проверить - поддерживает ли BIOS'овский int 13h расширенные функции работы с дисками (ah=4xh... 64-битную LBA-адресацию, по сути). Можно ли это сделать? И как? можно попробовать считать SMBIOS/ACPI таблицы бит 19 в разделе BIOS хранит инфу о поддержке EDD - Enhanced-Disk-Drive: Скрытый текст [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 |
Сообщ.
#3
,
|
|
|
GetSystemFirmwareTable (вместе с EnumSystemFirmwareTables) у меня не пашет, возвращает нули, а GetLastError = 1 (ERROR_INVALID_FUNCTION)
Win10 x64 |
Сообщ.
#4
,
|
|
|
а kernel32.dll вообще экспортирует эту функцию, проверял?
можно прямо в тотале открыть по [Ctrl+Q] кернел32, и посмотреть экспорт. у меня ХР - FirmwareTable в списке нет, соответственно и проверить не могу |
Сообщ.
#5
,
|
|
|
core-i7, конечно экспортирует, иначе прога не запустилась бы (или GetProcAddress выдал бы 0, если через него делать).
|
Сообщ.
#6
,
|
|
|
Да, EnumSystemFirmwareTables и GetSystemFirmwareTable экспортируются в Win10 x64 из kernel32.dll.
|
Сообщ.
#7
,
|
|
|
в подвале этого линка есть пример (176 Kb), попробуй его запустить на своей десятке.
он открывает доступ к физ.памяти чз 'Device\PhysicalMemory'.. чем чёрт не шутит: http://www.delphiplus.org/articles/api/mem_read/index.html Добавлено Цитата Jin X @ конечно экспортирует тогда GetLastError не должен возвращать единицу INVALID_FUNCTION |
Сообщ.
#8
,
|
|
|
Цитата core-i7 @ Даже в описании функции GetSystemFirmwareTable написано:он открывает доступ к физ.памяти чз 'Device\PhysicalMemory'.. чем чёрт не шутит Цитата Но я попробовал, конечно (от админа). И ничего не вышло. Что неудивительно 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 @ Какая тут связь? Если функция не экспортируется, прога просто не запускается, а ошибка "invalid function" выдаётся во многих других случаях. тогда GetLastError не должен возвращать единицу INVALID_FUNCTION |
Сообщ.
#9
,
|
|
|
У меня GetSystemFirmwareTable успешно отрабатывает.
|
Сообщ.
#10
,
|
|
|
Цитата Jin X @ Какая тут связь? ..прямая! если функция в библиотеке есть, она должна отработать. в противном случае, вина лежит на программисте - возможно криво оформил или нет прав Добавлено Цитата Славян @ У меня GetSystemFirmwareTable успешно отрабатывает. а можно посмотреть, что она возвращает в буфер? |
Сообщ.
#11
,
|
|
|
Конечно можно. Только я 'от балды' запилил в аргументы значения из справки:
char pBufffer[512]; unsigned ret = GetSystemFirmwareTable( 'ACPI', 'PCAF', pBufffer, sizeof(pBufffer)); |
Сообщ.
#12
,
|
|
|
Славян буфер для данных smbios нужен как-мин 1000h, и дальше:
// Получить таблицу SMBIOS bytesWritten = GetSystemFirmwareTable ('RSMB', 0, smBiosData, smBiosDataSize); Добавлено размер буфера можно получить так: // Размер данных SMBIOS. smBiosDataSize = GetSystemFirmwareTable ('RSMB', 0, NULL, 0); |
Сообщ.
#13
,
|
|
|
Хор. Минутку.
Добавлено Ну получил. Вагон двоичных данных. Там есть и этот Megatrends, название мат.платы и всё такое. Что именно надо? |
Сообщ.
#14
,
|
|
|
в шапке там должно быть типа такого (по крайней мере у меня)..
[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 |
Сообщ.
#15
,
|
|
|
Всё, вкурил. Там почти как и в вашем примере. Только у вас хвост: 80 9A 8B 7F 01, а у меня 90 DA 8B 7F 01.
Т.е. у меня ISA Supported, и EDD тоже есть. |
Сообщ.
#16
,
|
|
|
Славян ну вот.. значит фишка работает.. спасибо!
|
Сообщ.
#17
,
|
|
|
А, ещё у меня (ибо DA, а не 9A):
Bit14 ESCD support is available - 1 (Yes) Добавлено Да, работает. Непонятно, всё же, почему у Jin X не пашет. |
Сообщ.
#18
,
|
|
|
а вообще, тут достаточно двух строк в консоли:
wmic partition get type |
Сообщ.
#19
,
|
|
|
Да, это я прогнал
Короче, писал на Delphi 7 и на fasm. В Delphi забыл поставить stdcall в определении функций. А в fasm указывал строкой, но она почему-то не заносилась в стек вообще (при подключении win32ax.inc, а вот с win32a.inc всё работает). Конкретно этот бит пока не проверял, но думаю, всё сработает, спасибо за инфу |
Сообщ.
#20
,
|
|
|
возвращает тип разделов, среди которых должен быть и 'Extended int-13'
Добавлено Цитата но думаю, всё сработает, спасибо за инфу я - так вообще не проверял.. (у меня XP 32-бит) чисто в теории должно было работать |
Сообщ.
#21
,
|
|
|
Какие-то странноватые данные выходят. Я же правильно понял, что "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)? Жесть какая-то... Добавлено Цитата core-i7 @ В какой шапке?в шапке там должно быть типа такого (по крайней мере у меня) А вообще, эта таблица (в таком виде) из какой программы сграблена? Добавлено На всякий случай инфа из RBIL: 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 блока инфы о биосе? |
Сообщ.
#22
,
|
|
|
Jin X, мои логи из программы rw: http://rweverything.com/download/
я не вижу, что возвращает эта функция, ..но вы можете сравнить выхлоп функции "GetSystemFirmwareTable" с данными этой проги. По сути, там сперва должен идти заголовок (см.мой лог), а потом - сами структуры. В заголовке указывается кол-во структур в таблице. RBIL (как я понял) это хелп Ральфа Брауна что-ли? Лучше покурить SMBIOS/DMI спецификацию: https://www.dmtf.org/sites/default/files/st...P0134_3.2.0.pdf |
Сообщ.
#23
,
|
|
|
на всякий.. приведу расклад DMI-таблицы
по моим расчётам, GetSystemFirmwareTable должна была сбросить в буфер всю таблицу, включая заголовок, иначе разобраться в куче данных будет проблематично (нет описания таблицы). То-есть данные в буфере должны начинаться с сигнатуры _SM_. Ну и где-то должна валяться база таблицы [SMBIOS-Entry], чтобы дальше плясать от неё. Например вот лог, где указана линейная база 0x000FAFF0 (FAFF:0000) - дзебуг подтверждает Entry-Point: [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-таблица находится в другом/свободном месте физ.памяти и не прижата к заголовку: [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) |
Сообщ.
#24
,
|
|
|
core-i7, да, это Ralf Brown, но в спецификации SMBIOS такая же фигня, ничего про эту канитель со странными первыми 8-ю байтами я не нашёл.
В общем, я накатал вот такую прогу для проверки поддержки EDD: ; 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: ; 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 возвращает структуру: struct RawSMBIOSData { BYTE Used20CallingMethod; BYTE SMBIOSMajorVersion; BYTE SMBIOSMinorVersion; BYTE DmiRevision; DWORD Length; BYTE SMBIOSTableData[]; }; |
Сообщ.
#25
,
|
|
|
Итого имеем...
EDDSupportCheck.fasm: ; 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: ; 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 (3,23 Кбайт, скачиваний: 152) Добавлено Можно, конечно, так не заморачиваться, а просто проверять первый байт (вернее, 9-й, т.е. со смещением 8, если брать Raw SMBIOS table) на значение 0, а второй - на значение 12h+ (чтоб был не меньше), а дальше уже по смещению 0Ah берём 19-й бит (а точнее test byte [Buffer+0Ch],8). Добавлено Хоть в спецификации и не сказано, что структура BIOS Information (тип 0) должна быть первой, наверняка всегда (или почти всегда) так и есть. Но я бы лучше подстраховался и сделал нормально (как в коде выше). |
Сообщ.
#26
,
|
|
|
Jin X, прикольно.. закинем в сундучок.
а для систем ХР можно реализовать так-же, и читать SMBIOS хоть ком-файлом чз NTVDM |
Сообщ.
#27
,
|
|
|
Так же, наверное, не выйдет, т.к. заветной функции нет в XP (32-битной, по крайней мере).
Можно попробовать через \\Device\PhysicalMemory. И там искать сигнатуру _SM_ или _SM3_ (я пока не понял, есть ли в SMBIOS 3.0 _SM_ тоже или только _SM3_) и дальше выходить на таблицу. Добавлено Ну или WMI как универсальный способ... |
Сообщ.
#28
,
|
|
|
Короче, сделал я так, что теперь всё работает и на Windows XP, и на более свежих.
Правда, я не проверял, можно ли заменить NtOpenSection на CreateFile + CreateFileMapping, но не думаю, что тут будет какой-то профит (по размеру файла). Ну и ещё, конечно, можно заменить MapViewOfFile на NtMapViewOfSection (чтобы раз начали с натива, то и дальше в том же духе), но пока заморачиваться не хочется, а хочется спать Исходники в аттаче (постить в лом). Прикреплённый файлEDDSupportCheck.zip (4,67 Кбайт, скачиваний: 140) |
Сообщ.
#29
,
|
|
|
Цитата Jin X @ теперь всё работает и на Windows XP, и на более свежих. ..у меня почему-то выдаёт эррор: Цитата SMBIOS table read error Press a key to exit... |
Сообщ.
#30
,
|
|
|
Хм, у меня на виртуалке работает.
Будем разбираться тогда. Запустите дебаг-версию, какие данные она выдаст? Прикреплённый файлEDDSupportCheckDEBUG.zip (4,45 Кбайт, скачиваний: 152) |
Сообщ.
#31
,
|
|
|
Меня ещё смущает текст в спецификации 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 ? Может, встречаются такие случаи? |
Сообщ.
#32
,
|
|
|
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М |
Сообщ.
#33
,
|
|
|
Цитата core-i7 @ MapViewOfFile выдаёт ошибку "Attempt to access invalid address."EBP=101, ..., GetLastError=487 (dec) Не понимаю, чего там инвалидного? Сейчас попробуем читать не весь мегабайт, а 0xC0000..0xFFFFF. Попробуйте ещё раз. Если будет опять ошибка, попробуйте запустить от админа (если там есть такая функция). Цитата core-i7 @ Про ниже 1 МБ логично (и я почти уверен, что так всегда).думаю, что только ниже первого мега. Я сейчас посмотрел что происходит в VMware, там адрес таблицы – 0xE0010, так что, видимо, с 0xC0000 нужно начинать... Прикреплённый файлEDDSupportCheckDEBUG2.zip (4,55 Кбайт, скачиваний: 164) Добавлено Кстати, а у вас вот эта прога нормально работает? http://www.delphiplus.org/articles/api/mem_read/index.html Попробуйте прочитать адреса 0, 0xC0000, 0xF0000, 0xFF000. |
Сообщ.
#34
,
|
|
|
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 @ Кстати, а у вас вот эта прога нормально работает? да.. нормально читает |
Сообщ.
#35
,
|
|
|
Цитата core-i7 @ В общем, почему-то MapViewOfFile не даёт доступа к физ. адресам 0-0x100000, но даёт к 0xC0000-0x100000. В общем-то, нам больше и не надо.да.. нормально читает Цитата core-i7 @ Работает на всём диапазоне?эта работает вроде.. Можете проверить диапазон первого МБ с интервалом 0x10000 ? Проверил ещё в 2000 – всё нормально, а NT выдаёт ошибку 0xC000000D (STATUS_INVALID_PARAMETER). Прога mem_read.exe там тоже не работает. В общем, сделал очередную версию с учётом исправлений. Прикреплённый файлEDDSupportCheck.zip (8,95 Кбайт, скачиваний: 158) |
Сообщ.
#36
,
|
|
|
дебуг версия из последнего архива:
Цитата >> $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. Останется распарсить текст в бинарник, и просканить биты. Вот пример.. 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. так в доках вроде сказано: -"Только первый мегабайт" |
Сообщ.
#37
,
|
|
|
Тоже вариант
Интересно бы реализацию использования WMI на асме глянуть. Я вот этим не занимался ни разу... |
Сообщ.
#38
,
|
|
|
думаю API-шпион 'Kerberos' сможет тебе в этом помочь.. (хотя не проверял).
Добавлено WMI чем удобный - он точно кроссплатформенный |
Сообщ.
#39
,
|
|
|
Кстати...
Цитата Jin X @ В проге mem_read. Можете проверить диапазон первого МБ с интервалом 0x10000 ? |
Сообщ.
#40
,
|
|
|
Сообщ.
#41
,
|
|
|
Цитата core-i7 @ До мега (0 - тоже, 0x10000, 0x20000...).0x10000 надо, или выше мега? Мне интересно, почему мой предыдущий код, который берёт область от 0 до 0x100000 ошибку выдаёт? Что не может взять? Может, просто первые 64 Кб или ещё что-то... Добавлено Хотя вполне возможно, что граничные области нормально будут читаться, а где-то внутри - нет. Добавлено Со скринами можно не заморачиваться... |
Сообщ.
#42
,
|
|
|
она читает от 0x9000 и по самые помидоры (в зависимости от установленной)
Добавлено 8FFF уже не читает |
Сообщ.
#43
,
|
|
|
core-i7, понял, спасибо.
|