psptool 3.2.dev1__tar.gz → 3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. {psptool-3.2.dev1 → psptool-3.4}/.github/workflows/gha-metrics.yml +1 -0
  2. {psptool-3.2.dev1 → psptool-3.4}/.github/workflows/publish.yml +0 -23
  3. {psptool-3.2.dev1 → psptool-3.4}/.github/workflows/python-tests.yml +2 -1
  4. {psptool-3.2.dev1 → psptool-3.4}/PKG-INFO +1 -1
  5. {psptool-3.2.dev1 → psptool-3.4}/psptool/__main__.py +2 -2
  6. {psptool-3.2.dev1 → psptool-3.4}/psptool/blob.py +3 -10
  7. {psptool-3.2.dev1 → psptool-3.4}/psptool/directory.py +33 -0
  8. {psptool-3.2.dev1 → psptool-3.4}/psptool/fet.py +4 -10
  9. {psptool-3.2.dev1 → psptool-3.4}/psptool/file.py +2 -1
  10. {psptool-3.2.dev1 → psptool-3.4}/psptool/header_file.py +1 -1
  11. {psptool-3.2.dev1 → psptool-3.4}/.gitignore +0 -0
  12. {psptool-3.2.dev1 → psptool-3.4}/.gitmodules +0 -0
  13. {psptool-3.2.dev1 → psptool-3.4}/LICENSE +0 -0
  14. {psptool-3.2.dev1 → psptool-3.4}/README.md +0 -0
  15. {psptool-3.2.dev1 → psptool-3.4}/psptool/__init__.py +0 -0
  16. {psptool-3.2.dev1 → psptool-3.4}/psptool/cert_tree.py +0 -0
  17. {psptool-3.2.dev1 → psptool-3.4}/psptool/crypto.py +0 -0
  18. {psptool-3.2.dev1 → psptool-3.4}/psptool/entry.py +0 -0
  19. {psptool-3.2.dev1 → psptool-3.4}/psptool/errors.py +0 -0
  20. {psptool-3.2.dev1 → psptool-3.4}/psptool/firmware.py +0 -0
  21. {psptool-3.2.dev1 → psptool-3.4}/psptool/key_store_file.py +0 -0
  22. {psptool-3.2.dev1 → psptool-3.4}/psptool/microcode_file.py +0 -0
  23. {psptool-3.2.dev1 → psptool-3.4}/psptool/psptool.py +0 -0
  24. {psptool-3.2.dev1 → psptool-3.4}/psptool/pubkey_file.py +0 -0
  25. {psptool-3.2.dev1 → psptool-3.4}/psptool/rom.py +0 -0
  26. {psptool-3.2.dev1 → psptool-3.4}/psptool/utils.py +0 -0
  27. {psptool-3.2.dev1 → psptool-3.4}/pyproject.toml +0 -0
  28. {psptool-3.2.dev1 → psptool-3.4}/tests/__init__.py +0 -0
  29. {psptool-3.2.dev1 → psptool-3.4}/tests/create_metrics.sh +0 -0
  30. {psptool-3.2.dev1 → psptool-3.4}/tests/gha_metrics.py +0 -0
  31. {psptool-3.2.dev1 → psptool-3.4}/tests/integration/__init__.py +0 -0
  32. {psptool-3.2.dev1 → psptool-3.4}/tests/integration/test_psptrace.py +0 -0
  33. {psptool-3.2.dev1 → psptool-3.4}/tests/integration/test_rom_files.py +0 -0
  34. {psptool-3.2.dev1 → psptool-3.4}/tests/metrics.txt +0 -0
  35. {psptool-3.2.dev1 → psptool-3.4}/tests/unit/__init__.py +0 -0
  36. {psptool-3.2.dev1 → psptool-3.4}/tests/unit/test_cli.py +0 -0
@@ -13,6 +13,7 @@ jobs:
13
13
  steps:
14
14
  - uses: actions/checkout@v3
15
15
  with:
16
+ ref: ${{ github.event.pull_request.head.sha }}
16
17
  submodules: recursive
17
18
  ssh-key: ${{ secrets.PSPTOOL_FIXTURES_NEW_PRIVATE_KEY }}
18
19
  - name: Set up Python ${{ matrix.python-version }}
@@ -49,26 +49,3 @@ jobs:
49
49
  path: dist/
50
50
  - name: Publish distribution to PyPI
51
51
  uses: pypa/gh-action-pypi-publish@release/v1
52
-
53
- publish-to-testpypi:
54
- name: >-
55
- Publish Python distribution to TestPyPI
56
- needs:
57
- - build
58
- runs-on: ubuntu-latest
59
- environment:
60
- name: testpypi
61
- url: https://test.pypi.org/p/psptool/
62
- permissions:
63
- id-token: write # important for trusted publishing
64
- steps:
65
- - name: Download all the dists
66
- uses: actions/download-artifact@v4
67
- with:
68
- name: python-package-distributions
69
- path: dist/
70
- - name: Publish distribution to TestPyPI
71
- uses: pypa/gh-action-pypi-publish@release/v1
72
- with:
73
- repository-url: https://test.pypi.org/legacy/
74
- verbose: true
@@ -1,6 +1,6 @@
1
1
  name: Python tests
