Skip to content

Instantly share code, notes, and snippets.

@SocraticBliss
Last active May 6, 2021 13:55
Show Gist options
  • Save SocraticBliss/dab7c20ba1d88043d27d70a17c5eb800 to your computer and use it in GitHub Desktop.
Save SocraticBliss/dab7c20ba1d88043d27d70a17c5eb800 to your computer and use it in GitHub Desktop.
PS4 SysCon Patch Decryptor
'''
PS4 SysCon Patch Decryptor by SocraticBliss (R)
Thanks to zecoxao <3
1) Replace AES CBC Key on line 50 with the actual key
2) Replace AES CMAC Key on line 50 with the actual key
3) Place in your PS4UPDATE1/dev directory
4) python ps4_syscon_patch_decryptor.py
'''
from binascii import unhexlify as uhx, hexlify as hx
from Crypto.Cipher import AES
from Crypto.Hash import CMAC
import struct
import sys
class SBL2:
__slots__ = ('MAGIC', 'VERSION', 'FLAGS', 'FILE_COUNT', 'BLOCK_COUNT', 'PADDING')
def __init__(self, f):
f.seek(0)
# Header
self.MAGIC = struct.unpack('<4s', f.read(4))[0]
self.VERSION = struct.unpack('<I', f.read(4))[0]
self.FLAGS = struct.unpack('<I', f.read(4))[0]
self.FILE_COUNT = struct.unpack('<I', f.read(4))[0]
self.BLOCK_COUNT = struct.unpack('<I', f.read(4))[0]
self.PADDING = struct.unpack('12x', f.read(12))
# SBL2 Entries
SBL2.ENTRIES = [ENTRY(f) for entry in range(self.FILE_COUNT)]
class ENTRY:
__slots__ = ('BLOCK_OFFSET', 'FILE_SIZE', 'ALIGNMENT_1', 'ALIGNMENT_2', 'FILE_NAME')
def __init__(self, f):
self.BLOCK_OFFSET = struct.unpack('<I', f.read(4))[0]
self.FILE_SIZE = struct.unpack('<I', f.read(4))[0]
self.ALIGNMENT_1 = struct.unpack('<I', f.read(4))[0]
self.ALIGNMENT_2 = struct.unpack('<I', f.read(4))[0]
self.FILE_NAME = struct.unpack('<32s', f.read(32))[0]
KEYS = [
# Patch Firmware
# AES CBC Key and AES CMAC Key
['AES CBC Key', 'AES CMAC Key'],
]
def aes_cbc_decrypt(key, data):
return AES.new(uhx(key), AES.MODE_CBC).decrypt(data)
def aes_cmac_decrypt(key, data):
return CMAC.new(uhx(key), msg = data, ciphermod = AES).digest()
def decrypt(data):
cbc_data = aes_cbc_decrypt(KEYS[0][0], data)
cmac_data = aes_cmac_decrypt(KEYS[0][1], cbc_data[0x10:])
return cbc_data
# Unpack and Decrypt SysCon Patch Firmware...
def main(argc, argv):
if argc != 1:
raise SystemExit('\nUsage: python ps4_syscon_patch_decryptor.py')
with open('sc_fw_update0', 'rb') as input:
PUP = input.read()
try:
for entry in SBL2(input).ENTRIES:
# Block Size = 512 or 0x200
offset = entry.BLOCK_OFFSET * 0x200
data = PUP[offset:offset + entry.FILE_SIZE]
name = entry.FILE_NAME.split(b'\x00', 1)[0].decode('utf8')
if name in ['40010001', '40010002']:
with open(name, 'wb') as encrypted, open('%s.dec' % name, 'wb') as decrypted:
encrypted.write(data)
data = decrypt(data)
decrypted.write(data)
except:
print('\nYou forgot to enter the proper keys didn\'t you?')
if __name__ == '__main__':
main(len(sys.argv), sys.argv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment