binarly-io / fwhunt-scan

Tools for analyzing UEFI firmware and checking UEFI modules with FwHunt rules
GNU General Public License v3.0
210 stars 30 forks source link

Added command to extract all UEFI modules #53

Closed phretor closed 1 year ago

phretor commented 1 year ago

I added a utility command to extract all valid modules (regardless of their GUIDs) into a given folder. I find the result of UefiExtractor() easier to use and better organized than what UEFIExtract produces, so I thought this may be useful to others.

$ python fwhunt_scan_analyzer.py extract fw-image.bin /tmp
5c266089-e103-4d43-9ab5-12d7095be2af -> /tmp/5c266089-e103-4d43-9ab5-12d7095be2af-IntelSaGopDriver.dxe
5bba83e6-f027-4ca7-bfd0-16358cc9e123 -> /tmp/5bba83e6-f027-4ca7-bfd0-16358cc9e123-IntelGopDriver.dxe
5007a40e-a5e0-44f7-86ae-662f9a91da26 -> /tmp/5007a40e-a5e0-44f7-86ae-662f9a91da26-FvOnFv2Thunk.dxe
e03abadf-e536-4e88-b3a0-b77f78eb34fe -> /tmp/e03abadf-e536-4e88-b3a0-b77f78eb34fe-CpuDxe.dxe
f50d4740-9ecd-4c3a-b5de-bdf99eadfa7d -> /tmp/f50d4740-9ecd-4c3a-b5de-bdf99eadfa7d-DellTcgAddSolDxe.dxe
196ca3d8-9a5a-4735-b328-8ffc1d93d188 -> /tmp/196ca3d8-9a5a-4735-b328-8ffc1d93d188-DellTcgPlatformSetupPolicy.dxe
5e9caba3-f2b1-497a-adac-24f575e9cde9 -> /tmp/5e9caba3-f2b1-497a-adac-24f575e9cde9-TcgDxe.dxe
93022f8c-1f09-47ef-bbb2-5814ff609df5 -> /tmp/93022f8c-1f09-47ef-bbb2-5814ff609df5-FileSystem.dxe
cbc59c4a-383a-41eb-a8ee-4498aea567e4 -> /tmp/cbc59c4a-383a-41eb-a8ee-4498aea567e4-Runtime.dxe
0a602c5b-05a0-40c4-9181-edcd891d0001 -> /tmp/0a602c5b-05a0-40c4-9181-edcd891d0001-OememDxeCore.dxe
3c1de39f-d207-408a-aacc-731cfb7f1dd7 -> /tmp/3c1de39f-d207-408a-aacc-731cfb7f1dd7-PciBus.dxe
9f3a0016-ae55-4288-829d-d22fd344c347 -> /tmp/9f3a0016-ae55-4288-829d-d22fd344c347-AmiBoardInfo.dxe
13ac6dd0-73d0-11d4-b06b-00aa00bd6de7 -> /tmp/13ac6dd0-73d0-11d4-b06b-00aa00bd6de7-EBC.dxe
62d171cb-78cd-4480-8678-c6a2a797a8de -> /tmp/62d171cb-78cd-4480-8678-c6a2a797a8de-CpuInitDxe.dxe
f7731b4c-58a2-4df4-8980-5645d39ece58 -> /tmp/f7731b4c-58a2-4df4-8980-5645d39ece58-PowerMgmtDxe.dxe
8f0b5301-c79b-44f1-8fd3-26d73e316700 -> /tmp/8f0b5301-c79b-44f1-8fd3-26d73e316700-PowerMgmtS3.dxe
15b9b6da-00a9-4de7-b8e8-ed7afb88f16e -> /tmp/15b9b6da-00a9-4de7-b8e8-ed7afb88f16e-CpuPolicyDxe.dxe
77a6009e-116e-464d-8ef8-b35201a022dd -> /tmp/77a6009e-116e-464d-8ef8-b35201a022dd-DigitalThermalSensorSmm.dxe
ff917e22-a228-448d-bdaa-68efccdda5d3 -> /tmp/ff917e22-a228-448d-bdaa-68efccdda5d3-TxtDxe.dxe
...

To ignore the GUIDs I had to refactor UefiExtractor.extract_all() to take the ignore_guids=True argument. This doesn't affect the other code as the loop is now conditioned by ignore_guids and the existing condition:

class UefiExtractor:
    # ...
    def extract_all(self, ignore_guid=False) -> None:
        self._extract()
        for guid in self._info:
            if self._info[guid]["content"] is not None and \
                (guid in self._file_guids or ignore_guid):

                self.binaries.append(
                    UefiBinary(
                        content=self._info[guid]["content"],
                        name=self._info[guid]["name"],
                        guid=guid,
                        ext=self._info[guid]["ext"],
                    )
                )

Signed-off-by: Federico Maggi federico.maggi@gmail.com

xorpse commented 1 year ago

Thank you!