Last active
May 6, 2021 13:55
-
-
Save SocraticBliss/dab7c20ba1d88043d27d70a17c5eb800 to your computer and use it in GitHub Desktop.
PS4 SysCon Patch Decryptor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
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