Skip to content
FreeDOSDeep Dive Published Updated 7 min readViews unavailable

Reading SMBIOS Tables from a DOS Hardware Inventory Utility

Find and validate SMBIOS entry points, parse length-delimited records safely, and report firmware strings as claims rather than physical proof.

System Management BIOS (SMBIOS) gives firmware a standardized table of system-management records such as BIOS version, system manufacturer, baseboard identity, processor descriptions, and memory-device inventory. A DOS utility can use that table for diagnostics without probing every controller directly. The table is still firmware-reported metadata: it can be blank, stale, virtualized, or inconsistent with replaceable hardware. Treat it as an inventory source with explicit validity checks, not as a hardware attestation mechanism.

The parser has two jobs. It must find a valid entry point using the access method available to the current environment, then walk a packed stream of structures whose formatted sections and string areas have different boundaries. Trusting an anchor string alone is not enough. Check length, checksum, table address, maximum table size, structure count or end marker, and every record boundary before reading fields.

Prefer a platform-provided entry point when available

On EFI systems, the firmware configuration table can contain an SMBIOS entry-point GUID and pointer. A plain real-mode DOS program generally does not have that EFI interface after boot, so legacy code searches the documented legacy address range on 16-byte boundaries for the 32-bit SMBIOS entry-point anchor. A protected-mode or UEFI-aware loader may instead provide a pointer through its own contract. Do not assume that a 64-bit physical pointer can be read through an ordinary 16-bit segment:offset.

SMBIOS defines both the 32-bit entry-point structure and a 64-bit entry point for the table. The 32-bit form uses _SM_ and an intermediate _DMI_ anchor; the 64-bit form uses _SM3_. These are different layouts and have different address widths. Validate the version and length before interpreting fields, and do not parse a 64-bit table address by truncating it into a 32-bit variable.

for each 16-byte-aligned candidate in the documented legacy search window:
    if candidate begins with the expected anchor:
        read only the fixed prefix needed to learn the entry-point length
        reject if length is outside the supported structure size
        checksum exactly that many bytes; require the specified zero sum
        validate the secondary anchor and its checksum for the 2.x form
        validate table address, table length, and version bounds

This is pseudocode, not a universal discovery method for every UEFI boot path. Use a loader-provided SMBIOS pointer when one exists, and constrain legacy scans to the specification’s documented area. Do not scan arbitrary RAM: it can be expensive, can fault under protected-mode memory limits, and may find random bytes that happen to resemble an anchor.

Parse each record using its own length

The SMBIOS table is a packed sequence of structures. Each begins with a four-byte header: type, formatted length, and handle. The formatted area contains fixed-offset fields whose presence depends on the structure type and reported length. It is followed by zero or more NUL-terminated strings and then a second NUL that ends the structure. A type 127 end-of-table record is commonly used as the terminator, but the parser should also honor the table length and any structure-count constraints from the entry point.

Never assume a current structure has the full length from the newest version of the specification. Check formatted_length >= minimum_length_for_field before reading a field, and validate that the full formatted area lies within the remaining table bytes. String indices are one-based; zero means no string. To resolve a string index, walk only within the current structure’s string area, count NUL-terminated entries, and reject an unterminated string or index that runs past the double-NUL boundary.

The type-specific schema evolves over time. A type may gain new fields, but old firmware can omit them. Parse known fields conditionally and preserve unknown trailing formatted bytes without assigning a meaning. Avoid fixed-size C structs that assume a single SMBIOS revision: compiler packing, pointer width, and structure evolution can make such casts unsafe.

The entry-point checksum and structure-table checksum are separate checks in the legacy SMBIOS 2.x entry point. Validate each over the length specified by its own field; do not checksum a hard-coded structure size or include unrelated padding. SMBIOS 3.x has its own entry-point format and maximum-table-size field. A table that ends before its claimed length, an entry point whose declared length exceeds the bytes safely readable, or a checksum mismatch must be rejected or clearly marked invalid.

The structure handle is an identifier within the table, not a physical address or a promise that every handle is unique across separate boots. Relationships between records can use handles, so store them as values and resolve them only against the same validated table snapshot. Avoid assuming that related records always appear in a particular order; parse first, then resolve references after validating the complete table.

Firmware facts are not ground truth

System, baseboard, and chassis strings are vendor-supplied strings, not validated product identifiers. Memory-device structures can report sockets that are empty, devices that were removed, or values the firmware cannot measure. A table can be synthetic inside a virtual machine. The utility should label data as “reported by SMBIOS” and include the SMBIOS version and structure type so downstream readers can distinguish it from direct device identification.

Do not use SMBIOS serial numbers or UUIDs as authentication credentials. Firmware may duplicate, zero, expose defaults, or permit the values to be changed. A DMI record saying a machine has a particular processor does not prove that processor is executing. For performance or security decisions, use the relevant OS or device interface and a threat model designed for that purpose.

SMBIOS also is not a memory map. It may describe installed memory devices, but usable physical ranges, firmware-reserved ranges, MMIO holes, and remapped memory belong to interfaces such as the BIOS E820 map or the EFI memory map. The two datasets may legitimately disagree because they answer different questions.

Build a bounded parser

Keep the table base, table length, current offset, structure count, and maximum string scan length in types wide enough for the entry-point version. Before each addition, check for integer overflow and ensure offset + length <= table_length. Stop on the end marker or at the validated table boundary. Cap the number of records to the maximum possible implied by the table length so malformed data cannot loop indefinitely.

For each parsed record, retain raw type, handle, formatted length, and source address in diagnostics. Decode only fields your report needs. Display untrusted firmware strings with escaping for terminal control characters, NULs, and non-printable bytes so a crafted table cannot change the display or corrupt a CSV export. Keep binary values alongside rendered text if the tool is used for forensic comparison.

When a checksum fails, do not “repair” the entry point and continue as though the table were authoritative. Report the invalid checksum, candidate address, signature, and version bytes, then either fail closed for that data source or offer an explicitly labeled best-effort mode. A corrupt table can be evidence of a firmware bug, a memory corruption incident, or a bad virtual-machine configuration.

Verification plan

Test a valid 2.x entry point, a valid 3.x entry point when the program’s environment can represent it, a missing table, a bad checksum, a zero or undersized table length, an invalid string index, an unterminated string, an unknown type, and a truncated final structure. Fuzz the parser with a copied table image in an ordinary host-side test harness before running it on hardware. Confirm that malformed input cannot read outside the supplied table buffer or write outside the output buffer.

Cross-check selected fields against firmware setup or a trusted OS inventory tool, but treat disagreement as an investigation cue rather than proof that one tool is wrong. Record source and parser version in exported reports. On DOS, state whether the utility used a real-mode legacy scan, a protected-mode mapping service, or an explicit loader handoff.

Keep a small corpus of real table dumps from different firmware families and virtual machines, with identifying serial numbers removed where appropriate. Use it to test parser compatibility as structure versions evolve. Compare raw record lengths and string indices against a trusted decoder, but do not make the decoder’s rendered product claims the expected truth; the parser test should verify bounds, fields, and checksums. A forensic export can retain original bytes and their source address beside normalized fields so later reviewers can reproduce a disagreement.

SMBIOS is valuable because it replaces risky guesses with a documented table format. Its safe use depends on respecting the entry-point version, checksums, variable record lengths, address width, and firmware’s limited authority over reality. Parse defensively and report precisely what the firmware claimed.

Related:

Sources:

Comments