2
2
 
3
- on: [push]
3
+ on: [push, pull_request_target]
4
4
 
5
5
  jobs:
6
6
  test:
@@ -13,6 +13,7 @@ jobs:
13
13
  steps:
14
14
  - uses: actions/checkout@v3
15
15
  with:
16
+ ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || github.sha }}
16
17
  submodules: recursive
17
18
  ssh-key: ${{ secrets.PSPTOOL_FIXTURES_NEW_PRIVATE_KEY }}
18
19
  - name: Set up Python ${{ matrix.python-version }}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: psptool
3
- Version: 3.2.dev1
3
+ Version: 3.4
4
4
  Summary: PSPTool is a tool for dealing with AMD binary blobs
5
5
  Author-email: Christian Werling <cwerling@posteo.de>
6
6
  License-File: LICENSE
@@ -193,7 +193,7 @@ def main():
193
193
  if args.decompress and type(file) is HeaderFile:
194
194
  out_bytes = file.get_signed_bytes()
195
195
  elif args.decrypt and type(file) is HeaderFile:
196
- out_bytes = file.get_decrypted()
196
+ out_bytes = file.get_decrypted_body()
197
197
  elif args.pem_key and type(file) is PubkeyFile:
198
198
  out_bytes = file.get_pem_encoded()
199
199
  else:
@@ -216,7 +216,7 @@ def main():
216
216
  if args.decompress and type(file) is HeaderFile:
217
217
  out_bytes = file.get_signed_bytes()
218
218
  elif args.decrypt and type(file) is HeaderFile:
219
- out_bytes = file.get_decrypted()
219
+ out_bytes = file.get_decrypted_body()
220
220
  elif args.pem_key and type(file) is PubkeyFile:
221
221
  out_bytes = file.get_pem_encoded()
222
222
  else:
@@ -179,13 +179,6 @@ class Blob(NestedBuffer):
179
179
  found_pkes += self._find_inline_pubkeys(key_id)
180
180
  return found_pkes
181
181
 
182
- def get_entries_by_type(self, type_) -> List[File]:
183
- entries = []
184
-
185
- for rom in self.roms:
186
- for _dir in rom.directories:
187
- for entry in _dir.entries:
188
- if entry.type == type_:
189
- entries.append(entry)
190
-
191
- return entries
182
+ def get_files_by_type(self, type_) -> List[File]:
183
+ all_files = self.unique_files()
184
+ return list(filter(lambda f: f.type == type_, all_files))
@@ -31,6 +31,22 @@ class Directory(NestedBuffer):
31
31
  ENTRY_SIZE = DirectoryEntry.ENTRY_SIZE
32
32
  FILE_CLASS = File
33
33
 
34
+ ZEN_GENERATION_IDS = {'Zen 1' : [b'\x00\x09\xBC', b'\x00\x0A\xBC'],
35
+ 'Zen 2' : [b'\x05\x0B\xBC', b'\x01\x0A\xBC'],
36
+ 'Zen 3' : [b'\x01\x0C\xBC', b'\x00\x0C\xBC'],
37
+ 'Zen 4' : [b'\x04\x0D\xBC', b'\x0B\x0D\xBC'],
38
+ 'Zen 4/5': [b'\x03\x0D\xBC']
39
+ }
40
+
41
+ @classmethod
42
+ def get_possible_zen_generation(cls, zen_generation_id):
43
+ zen_generation = 'unknown'
44
+ for possible_zen_generation in cls.ZEN_GENERATION_IDS:
45
+ if zen_generation_id in cls.ZEN_GENERATION_IDS[possible_zen_generation]:
46
+ zen_generation = possible_zen_generation
47
+
48
+ return zen_generation
49
+
34
50
  class ParseError(Exception):
35
51
  pass
36
52
 
@@ -43,6 +59,7 @@ class Directory(NestedBuffer):
43
59
  # Recursively return or create and return found directories
44
60
 
45
61
  if offset in fet.psptool.directories_by_offset:
62
+ fet.psptool.directories_by_offset[offset].update_zen_generation(fet, zen_generation)
46
63
  return [fet.psptool.directories_by_offset[offset]]
47
64
  else:
48
65
  # 1. Create the immediate directory in front of us
@@ -69,6 +86,14 @@ class Directory(NestedBuffer):
69
86
  for tertiary_directory_offset in directory.tertiary_directory_offsets:
70
87
  directory_body = fet.rom.get_bytes(tertiary_directory_offset, 32)
71
88
  actual_tertiary_offset = int.from_bytes(directory_body[16:20], 'little')
