mirror of
https://github.com/chipsec/chipsec
synced 2026-06-08 13:31:00 +00:00
Add usage documentation to pcie_fuzz.py
Signed-off-by: Frinzell, Aaron <aaron.frinzell@intel.com>
This commit is contained in:
committed by
Nathaniel Mitchell
parent
38d8884707
commit
bbaea2bc11
@@ -25,8 +25,8 @@ Simple PCIe device Memory-Mapped I/O (MMIO) and I/O ranges VMM emulation fuzzer
|
||||
Usage:
|
||||
``chipsec_main -m tools.vmm.pcie_fuzz [-a <bus> <dev> <fun>]``
|
||||
|
||||
- ``<bus>`` : Bus # to fuzz (in hex)
|
||||
- ``<dev>`` : Device # to fuzz (in hex)
|
||||
- ``<bus>`` : Bus # to fuzz (in hex)
|
||||
- ``<dev>`` : Device # to fuzz (in hex)
|
||||
- ``<fun>`` : Function # to fuzz (in hex)
|
||||
|
||||
Where:
|
||||
@@ -37,12 +37,21 @@ Examples:
|
||||
>>> chipsec_main.py -i -m tools.vmm.pcie_fuzz -l log.txt
|
||||
>>> chipsec_main.py -i -m tools.vmm.pcie_fuzz -a 0 1f 0
|
||||
|
||||
Additional options set within the module:
|
||||
- ``IO_FUZZ`` : Set to fuzz IO BARs
|
||||
- ``CALC_BAR_SIZE`` : Set to calculate BAR sizes
|
||||
- ``TIMEOUT`` : Timeout between memory writes (seconds)
|
||||
- ``ACTIVE_RANGE`` : Set to fuzz MMIO BAR in Active range
|
||||
- ``BIT_FLIP`` : Set to fuzz using bit flips
|
||||
- ``_EXCLUDE_BAR`` : BARs to exclude (list)
|
||||
|
||||
.. note::
|
||||
- Returns a Warning by default.
|
||||
- System may be in an unknown state, further evaluation may be needed.
|
||||
- Returns a Warning by default
|
||||
- System may be in an unknown state, further evaluation may be needed
|
||||
|
||||
.. important::
|
||||
- This module is designed to run in a VM environment
|
||||
- Behavior on physical HW is undefined
|
||||
|
||||
"""
|
||||
|
||||
@@ -73,12 +82,12 @@ class pcie_fuzz(BaseModule):
|
||||
# Issue 8/16/32-bit I/O requests with various values to all I/O ports (aligned and unaligned)
|
||||
for port_off in range(size):
|
||||
port_value = self.cs.io.read_port_byte(bar + port_off)
|
||||
self.cs.io.write_port_byte (bar + port_off, port_value)
|
||||
self.cs.io.write_port_byte (bar + port_off, ((~port_value) & 0xFF))
|
||||
self.cs.io.write_port_byte (bar + port_off, 0xFF)
|
||||
self.cs.io.write_port_byte (bar + port_off, 0x00)
|
||||
self.cs.io.write_port_word (bar + port_off, 0xFFFF)
|
||||
self.cs.io.write_port_word (bar + port_off, 0x0000)
|
||||
self.cs.io.write_port_byte(bar + port_off, port_value)
|
||||
self.cs.io.write_port_byte(bar + port_off, ~port_value & 0xFF)
|
||||
self.cs.io.write_port_byte(bar + port_off, 0xFF)
|
||||
self.cs.io.write_port_byte(bar + port_off, 0x00)
|
||||
self.cs.io.write_port_word(bar + port_off, 0xFFFF)
|
||||
self.cs.io.write_port_word(bar + port_off, 0x0000)
|
||||
self.cs.io.write_port_dword(bar + port_off, 0xFFFFFFFF)
|
||||
self.cs.io.write_port_dword(bar + port_off, 0x00000000)
|
||||
|
||||
@@ -97,7 +106,7 @@ class pcie_fuzz(BaseModule):
|
||||
self.cs.mem.write_physical_mem_byte(bar + reg_off + 1, 0xFF)
|
||||
|
||||
def fuzz_mmio_bar(self, bar, is64bit, size=0x1000):
|
||||
self.logger.log( "[*] Fuzzing MMIO BAR 0x{:016X}, size = 0x{:X}..".format(bar, size) )
|
||||
self.logger.log("[*] Fuzzing MMIO BAR 0x{:016X}, size = 0x{:X}..".format(bar, size))
|
||||
reg_off = 0
|
||||
# Issue aligned 32-bit MMIO requests with various values to all MMIO registers
|
||||
for reg_off in range(0, size, 4):
|
||||
@@ -108,34 +117,34 @@ class pcie_fuzz(BaseModule):
|
||||
self.cs.mmio.write_MMIO_reg(bar, reg_off, reg_value)
|
||||
|
||||
def fuzz_mmio_bar_random(self, bar, is64bit, size=0x1000):
|
||||
self.logger.log( "[*] Fuzzing MMIO BAR in random mode 0x{:016X}, size = 0x{:X}..".format(bar, size) )
|
||||
self.logger.log("[*] Fuzzing MMIO BAR in random mode 0x{:016X}, size = 0x{:X}..".format(bar, size))
|
||||
reg_off = 0
|
||||
while 1:
|
||||
rand = random.randint(0, size /4 -1)
|
||||
self.fuzz_offset(bar, reg_off, rand *4, is64bit)
|
||||
self.fuzz_offset(bar, reg_off, rand *4 +1, is64bit)
|
||||
self.fuzz_unaligned(bar, rand *4, is64bit)
|
||||
rand = random.randint(0, size / 4 - 1)
|
||||
self.fuzz_offset(bar, reg_off, rand * 4, is64bit)
|
||||
self.fuzz_offset(bar, reg_off, rand * 4 + 1, is64bit)
|
||||
self.fuzz_unaligned(bar, rand * 4, is64bit)
|
||||
|
||||
def fuzz_mmio_bar_in_active_range(self, bar, is64bit, list):
|
||||
self.logger.log( "[*] Fuzzing MMIO BAR in Active range 0x{:016X}, size of range = 0x{:X}..".format(bar, len(list)) )
|
||||
self.logger.log("[*] Fuzzing MMIO BAR in Active range 0x{:016X}, size of range = 0x{:X}..".format(bar, len(list)))
|
||||
for reg_off in list:
|
||||
rand = random.randint(0, 255)
|
||||
self.fuzz_offset(bar, reg_off, rand, is64bit)
|
||||
self.fuzz_unaligned(bar, reg_off, is64bit)
|
||||
|
||||
def fuzz_mmio_bar_in_active_range_random(self, bar, is64bit, list):
|
||||
self.logger.log( "[*] Fuzzing MMIO BAR in Active range 0x{:016X} in random mode, size of range = 0x{:X}..".format(bar, len(list)) )
|
||||
self.logger.log("[*] Fuzzing MMIO BAR in Active range 0x{:016X} in random mode, size of range = 0x{:X}..".format(bar, len(list)))
|
||||
reg_off = 0
|
||||
self.fuzz_unaligned(bar, reg_off, is64bit)
|
||||
while 1:
|
||||
rand = random.randint(0, len(list) -1)
|
||||
rand = random.randint(0, len(list) - 1)
|
||||
self.fuzz_offset(bar, reg_off, list[rand], is64bit)
|
||||
|
||||
def fuzz_mmio_bar_in_active_range_bit_flip(self, bar, is64bit, list):
|
||||
self.logger.log( "[*] Fuzzing (bit flipping) MMIO BAR in Active range 0x{:016X}, size of range = 0x{:X}..".format(bar, len(list)) )
|
||||
self.logger.log("[*] Fuzzing (bit flipping) MMIO BAR in Active range 0x{:016X}, size of range = 0x{:X}..".format(bar, len(list)))
|
||||
reg_off = 0
|
||||
while 1:
|
||||
rand_index = random.randint(0, len(list) -1)
|
||||
rand_index = random.randint(0, len(list) - 1)
|
||||
reg_value = self.cs.mmio.read_MMIO_reg(bar, list[rand_index])
|
||||
|
||||
rand_offset = random.randint(0, 32)
|
||||
@@ -147,14 +156,15 @@ class pcie_fuzz(BaseModule):
|
||||
self.cs.mmio.write_MMIO_reg(bar, reg_off, reg_value)
|
||||
|
||||
def find_active_range(self, bar, size):
|
||||
self.logger.log( "[*] Determine MMIO BAR Active range 0x{:016X}, size 0x{:X}..".format(bar, size) )
|
||||
self.logger.log("[*] Determine MMIO BAR Active range 0x{:016X}, size 0x{:X}..".format(bar, size))
|
||||
one = self.cs.mem.read_physical_mem(bar, size)
|
||||
time.sleep(TIMEOUT)
|
||||
two = self.cs.mem.read_physical_mem(bar, size)
|
||||
diff_index = []
|
||||
for i in range(len(one) //4 - 1):
|
||||
if one[4 *i] != two[4 *i] or one[4 *i +1] != two[4 *i +1] or one[4 *i +2] != two[4 *i +2] or one[4 *i +3] != two[4 *i +3]:
|
||||
diff_index.append(i *4)
|
||||
for i in range(len(one) // 4 - 1):
|
||||
j = 4 * i
|
||||
if (one[j] != two[j]) or (one[j + 1] != two[j + 1]) or (one[j + 2] != two[j + 2]) or (one[j + 3] != two[j + 3]):
|
||||
diff_index.append(j)
|
||||
return diff_index
|
||||
|
||||
def fuzz_pcie_device(self, b, d, f):
|
||||
@@ -164,7 +174,7 @@ class pcie_fuzz(BaseModule):
|
||||
if bar not in _EXCLUDE_BAR:
|
||||
# Fuzzing MMIO registers of the PCIe device
|
||||
if isMMIO:
|
||||
self.logger.log( "[*] + 0x{:02X} ({:X}): MMIO BAR at 0x{:016X} (64-bit? {:d}) with size: 0x{:08X}. Fuzzing..".format(bar_off, bar_reg, bar, is64bit, size) )
|
||||
self.logger.log("[*] + 0x{:02X} ({:X}): MMIO BAR at 0x{:016X} (64-bit? {:d}) with size: 0x{:08X}. Fuzzing..".format(bar_off, bar_reg, bar, is64bit, size))
|
||||
if ACTIVE_RANGE and (size > 0x1000):
|
||||
list = []
|
||||
list = self.find_active_range(bar, size)
|
||||
@@ -180,7 +190,7 @@ class pcie_fuzz(BaseModule):
|
||||
# Fuzzing I/O registers of the PCIe device
|
||||
else:
|
||||
if IO_FUZZ:
|
||||
self.logger.log( "[*] + 0x{:02X}: I/O BAR at 0x{:08X}. Fuzzing..".format(bar_off, bar) )
|
||||
self.logger.log("[*] + 0x{:02X}: I/O BAR at 0x{:08X}. Fuzzing..".format(bar_off, bar))
|
||||
self.fuzz_io_bar(bar)
|
||||
|
||||
def run(self, module_argv):
|
||||
@@ -191,16 +201,19 @@ class pcie_fuzz(BaseModule):
|
||||
_bus = int(module_argv[0], 16)
|
||||
_dev = int(module_argv[1], 16)
|
||||
_fun = int(module_argv[2], 16)
|
||||
pcie_devices.append( (_bus, _dev, _fun, 0, 0) )
|
||||
pcie_devices.append((_bus, _dev, _fun, 0, 0))
|
||||
else:
|
||||
self.logger.log("[*] Enumerating available PCIe devices..")
|
||||
pcie_devices = self.cs.pci.enumerate_devices()
|
||||
|
||||
self.logger.log("[*] About to fuzz the following PCIe devices..")
|
||||
print_pci_devices(pcie_devices)
|
||||
|
||||
for (b, d, f, _, _) in pcie_devices:
|
||||
self.logger.log( "[+] Fuzzing device {:02X}:{:02X}.{:X}".format(b, d, f) )
|
||||
self.logger.log("[+] Fuzzing device {:02X}:{:02X}.{:X}".format(b, d, f))
|
||||
self.fuzz_pcie_device(b, d, f)
|
||||
|
||||
self.logger.log_information('Module completed')
|
||||
self.logger.log_warning('System may be in an unknown state, further evaluation may be needed.')
|
||||
return ModuleResult.WARNING
|
||||
self.res = ModuleResult.WARNING
|
||||
return self.res
|
||||
|
||||
Reference in New Issue
Block a user