Как проверить поддержку расширенного режима работы с int 13h из-под Windows?

Тема в разделе "WASM.WIN32", создана пользователем Jin X, 28 июн 2018.

  1. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Так, она же на UEFI API написана, а не WinAPI.

    Не от корки не корки. Этого не видел.

    VMware выдаёт адрес таблицы 0xE0010.
    Как выяснилось, на некоторых системах (Windows XP в частности) MapViewOfFile не даёт доступа к диапазону 0-0x100000, но к 0xC0000-0x100000 даёт, так что я тут переделал малясь прогу (и сделал в одном файле).
    Проверил ещё в 2000 – всё нормально, а NT выдаёт ошибку 0xC000000D (STATUS_INVALID_PARAMETER на NtOpenSection).

    Кстати, есть ли ещё способ прочитать первый мегабайт (в системах XP, в более новых)?
    По идее, можно же прочитать память из COM-программы при запуске через NTVDM... а из Win-проги?

    Код (ASM):
    1. ; fasm 1 (Windows 2000+)
    2.  
    3. format  PE Console 5.0
    4. include 'win32axp.inc'
    5.  
    6. ;-- CODE SECTION -------------------------------------------------------------------------------------------------------
    7.  
    8. FirmText        equ     'RSMB'
    9. FirmSign        =       FirmText shr 24 + (FirmText shr 8) and 0xFF00 + (FirmText shl 8) and 0xFF0000 + (FirmText shl 24) and 0xFF000000
    10. FirmTable       =       0
    11.  
    12. MAX_TABLE_SIZE  =       65536
    13. BUFFER_SIZE     =       MAX_TABLE_SIZE+8        ; 8 bytes of header
    14. SHOW_READ_OK    =       1
    15. SAVE_TO_FILE    =       1
    16. SHOW_BIOS_INFO  =       1
    17.  
    18. .code
    19. start:
    20.  
    21.                 ; Read SMBIOS table
    22.                 cld
    23.                 stdcall GetSMBIOSTable
    24.                 jc      .readerror
    25.  
    26. if defined SHOW_READ_OK & SHOW_READ_OK
    27.   if defined SHOW_BIOS_INFO & SHOW_BIOS_INFO
    28.                 movzx   ecx,[SMBIOSMajorVersion]
    29.                 movzx   edx,[SMBIOSMinorVersion]
    30.                 cinvoke printf, <'SMBIOS table is read (size = %d bytes)!',10,\
    31.                                  'SMBIOS version %d.%d',10>, eax, ecx, edx
    32.   else
    33.                 cinvoke printf, <'SMBIOS table is read (size = %d bytes)!',10>, eax
    34.   end if
    35. end if
    36.  
    37. if defined SAVE_TO_FILE & SAVE_TO_FILE
    38.                 ; Save table to file
    39.                 stdcall SaveToFile
    40. end if
    41.                 ; Check of EDD support and show results
    42.                 stdcall GetBIOSChars
    43.                 jc      .notfound
    44.  
    45. if defined SHOW_BIOS_INFO & SHOW_BIOS_INFO
    46.                 push    eax
    47.                 cinvoke printf, <'BIOS Characteristics = %08X%08X (hex)',10>, edx, eax
    48.                 pop     eax
    49. end if
    50.                 btc     eax,19
    51.                 jnc     @F
    52.                 cinvoke printf, <'EDD is supported!',10>
    53.                 jmp     .finish
    54.         @@:     cinvoke printf, <'EDD is NOT supported :(',10>
    55.  
    56.                 ; Finalization
    57.         .finish:
    58.                 cinvoke printf, <'Press a key to exit...',10>
    59.                 cinvoke getch
    60.                 invoke  ExitProcess, 0
    61.  
    62.                 ; Errors
    63.         .readerror:
    64.                 test    eax,eax
    65.                 jnz     .toolarge
    66.                 cinvoke printf, <'SMBIOS table read error :(',10>
    67.                 jmp     .finish
    68.         .toolarge:
    69.                 cinvoke printf, <'SMBIOS table is too large (%d bytes)',10>, eax
    70.                 jmp     .finish
    71.         .notfound:
    72.                 cinvoke printf, <'BIOS Information structure is not found :(',10>
    73.                 jmp     .finish
    74.  
    75. ; Read raw SMBIOS firmware table to Buffer via WinAPI
    76. ; Returns EAX = table size (CF=0) if ok; EAX = 0 (CF=1) on error
    77. proc            GetSMBIOSTable
    78.                 call    GetSMBIOSTableWinAPI
    79.                 jnc     .exit
    80.                 cmp     eax,-1
    81.                 jne     .exit                   ; jump if WinAPI function is supported (CF=1 because EAX < unsigned -1)
    82.                 call    GetSMBIOSTablePhysMem
    83.         .exit:
    84.                 ret
    85. endp
    86.  
    87. ; Read raw SMBIOS firmware table to Buffer via WinAPI function GetSystemFirmwareTable [Windows Vista/XP Pro x64 and above]
    88. ; Returns EAX = table size (CF=0) if ok; EAX = 0 if function returned error, -1 if function is not supported, other value if buffer is too small (CF=1)
    89. proc            GetSMBIOSTableWinAPI
    90.                 invoke  GetModuleHandle, 'kernel32.dll'
    91.                 invoke  GetProcAddress, eax, 'GetSystemFirmwareTable'
    92.                 test    eax,eax
    93.                 jz      .noproc                 ; CF=0 (not 1)
    94.                 stdcall eax, FirmSign, FirmTable, Buffer, BUFFER_SIZE
    95.                 test    eax,eax
    96.                 jz      .error                  ; CF=0 (not 1)
    97.                 sub     eax,8                   ; subtract size of raw data header
    98.                 cmp     eax,MAX_TABLE_SIZE
    99.                 ja      .error                  ; CF=0 (not 1)
    100.                 stc                             ; CF=1 (not 0)
    101.         .error:
    102.                 cmc                             ; CF = not CF
    103.                 ret
    104.         .noproc:
    105.                 dec     eax                     ; EAX = -1 (WinAPI function is not supported)
    106.                 jmp     .error
    107. endp
    108.  
    109. ; Read raw SMBIOS firmware table to Buffer via NtOpenSection (\Device\PhysicalMemory) [Windows XP and below]
    110. ; Returns EAX = table size (CF=0) if ok; EAX = 0 on read error or if table is not found (CF=1)
    111. proc            GetSMBIOSTablePhysMem   uses ebx esi edi
    112. @SMBIOSSign     =       '_SM_'
    113. @SMBIOSMapStartAddr =   0xC0000                 ; value 0 doesn't work on some systems
    114. @SMBIOSMapEndAddr =     0x100000
    115. @SMBIOSSignStartAddr =  0xF0000                 ; must be >= @SMBIOSMapStartAddr
    116. @SMBIOSSignEndAddr =    0x100000                ; mast be <= @SMBIOSSignEndAddr
    117.                 ; Map view of physical memory
    118.                 xor     ebx,ebx
    119.                 invoke  NtOpenSection, hPhysMem, SECTION_MAP_READ, ObjectAttributes
    120.         if defined DEBUG & DEBUG
    121.                 mov     ecx,eax
    122.         end if
    123.                 test    eax,eax
    124.                 jnz     .finish
    125.                 invoke  MapViewOfFile, [hPhysMem], FILE_MAP_READ, 0, @SMBIOSMapStartAddr, @SMBIOSMapEndAddr-@SMBIOSMapStartAddr
    126.                 test    eax,eax
    127.                 jz      .close
    128.  
    129.                 ; Search for SMBIOS entry point structure
    130.                 lea     edx,[eax+@SMBIOSSignStartAddr-@SMBIOSMapStartAddr]
    131.                 mov     ecx,(@SMBIOSSignEndAddr-@SMBIOSSignStartAddr)/16
    132.         @@:     cmp     dword [edx],@SMBIOSSign
    133.                 je      .ok
    134.                 add     edx,0x10
    135.                 loop    @B
    136.                 jmp     .notfound
    137.         .ok:
    138.                 ; Find, check and copy table into buffer
    139.                 movzx   ecx,word [edx+0x16]     ; table size
    140. if      @SMBIOSMapEndAddr-@SMBIOSMapStartAddr > MAX_TABLE_SIZE
    141.                 cmp     ecx,MAX_TABLE_SIZE
    142.                 ja      .setcf                  ; jump if table is too large
    143. end if
    144.         @@:     mov     esi,[edx+0x18]          ; table address
    145.                 cmp     esi,@SMBIOSMapStartAddr
    146.                 jb      .notfound               ; table starts below @SMBIOSMapStartAddr (very strange)
    147.                 lea     edi,[esi+ecx]           ; table end
    148.                 cmp     edi,@SMBIOSMapEndAddr
    149.                 ja      .notfound               ; table ends above @SMBIOSMapEndAddr (very strange)
    150.                 mov     ebx,ecx
    151.                 mov     [SMBIOSTableSize],ecx
    152.                 lea     esi,[esi+eax-@SMBIOSMapStartAddr] ; table start virtual address
    153.                 mov     edi,SMBIOSTable
    154.                 mov     ax,[edx+6]
    155.                 mov     word [SMBIOSMajorVersion],ax
    156.                 mov     al,[edx+0x1E]
    157.                 mov     [DmiRevision],al
    158.                 rep movsb                       ; copy table to buffer
    159.         .notfound:
    160.                 invoke  UnmapViewOfFile, eax    ; EAX was not changed
    161.         .close:
    162.                 invoke  NtClose, [hPhysMem]
    163.         .finish:
    164.                 mov     eax,ebx
    165.         .setcf: sub     ebx,1                   ; CF=1 if EBX = 0
    166.                 ret
    167. endp
    168.  
    169. ; Get BIOS Characteristic QWORD in EDX:EAX and address of structure start in ECX if CF=0 or CF=1 on error
    170. proc            GetBIOSChars    uses esi
    171.                 ; Search for BIOS Information structure
    172.                 mov     esi,SMBIOSTable
    173.                 mov     edx,[SMBIOSTableSize]
    174.                 add     edx,esi                 ; table end
    175.         .next:
    176.                 mov     ecx,esi                 ; structure start
    177.                 xor     eax,eax
    178.                 lodsb                           ; structure type
    179.                 cmp     al,127
    180.                 stc                             ; CF=1 if next just will occur
    181.                 je      .finish                 ; jump if end-of-table type
    182.                 test    al,al
    183.                 lodsb                           ; structure size
    184.                 lea     esi,[eax+ecx]           ; structure end, start of strings
    185.                 jz      .oktype                 ; jump if type = 0 (BIOS Information)
    186.                 ; Skip strings
    187.         @@:     mov     ah,al                   ; AL <> 0 for the first pass
    188.                 lodsb
    189.                 test    eax,eax
    190.                 jnz     @B                      ; searching for strings end (double 0)
    191.                 cmp     esi,edx
    192.                 jb      .next                   ; check next structure (of continue with AL = 0)
    193.         .oktype:
    194.                 cmp     al,0x12
    195.                 jb      .finish                 ; jump if bad structure (structure must be at least 0x12 bytes in size) [CF=1]
    196.                 ; Structure is found [CF=0]
    197.                 mov     eax,[ecx+0Ah]           ; BIOS Characteristics low dword
    198.                 mov     edx,[ecx+0Eh]           ; BIOS Characteristics high dword
    199.         .finish:
    200.                 ret                             ; CF=0 if ok, CF=1 on error
    201. endp
    202.  
    203. ; Save table to file
    204. proc            SaveToFile      uses ebx
    205.                 invoke  CreateFile, <'SMBIOSTable.bin'>, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
    206.                 cmp     eax,INVALID_HANDLE_VALUE
    207.                 je      .createerror
    208.                 mov     ebx,eax
    209.                 invoke  WriteFile, ebx, SMBIOSTable, [SMBIOSTableSize], Written, 0
    210.                 test    eax,eax
    211.                 jz      .writeerror
    212.                 mov     eax,[SMBIOSTableSize]
    213.                 cmp     [Written],eax
    214.                 jb      .writeerror
    215.                 cinvoke printf, <'Table is saved to file!',10>
    216.         .continue:
    217.                 invoke  CloseHandle, ebx
    218.                 ret
    219.         .createerror:
    220.                 cinvoke printf, <'File create error :(',10>
    221.                 ret
    222.         .writeerror:
    223.                 cinvoke printf, <'File write error :(',10>
    224.                 jmp     .continue
    225. endp
    226.  
    227. ;-- DATA SECTION -------------------------------------------------------------------------------------------------------
    228.  
    229. .data
    230.  
    231. align   4
    232. UnicodePhysicalMemory:
    233. UnicodePhysicalMemory.Length            dw      PhysMemDevNameSize-2
    234. UnicodePhysicalMemory.MaximumLength     dw      PhysMemDevNameSize
    235. UnicodePhysicalMemory.Buffer            dd      PhysMemDevName  ; dq on x64
    236.  
    237. ObjectAttributes:
    238. ObjectAttributes.Length                 dd      ObjectAttributesSize
    239. ObjectAttributes.RootDirectory          dd      0       ; dq on x64
    240. ObjectAttributes.ObjectName             dd      UnicodePhysicalMemory   ; dq on x64
    241. OBJ_KERNEL_HANDLE                       =       0x0000200
    242. ObjectAttributes.Attributes             dd      OBJ_KERNEL_HANDLE
    243. ObjectAttributes.SecurityDescriptor     dd      0       ; dq on x64
    244. ObjectAttributes.SecurityQualityOfService dd    0       ; dq on x64
    245. ObjectAttributesSize    =       $-ObjectAttributes
    246.  
    247. PhysMemDevName  du      '\Device\PhysicalMemory',0
    248. PhysMemDevNameSize =    $-PhysMemDevName
    249.  
    250. align   4
    251. hPhysMem        rd      1                       ; handle of physical memory section
    252.  
    253. Written         rd      1
    254.  
    255. Buffer          rb      1
    256. SMBIOSMajorVersion rb   1
    257. SMBIOSMinorVersion rb   1
    258. DmiRevision     rb      1
    259. SMBIOSTableSize rd      1
    260. SMBIOSTable     rb      MAX_TABLE_SIZE
    261. ZeroWord        rw      1                       ; just in case
    262.  
    263. section '.idata' import data readable
    264. library         kernel32, 'kernel32.dll',\
    265.                 msvcrt, 'msvcrt.dll',\
    266.                 ntdll, 'ntdll.dll'
    267.  
    268.                 import_kernel32
    269.                 all_api
    270.  
    271. import          msvcrt,\
    272.                 printf, 'printf',\
    273.                 getch, '_getch'
    274.  
    275. import          ntdll,\
    276.                 NtOpenSection,'NtOpenSection',\
    277.                 NtClose,'NtClose'
    Если у кого-то не будет работать (особенно в XP, 2000), запустите DEBUG-версию и скиньте сюда вывод, плиз.
     

    Вложения:

  2. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Решил из любопытства заменить MapViewOfFile на NtMapViewOfSection.
    Делаю так:
    Код (ASM):
    1. invoke NtMapViewOfSection, [hPhysMem], 0, BaseAddr, 0, 0, BaseOffset, 0x40000, ViewUnmap, 0, PAGE_READWRITE
    2. . . .
    3. BaseOffset dq 0xC0000 ; start address
    4. BaseAddr dd 0
    5. hPhysMem rd 1 ; handle of physical memory section
    Выдаёт ошибку 0xC0000005 (STATUS_ACCESS_VIOLATION)
    Что я делаю не так?
     
  3. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Поменял на:
    Код (ASM):
    1. invoke NtMapViewOfSection, [hPhysMem], -1, BaseAddr, 0, 0, SectionOffset, ViewSize, ViewUnmap, 0, PAGE_READWRITE
    2. . . .
    3. align 4
    4. SectionOffset dq 0xC0000
    5. BaseAddr dd 0
    6. ViewSize dd 0x40000
    7. hPhysMem rd 1 ; handle of physical memory section
    Теперь вылетает 0xC0000022 (STATUS_ACCESS_DENIED).
     
    Последнее редактирование: 27 сен 2018
  4. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Нашёл ошибку!
    Надо просто заменить PAGE_READWRITE на PAGE_READONLY (хотя я вроде так пробовал, но видимо, не допробовал).