119 lines
3.9 KiB
Plaintext
119 lines
3.9 KiB
Plaintext
biossums
|
|
|
|
|
|
Intention
|
|
|
|
Writing a bios for a pc-compatible includes the task of embedding various
|
|
checksums. At least there is the overall bios checksum stored in the very
|
|
last byte of the program. Depending on the number and types of services the
|
|
bios provides there are others, e.g.
|
|
|
|
-- a checksum for the pci bios extensions,
|
|
-- a checksum for the plug and play bios extensions,
|
|
-- checksums for multiprocessor bios extensions.
|
|
|
|
All these checksums have one common point: using the usual assembler directives
|
|
they are hard (if not impossible) to compute at compile time. You can either
|
|
compute them by hand --- a tedious, error-prone, task, where in addition you
|
|
often have to make unreliable assumptions about the memory layout of the
|
|
entire bios. Or you patch them directly into your compiled bios-image. Apart
|
|
from computing the checksums this is what biossums does for you.
|
|
|
|
|
|
|
|
Checksums
|
|
|
|
With the exception of the overall bios checksum, in a modern pc-bios checksums
|
|
are not used to ensure data integrity. Instead they are used in conjunction
|
|
with certain signatures to securely identify the entry points or the addresses
|
|
of important data of some bios-extensions. Because these services are often
|
|
invoked from x86 protected mode the original method via interrupts is not
|
|
applicable. Scanning (even only parts) of the bios for (short) signatures and
|
|
solely relying on this is insecure though, cause the found signature might not
|
|
refer to the sought service but rather be some obscure machine code resembling
|
|
the signature by accident.
|
|
|
|
Since signatures are usually part of a larger header or table the above
|
|
mentioned problem is being circumvented by checksumming over this header and
|
|
comparing the result to a checksum stored next to the signature. In practice the
|
|
checksum is often part of the header, chosen in a way that the contents of the
|
|
header add up to zero.
|
|
|
|
|
|
|
|
Usage
|
|
|
|
biossums is very simple and straightforward. The only (and mandatory) argument
|
|
is the file-name of the bios-image. The file is being read, patched and written.
|
|
So if you want to keep your original file for reference, use biossums on a copy
|
|
of your bios-image.
|
|
|
|
For now, biossums can only rely on signatures to find the locations of the
|
|
accompanying checksums. Therefore biossums refuses to set any checksums if it
|
|
finds more than one signature of the same type.
|
|
|
|
|
|
|
|
Example output
|
|
|
|
Run upon a Bochs bios configured for 2 CPUs (ver. 1.29) biossums displays:
|
|
|
|
PCI-Bios header at: 0x9480
|
|
Current checksum: 0xA9
|
|
Calculated checksum: 0xA9
|
|
|
|
|
|
MP header at: 0xD0F0
|
|
Current checksum: 0xC1
|
|
Calculated checksum: 0xC1
|
|
|
|
|
|
PCMP header at: 0xD000
|
|
Current checksum: 0x65
|
|
Calculated checksum: 0x65
|
|
|
|
|
|
Bios checksum at: 0xFFFF
|
|
Current checksum: 0x00
|
|
Calculated checksum: 0x24 Setting checksum.
|
|
|
|
|
|
If we patch in a second "_32_" signature at offset 0x9760 and reset the PCMP
|
|
checksum to 0x00 we get:
|
|
|
|
PCI-Bios header at: 0x9480
|
|
Current checksum: 0xA9
|
|
Calculated checksum: 0xA9
|
|
|
|
PCI-Bios header at: 0x9760
|
|
Current checksum: 0x00
|
|
Calculated checksum: 0x00 Multiple PCI headers! No checksum set.
|
|
|
|
|
|
MP header at: 0xD0F0
|
|
Current checksum: 0xC1
|
|
Calculated checksum: 0xC1
|
|
|
|
|
|
PCMP header at: 0xD000
|
|
Current checksum: 0x00
|
|
Calculated checksum: 0x65 Setting checksum.
|
|
|
|
|
|
Bios checksum at: 0xFFFF
|
|
Current checksum: 0x00
|
|
Calculated checksum: 0x01 Setting checksum.
|
|
|
|
|
|
|
|
Possible enhancements
|
|
|
|
Although biossums takes care of all checksums being used by the bios of the
|
|
Bochs project (as of version 2.02) there are more to cover, e.g. the checksums
|
|
for "Plug and Play" bios extension.
|
|
|
|
In addition it was planned to provide further information to biossums via map-/
|
|
symbol-files to verify the locations of checksums apart from scanning for
|
|
signatures. For now this seems not to be necessary; in practice no double
|
|
signatures have been observed yet.
|