Created
June 28, 2023 20:36
-
-
Save Cryptogenic/aab893a2c608f2aeb117983fd97822d8 to your computer and use it in GitHub Desktop.
Script for extracting and parsing MSR protection maps in ps5 kernel dumps
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
#!/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