89
+ zen_generation_id = directory_body[21:24]
90
+ zen_generation = cls.get_possible_zen_generation(zen_generation_id)
91
+ if zen_generation == 'unknown':
92
+ fet.psptool.ph.print_warning(f"Unknown {zen_generation_id=}")
93
+
94
+ zen_generation_id = hex(int.from_bytes(directory_body[20:24], 'little'))
95
+ zen_generation += f' (PSP ID {zen_generation_id})'
96
+
72
97
  # Resolve one more indirection
73
98
  tertiary_directories = cls.create_directories_if_not_exist(actual_tertiary_offset, fet, zen_generation)
74
99
  created_directories += tertiary_directories
@@ -198,6 +223,14 @@ class Directory(NestedBuffer):
198
223
  # 3. Update checksum
199
224
  self.update_checksum()
200
225
 
226
+ def update_zen_generation(self, fet, zen_generation):
227
+ if zen_generation is not None:
228
+ if zen_generation not in self.zen_generation:
229
+ self.zen_generation += '\n' + zen_generation
230
+ for offset in self.secondary_directory_offsets:
231
+ dir = fet.psptool.directories_by_offset[offset]
232
+ dir.update_zen_generation(fet, zen_generation)
233
+
201
234
 
202
235
  class BiosDirectory(Directory):
203
236
  DIRECTORY_MAGICS = [b'$BHD', b'$BL2']
@@ -19,12 +19,6 @@ from .directory import Directory
19
19
 
20
20
  from typing import List
21
21
 
22
-
23
- ZEN_GENERATION_IDS = {'Zen 1': [b'\x00\x09\xBC', b'\x00\x0A\xBC'],
24
- 'Zen 2': [b'\x05\x0B\xBC', b'\x01\x0A\xBC'],
25
- 'Zen 3': [b'\x01\x0C\xBC', b'\x00\x0C\xBC']}
26
-
27
-
28
22
  class EmptyFet(Exception):
29
23
  pass
30
24
 
@@ -121,13 +115,13 @@ class Fet(NestedBuffer):
121
115
 
122
116
  # entry_addr += self.blob_offset
123
117
  zen_generation_id = combo_dir[i*16+5:i*16+8]
124
- zen_generation = 'unknown'
125
- for possible_zen_generation in ZEN_GENERATION_IDS:
126
- if zen_generation_id in ZEN_GENERATION_IDS[possible_zen_generation]:
127
- zen_generation = possible_zen_generation
118
+ zen_generation = Directory.get_possible_zen_generation(zen_generation_id)
128
119
  if zen_generation == 'unknown':
129
120
  self.psptool.ph.print_warning(f"Unknown {zen_generation_id=}")
130
121
 
122
+ zen_generation_id = hex(int.from_bytes(combo_dir[i*16+4:i*16+8], byteorder='little'))
123
+ zen_generation += f' (PSP ID {zen_generation_id})'
124
+
131
125
  results.append((entry_addr, zen_generation))
132
126
 
133
127
  return results
@@ -229,6 +229,7 @@ class File(NestedBuffer):
229
229
  0x6F: 'OEM_LOGO_IMAGE',
230
230
  0x77: 'DDRPHY_PCU_FW',
231
231
  0x7B: 'MPRAS_TRUSTRED_APP_IMG',
232
+ 0x7C: 'OC_SWEET_SPOT_PROFILE',
232
233
  }
233
234
 
234
235
  PUBKEY_ENTRY_TYPES = [0x0, 0x9, 0xa, 0x5, 0xd, 0x43, 0x4e, 0x53, 0x81, 0x97, 0xad ]
@@ -237,7 +238,7 @@ class File(NestedBuffer):
237
238
  # TODO: Find a better way to identify those entries
238
239
  NO_HDR_ENTRY_TYPES = [0x4, 0xb, 0x21, 0x40, 0x48, 0x49, 0x4a, 0x70, 0x6, 0x61, 0x60, 0x68, 0x5f,
239
240
  0x1a, 0x22, 0x63, 0x67, 0x66, 0x6d, 0x62, 0x61, 0x7, 0x38, 0x46, 0x54,
240
- 0x82, 0x84, 0x8d, 0x69 ]
241
+ 0x82, 0x84, 0x8d, 0x69, 0x7c, 0x98 ]
241
242
 
242
243
  NO_SIZE_ENTRY_TYPES = [0xb]
243
244
  KEY_STORE_TYPES = [0x50, 0x51]
@@ -132,7 +132,7 @@ class HeaderFile(File):
132
132
  return '.'.join([hex(b)[2:].upper() for b in self.version])
133
133
 
134
134
  def get_ikek_md5sum(self) -> bytes:
135
- ikek = self.parent_buffer.get_entries_by_type(0x21)[0]
135
+ ikek = self.parent_buffer.get_files_by_type(0x21)[0]
136
136
  m = md5()
137
137
  m.update(ikek.get_bytes())
138
138
  return m.digest()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes