Skip to content

Instantly share code, notes, and snippets.

@Cryptogenic
Created June 28, 2023 20:36
Show Gist options
  • Save Cryptogenic/aab893a2c608f2aeb117983fd97822d8 to your computer and use it in GitHub Desktop.
Save Cryptogenic/aab893a2c608f2aeb117983fd97822d8 to your computer and use it in GitHub Desktop.
Script for extracting and parsing MSR protection maps in ps5 kernel dumps
#!/usr/bin/env python3
'''
Script to parse an MSR protection map from a binary dump
@SpecterDev
'''
import argparse
import os
# Support hex int args
def auto_int(x):
return int(x, 0)
# Helper function that'll check if a given bit in a given byte is set
def check_bit(byte, pos):
return (byte >> pos) & 1
# Helper function that'll calculate a given MSRs offset in a bitmap
def get_bitmap_byte_pos(msr_offset, base_offset):
return base_offset + int(msr_offset / 4)
# Check if a given MSR is protected
def check_msr(data, msr_offset, is_write):
# If the MSR is in the upper ranges, we need to account for that
base_offset = 0
if msr_offset <= 0x1FFF:
base_offset = 0
elif msr_offset >= 0xC0000000 and msr_offset <= 0xC0001FFF:
base_offset = 0x800
elif msr_offset >= 0xC0010000 and msr_offset <= 0xC0011FFF:
base_offset = 0x1000
else:
print("MSR offset '{:08x}' is invalid!".format(msr_offset))
os.exit(1)
byte_pos = get_bitmap_byte_pos(msr_offset & 0x1FFF, base_offset)
# Each byte supports 4 MSRs, which consists of two bits reach (read, write)
bit_pos = int(msr_offset % 4)
bit_pos *= 2
# Write bit is next to read bit
if is_write:
bit_pos += 1
bitmap_byte = data[byte_pos]
return check_bit(bitmap_byte, bit_pos)
# Iterates through a range of MSRs
def check_msr_range(msr_start, msr_end, data):
for msr_cur in range(msr_start, msr_end+1):
protected_str = ''
is_protected_read = check_msr(data, msr_cur, 0)
is_protected_write = check_msr(data, msr_cur, 1)
if is_protected_read:
protected_str = 'READ'
if is_protected_write:
if is_protected_read:
protected_str += ' & '
protected_str += 'WRITE'
if protected_str != '':
print("MSR {:08x} protected: {}".format(msr_cur, protected_str))
else:
print("MSR {:08x} is NOT protected".format(msr_cur))
return
# Main
if __name__ == '__main__':
msrpm = b''
parser = argparse.ArgumentParser()
parser.add_argument('--file', type=str, required=True)
parser.add_argument('--offset', type=auto_int, required=True)
args = parser.parse_args()
with open(args.file, 'rb') as f:
f.seek(args.offset)
msrpm = f.read(0x2000)
check_msr_range(0x00000000, 0x00001FFF, msrpm)
check_msr_range(0xC0000000, 0xC0001FFF, msrpm)
check_msr_range(0xC0010000, 0xC0011FFF, msrpm)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment