PSPReverse / PSPTool

Display, extract, and manipulate PSP firmware inside UEFI images
GNU General Public License v3.0
612 stars 62 forks source link

Failing Parse on MSI MPG X670E Carbon #57

Closed joshgarde closed 2 months ago

joshgarde commented 8 months ago

Attempting to parse the latest BIOS for the MSI MPG X670E Carbon appears to be failing.

PSP Tool version: 2.7

Output:

$ psptool E7D70AMS.1E0
Warning: Skipping FET at 0x1000 due to unknown ROM alignment
Warning: Couldn't parse entry at: 0x83020. Type: 0x48. Size 0x100
Warning: Couldn't parse entry at: 0x83040. Type: 0x48. Size 0x100
Warning: Couldn't parse entry at: 0x83060. Type: 0x48. Size 0x100
Warning: Couldn't parse entry at: 0x84000. Type: 0x4a. Size 0x100
Traceback (most recent call last):
  File "/home/jgarde/.local/bin/psptool", line 8, in <module>
    sys.exit(main())
  File "/home/jgarde/.local/lib/python3.10/site-packages/psptool/__main__.py", line 105, in main
    psp = PSPTool.from_file(args.file, verbose=args.verbose)
  File "/home/jgarde/.local/lib/python3.10/site-packages/psptool/psptool.py", line 33, in from_file
    pt = PSPTool(file_bytes, verbose=verbose)
  File "/home/jgarde/.local/lib/python3.10/site-packages/psptool/psptool.py", line 41, in __init__
    self.blob = Blob(rom_bytes, len(rom_bytes), self)
  File "/home/jgarde/.local/lib/python3.10/site-packages/psptool/blob.py", line 68, in __init__
    potential_rom = Rom(self, rom_size, rom_offset, fet_offset, psptool)
  File "/home/jgarde/.local/lib/python3.10/site-packages/psptool/rom.py", line 20, in __init__
    self.fet = Fet(self, fet_offset, psptool)
  File "/home/jgarde/.local/lib/python3.10/site-packages/psptool/fet.py", line 45, in __init__
    self._parse_entry_table()
  File "/home/jgarde/.local/lib/python3.10/site-packages/psptool/fet.py", line 118, in _parse_entry_table
    self._create_directory(rom_addr, dir_magic, zen_generation='unknown')
  File "/home/jgarde/.local/lib/python3.10/site-packages/psptool/fet.py", line 89, in _create_directory
    secondary_dir = Directory(self.rom, secondary_directory_address, 'secondary', self.psptool, zen_generation)
  File "/home/jgarde/.local/lib/python3.10/site-packages/psptool/directory.py", line 67, in __init__
    self._parse_header()
  File "/home/jgarde/.local/lib/python3.10/site-packages/psptool/directory.py", line 116, in _parse_header
    self.header = NestedBuffer(
  File "/home/jgarde/.local/lib/python3.10/site-packages/psptool/utils.py", line 48, in __init__
    assert (self.buffer_size <= self.buffer_offset + self.buffer_size), \
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'
vanishingfork commented 7 months ago

Experiencing the same issue with my MSI PRO B650M-A WIFI Tested versions: 7D77v1F (latest) 7D77v12 (initial release) PSPTool version: 2.8.dev3+g9841727 Output:


Warning: Skipping FET at 0x1000 due to unknown ROM alignment
Warning: Couldn't parse entry at: 0x83020. Type: 0x48. Size 0x100
Warning: Couldn't parse entry at: 0x83040. Type: 0x48. Size 0x100
Warning: Couldn't parse entry at: 0x83060. Type: 0x48. Size 0x100
Warning: Couldn't parse entry at: 0x84000. Type: 0x4a. Size 0x100
Traceback (most recent call last):
  File "c:\python39\lib\runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "c:\python39\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Python39\Scripts\psptool.exe\__main__.py", line 7, in <module>
  File "c:\python39\lib\site-packages\psptool\__main__.py", line 105, in main
    psp = PSPTool.from_file(args.file, verbose=args.verbose)
  File "c:\python39\lib\site-packages\psptool\psptool.py", line 33, in from_file
    pt = PSPTool(file_bytes, verbose=verbose)
  File "c:\python39\lib\site-packages\psptool\psptool.py", line 41, in __init__
    self.blob = Blob(rom_bytes, len(rom_bytes), self)
  File "c:\python39\lib\site-packages\psptool\blob.py", line 68, in __init__
    potential_rom = Rom(self, rom_size, rom_offset, fet_offset, psptool)
  File "c:\python39\lib\site-packages\psptool\rom.py", line 20, in __init__
    self.fet = Fet(self, fet_offset, psptool)
  File "c:\python39\lib\site-packages\psptool\fet.py", line 45, in __init__
    self._parse_entry_table()
  File "c:\python39\lib\site-packages\psptool\fet.py", line 118, in _parse_entry_table
    self._create_directory(rom_addr, dir_magic, zen_generation='unknown')
  File "c:\python39\lib\site-packages\psptool\fet.py", line 89, in _create_directory
    secondary_dir = Directory(self.rom, secondary_directory_address, 'secondary', self.psptool, zen_generation)
  File "c:\python39\lib\site-packages\psptool\directory.py", line 76, in __init__
    self._parse_entries()
  File "c:\python39\lib\site-packages\psptool\directory.py", line 140, in _parse_entries
    entry_fields['offset'] &= self.rom.addr_mask
KeyError: 'offset'
cwerling commented 7 months ago

Check out latest master as of now https://github.com/PSPReverse/PSPTool/commit/765a3f658ebfb97e94c74e2663b204b06e995c31, it should parse now at least. I had to add two more weird directory magics for some equally weird new directory format I don't understand yet. Let me know if you do.

vanishingfork commented 7 months ago

It parses now for the following versions, the 3rd board was chosen to test if the same problem occurs with other vendors:

PSPTool -V: 2.8.dev5+g59576e6

The following firmware versions fail to parse:

I don't know anything about AGESA but maybe the 1.1.0.0 release changed something.

The following error was seen:

> PSPTool .\E7D77AMS.1C0
Warning: Skipping FET at 0x1000 due to unknown ROM alignment
Warning: Couldn't parse entry at: 0x83020. Type: 0x48. Size 0x100
Warning: Couldn't parse entry at: 0x83040. Type: 0x48. Size 0x100
Warning: Couldn't parse entry at: 0x83060. Type: 0x48. Size 0x100
Warning: Couldn't parse entry at: 0x84000. Type: 0x4a. Size 0x100
Warning: Couldn't parse entry at: 0x7c0000. Type: 0x49. Size 0x400
Warning: Couldn't parse entry at: 0x751c00. Type: 0x8d. Size 0x30
Warning: Couldn't parse entry at: 0xab0000. Type: 0x93. Size 0x28000
Warning: Couldn't parse entry at: 0xad8000. Type: 0x93. Size 0x28000
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x7c0000, type=secondary, magic=b'$BL2', count=19) at 0x15c2000 cannot be parsed
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x7c0000, type=secondary, magic=b'$BL2', count=19) at 0x13c2000 cannot be parsed
Warning: Couldn't parse plain entry: 0x63
Warning: Entry of Directory(address=0x7c0000, type=secondary, magic=b'$BL2', count=19) at 0x1760000 cannot be parsed
Warning: Entry of Directory(address=0x7c0000, type=secondary, magic=b'$BL2', count=19) at 0x1360000 cannot be parsed
Warning: Entry of Directory(address=0x7c0000, type=secondary, magic=b'$BL2', count=19) at 0x1380000 cannot be parsed
Warning: Entry of Directory(address=0x7c0000, type=secondary, magic=b'$BL2', count=19) at 0x1350000 cannot be parsed
Warning: Entry of Directory(address=0x7c0000, type=secondary, magic=b'$BL2', count=19) at 0x13a0000 cannot be parsed
Traceback (most recent call last):
  File "c:\python39\lib\runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "c:\python39\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Python39\Scripts\psptool.exe\__main__.py", line 7, in <module>
  File "c:\python39\lib\site-packages\psptool\__main__.py", line 105, in main
    psp = PSPTool.from_file(args.file, verbose=args.verbose)
  File "c:\python39\lib\site-packages\psptool\psptool.py", line 33, in from_file
    pt = PSPTool(file_bytes, verbose=verbose)
  File "c:\python39\lib\site-packages\psptool\psptool.py", line 41, in __init__
    self.blob = Blob(rom_bytes, len(rom_bytes), self)
  File "c:\python39\lib\site-packages\psptool\blob.py", line 68, in __init__
    potential_rom = Rom(self, rom_size, rom_offset, fet_offset, psptool)
  File "c:\python39\lib\site-packages\psptool\rom.py", line 20, in __init__
    self.fet = Fet(self, fet_offset, psptool)
  File "c:\python39\lib\site-packages\psptool\fet.py", line 45, in __init__
    self._parse_entry_table()
  File "c:\python39\lib\site-packages\psptool\fet.py", line 121, in _parse_entry_table
    self._create_directory(rom_addr, dir_magic, zen_generation='unknown')
  File "c:\python39\lib\site-packages\psptool\fet.py", line 92, in _create_directory
    secondary_dir = Directory(self.rom, secondary_directory_address, 'secondary', self.psptool, zen_generation)
  File "c:\python39\lib\site-packages\psptool\directory.py", line 76, in __init__
    self._parse_entries()
  File "c:\python39\lib\site-packages\psptool\directory.py", line 140, in _parse_entries
    entry_fields['offset'] &= self.rom.addr_mask
KeyError: 'offset'
cwerling commented 7 months ago

Fixed your firmware files with https://github.com/PSPReverse/PSPTool/commit/0299688cd18cf8b1616b01959779dc5a61cc1adc

Let me know if you have any clue how to properly identify these directories.

joshgarde commented 7 months ago

I do have a logic trace on the SPI during boot for the board so I can try working on the directory structure

cwerling commented 2 months ago

Check out the zen5 branch for proper parsing of these directories. Still work-in-progress though.