import sys import os import math import uuid import struct import configparser from struct import unpack, pack from binascii import crc32 if len(sys.argv) > 4 or len(sys.argv) < 2: print("Usage: python3 resize_user.py [path to prod.keys or bis_key_03 in hex]") exit() try: from mbedtls import cipher except ModuleNotFoundError: print("This requires python-mbedtls. You can install it via 'pip install --user python-mbedtls'") exit() try: f = open(sys.argv[1], "r+b") except FileNotFoundError: print("Please enter an valid filename") exit() try: user_sector_size = int(float(sys.argv[2]) * (1024 ** 3) // 512) except ValueError: print("Please enter a floating point number in GiB") exit() if user_sector_size < 65536: print("USER must be greater than 32MiB (0.3125 GiB)") exit() try: with open(os.path.join(os.path.expanduser('~'), '.switch', 'prod.keys'), 'r') as k: c = configparser.ConfigParser() c.read_string("[keys]\n" + k.read()) key = bytes.fromhex(c["keys"]["bis_key_03"]) except FileNotFoundError: if len(sys.argv) > 3: try: with open(sys.argv[3], 'r') as k: c = configparser.ConfigParser() c.read_string("[keys]\n" + k.read()) key = bytes.fromhex(c["keys"]["bis_key_03"]) except FileNotFoundError: if len(sys.argv[3]) == 64: try: key = bytes.fromhex(sys.argv[3]) except ValueError: print("Please either place a prod.keys with bis_key_03 in ~/.switch/prod.keys, or enter a valid third argument with either the location of a prod.keys or your bis_key_03") exit() else: print("Please either place a prod.keys with bis_key_03 in ~/.switch/prod.keys, or enter a valid third argument with either the location of a prod.keys or your bis_key_03") exit() else: print("Please either place a prod.keys with bis_key_03 in ~/.switch/prod.keys, or enter a valid third argument with either the location of a prod.keys or your bis_key_03") exit() def parse_gpt_header(header): f.seek(0x800000 + (2 * 512) + (10 * 128)) usr = unpack('< 16s 16s Q Q Q 72s', header) name = usr[5].decode('utf-16le') print("Partition type GUID:\t", uuid.UUID(bytes_le=usr[0])) print("Unique Partition GUID:\t", uuid.UUID(bytes_le=usr[1])) print("Starting LBA:\t\t", usr[2]) print("Ending LBA:\t\t", usr[3]) print("Attributes:\t\t", usr[4]) print("Name:\t\t\t", usr[5].decode('utf-16le')) print("Size:\t\t\t", (usr[3] - usr[2] + 1) * 512 / 1024 ** 3, "GiB") def fix_user_partition_entry(size): # Read out gpt entry for sanity # parse_gpt_header(f.read(128)) f.seek(0x800000 + 512) magic, = unpack("<8s", f.read(8)) if magic != b"EFI PART": print("Error reading GPT header. Possible invalid emuMMC image: ", magic) exit() # calculate new end sector f.seek(0x800000 + (2 * 512) + (10 * 128) + 32) lba_start, = unpack("