From da4afbd4587d6414841dba7e728d1c941afdc967 Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 17 Oct 2026 02:11:51 -0400 Subject: [PATCH 01/12] Tabs to spaces. --- samples/install_app/make_fself.py | 1348 ++++++++++++++--------------- 1 file changed, 674 insertions(+), 674 deletions(-) diff --git a/samples/install_app/make_fself.py b/samples/install_app/make_fself.py index 86f1109b..9adb3066 100755 --- a/samples/install_app/make_fself.py +++ b/samples/install_app/make_fself.py @@ -5,278 +5,278 @@ import argparse, re, string def int_with_base_type(val): - return int(val, 0) + return int(val, 0) def try_parse_int(x, base=0): - try: - return int(x, base) if isinstance(x, str) else int(x) - except: - return None + try: + return int(x, base) if isinstance(x, str) else int(x) + except: + return None def align_up(x, alignment): - return (x + (alignment - 1)) & ~(alignment - 1) + return (x + (alignment - 1)) & ~(alignment - 1) def align_down(x, alignment): - return x & ~(alignment - 1) + return x & ~(alignment - 1) def ilog2(x): - if x <= 0: - raise ValueError('math domain error') - return len(bin(x)) - 3 + if x <= 0: + raise ValueError('math domain error') + return len(bin(x)) - 3 def is_intervals_overlap(p1, p2): - return p1[0] <= p2[1] and p1[1] <= p2[0] + return p1[0] <= p2[1] and p1[1] <= p2[0] def check_file_magic(f, expected_magic): - old_offset = f.tell() - try: - magic = f.read(len(expected_magic)) - except: - return False - finally: - f.seek(old_offset) - return magic == expected_magic + old_offset = f.tell() + try: + magic = f.read(len(expected_magic)) + except: + return False + finally: + f.seek(old_offset) + return magic == expected_magic def parse_version(version): - major, minor, patch = (version >> 8) & 0xFF, version & 0xFF, 0 # FIXME - major = 10 * (major >> 4) + (major & 0xF) - minor = 10 * (minor >> 4) + (minor & 0xF) - return '{0:d}.{1:02d}.{2:03d}'.format(major, minor, patch) + major, minor, patch = (version >> 8) & 0xFF, version & 0xFF, 0 # FIXME + major = 10 * (major >> 4) + (major & 0xF) + minor = 10 * (minor >> 4) + (minor & 0xF) + return '{0:d}.{1:02d}.{2:03d}'.format(major, minor, patch) def sha256(data): - return hashlib.sha256(data).digest() + return hashlib.sha256(data).digest() def hmac_sha256(key, data): - return hmac.new(key=key, msg=data, digestmod=hashlib.sha256).digest() + return hmac.new(key=key, msg=data, digestmod=hashlib.sha256).digest() class ElfError(Exception): - def __init__(self, msg): - self.msg = msg + def __init__(self, msg): + self.msg = msg - def __str__(self): - return repr(self.msg) + def __str__(self): + return repr(self.msg) class ElfEHdr(object): - FMT = '<4s5B6xB' - EX_FMT = '<2HI3QI6H' - - MAGIC = b'\x7FELF' - CLASS64 = 0x2 - DATA2LSB = 0x1 - EM_X86_64 = 0x3E - EV_CURRENT = 0x1 - - ET_EXEC = 0x2 - ET_SCE_EXEC = 0xFE00 - ET_SCE_EXEC_ASLR = 0xFE10 - ET_SCE_DYNAMIC = 0xFE18 - - def __init__(self): - self.magic = None - self.machine_class = None - self.data_encoding = None - self.version = None - self.os_abi = None - self.abi_version = None - self.nident_size = None - self.type = None - self.machine = None - self.version = None - self.entry = None - self.phoff = None - self.shoff = None - self.flags = None - self.ehsize = None - self.phentsize = None - self.phnum = None - self.shentsize = None - self.shnum = None - self.shstridx = None - - def load(self, f): - if not check_file_magic(f, ElfEHdr.MAGIC): - raise ElfError('Invalid magic.') - - self.magic, self.machine_class, self.data_encoding, self.version, self.os_abi, self.abi_version, self.nident_size = struct.unpack(ElfEHdr.FMT, f.read(struct.calcsize(ElfEHdr.FMT))) - if self.machine_class != ElfEHdr.CLASS64 or self.data_encoding != ElfEHdr.DATA2LSB: - raise ElfError('Unsupported class or data encoding.') - self.type, self.machine, self.version, self.entry, self.phoff, self.shoff, self.flags, self.ehsize, self.phentsize, self.phnum, self.shentsize, self.shnum, self.shstridx = struct.unpack(ElfEHdr.EX_FMT, f.read(struct.calcsize(ElfEHdr.EX_FMT))) - if self.machine != ElfEHdr.EM_X86_64 or self.version != ElfEHdr.EV_CURRENT: - raise ElfError('Unsupported machine type or version.') - if self.phentsize != struct.calcsize(ElfPHdr.FMT) or (self.shentsize > 0 and self.shentsize != struct.calcsize(ElfSHdr.FMT)): - raise ElfError('Unsupported header entry size.') - if self.type not in [ElfEHdr.ET_EXEC, ElfEHdr.ET_SCE_EXEC, ElfEHdr.ET_SCE_EXEC_ASLR, ElfEHdr.ET_SCE_DYNAMIC]: - raise ElfError('Unsupported type.') - - def save(self, f): - f.write(struct.pack(ElfEHdr.FMT, self.magic, self.machine_class, self.data_encoding, self.version, self.os_abi, self.abi_version, self.nident_size)) - f.write(struct.pack(ElfEHdr.EX_FMT, self.type, self.machine, self.version, self.entry, self.phoff, self.shoff, self.flags, self.ehsize, self.phentsize, self.phnum, self.shentsize, self.shnum, self.shstridx)) - - def has_segments(self): - return self.phentsize > 0 and self.phnum > 0 - - def has_sections(self): - return self.shentsize > 0 and self.shnum > 0 + FMT = '<4s5B6xB' + EX_FMT = '<2HI3QI6H' + + MAGIC = b'\x7FELF' + CLASS64 = 0x2 + DATA2LSB = 0x1 + EM_X86_64 = 0x3E + EV_CURRENT = 0x1 + + ET_EXEC = 0x2 + ET_SCE_EXEC = 0xFE00 + ET_SCE_EXEC_ASLR = 0xFE10 + ET_SCE_DYNAMIC = 0xFE18 + + def __init__(self): + self.magic = None + self.machine_class = None + self.data_encoding = None + self.version = None + self.os_abi = None + self.abi_version = None + self.nident_size = None + self.type = None + self.machine = None + self.version = None + self.entry = None + self.phoff = None + self.shoff = None + self.flags = None + self.ehsize = None + self.phentsize = None + self.phnum = None + self.shentsize = None + self.shnum = None + self.shstridx = None + + def load(self, f): + if not check_file_magic(f, ElfEHdr.MAGIC): + raise ElfError('Invalid magic.') + + self.magic, self.machine_class, self.data_encoding, self.version, self.os_abi, self.abi_version, self.nident_size = struct.unpack(ElfEHdr.FMT, f.read(struct.calcsize(ElfEHdr.FMT))) + if self.machine_class != ElfEHdr.CLASS64 or self.data_encoding != ElfEHdr.DATA2LSB: + raise ElfError('Unsupported class or data encoding.') + self.type, self.machine, self.version, self.entry, self.phoff, self.shoff, self.flags, self.ehsize, self.phentsize, self.phnum, self.shentsize, self.shnum, self.shstridx = struct.unpack(ElfEHdr.EX_FMT, f.read(struct.calcsize(ElfEHdr.EX_FMT))) + if self.machine != ElfEHdr.EM_X86_64 or self.version != ElfEHdr.EV_CURRENT: + raise ElfError('Unsupported machine type or version.') + if self.phentsize != struct.calcsize(ElfPHdr.FMT) or (self.shentsize > 0 and self.shentsize != struct.calcsize(ElfSHdr.FMT)): + raise ElfError('Unsupported header entry size.') + if self.type not in [ElfEHdr.ET_EXEC, ElfEHdr.ET_SCE_EXEC, ElfEHdr.ET_SCE_EXEC_ASLR, ElfEHdr.ET_SCE_DYNAMIC]: + raise ElfError('Unsupported type.') + + def save(self, f): + f.write(struct.pack(ElfEHdr.FMT, self.magic, self.machine_class, self.data_encoding, self.version, self.os_abi, self.abi_version, self.nident_size)) + f.write(struct.pack(ElfEHdr.EX_FMT, self.type, self.machine, self.version, self.entry, self.phoff, self.shoff, self.flags, self.ehsize, self.phentsize, self.phnum, self.shentsize, self.shnum, self.shstridx)) + + def has_segments(self): + return self.phentsize > 0 and self.phnum > 0 + + def has_sections(self): + return self.shentsize > 0 and self.shnum > 0 class ElfPHdr(object): - FMT = '<2I6Q' - - PT_LOAD = 0x1 - PT_DYNAMIC = 0x2 - PT_INTERP = 0x3 - PT_TLS = 0x7 - PT_GNU_EH_FRAME = 0x6474E550 - PT_GNU_STACK = 0x6474E551 - PT_SCE_RELA = 0x60000000, - PT_SCE_DYNLIBDATA = 0x61000000 - PT_SCE_PROCPARAM = 0x61000001 - PT_SCE_MODULE_PARAM = 0x61000002 - PT_SCE_RELRO = 0x61000010 - PT_SCE_COMMENT = 0x6FFFFF00 - PT_SCE_VERSION = 0x6FFFFF01 - - PF_EXEC = 0x1 - PF_WRITE = 0x2 - PF_READ = 0x4 - PF_READ_EXEC = PF_READ | PF_EXEC - PF_READ_WRITE = PF_READ | PF_WRITE - - def __init__(self, idx): - self.idx = idx - self.type = None - self.flags = None - self.offset = None - self.vaddr = None - self.paddr = None - self.filesz = None - self.memsz = None - self.align = None - - def load(self, f): - self.type, self.flags, self.offset, self.vaddr, self.paddr, self.filesz, self.memsz, self.align = struct.unpack(ElfPHdr.FMT, f.read(struct.calcsize(ElfPHdr.FMT))) - - def save(self, f): - f.write(struct.pack(ElfPHdr.FMT, self.type, self.flags, self.offset, self.vaddr, self.paddr, self.filesz, self.memsz, self.align)) - - def name(self): - if self.type == ElfPHdr.PT_LOAD: - if (self.flags & ElfPHdr.PF_READ_EXEC) == ElfPHdr.PF_READ_EXEC: - return '.text' - elif (self.flags & ElfPHdr.PF_READ_WRITE) == ElfPHdr.PF_READ_WRITE: - return '.data' - else: - return '.load_{0:02}'.format(self.idx) - else: - return { - ElfPHdr.PT_DYNAMIC: '.dynamic', - ElfPHdr.PT_INTERP: '.interp', - ElfPHdr.PT_TLS: '.tls', - ElfPHdr.PT_GNU_EH_FRAME: '.eh_frame_hdr', - ElfPHdr.PT_SCE_DYNLIBDATA: '.sce_dynlib_data', - ElfPHdr.PT_SCE_PROCPARAM: '.sce_process_param', - ElfPHdr.PT_SCE_MODULE_PARAM: '.sce_module_param', - ElfPHdr.PT_SCE_COMMENT: '.sce_comment', - }.get(self.type, None) - - def class_name(self): - if (self.flags & ElfPHdr.PF_READ_EXEC) == ElfPHdr.PF_READ_EXEC: - return 'CODE' - else: - return 'DATA' + FMT = '<2I6Q' + + PT_LOAD = 0x1 + PT_DYNAMIC = 0x2 + PT_INTERP = 0x3 + PT_TLS = 0x7 + PT_GNU_EH_FRAME = 0x6474E550 + PT_GNU_STACK = 0x6474E551 + PT_SCE_RELA = 0x60000000, + PT_SCE_DYNLIBDATA = 0x61000000 + PT_SCE_PROCPARAM = 0x61000001 + PT_SCE_MODULE_PARAM = 0x61000002 + PT_SCE_RELRO = 0x61000010 + PT_SCE_COMMENT = 0x6FFFFF00 + PT_SCE_VERSION = 0x6FFFFF01 + + PF_EXEC = 0x1 + PF_WRITE = 0x2 + PF_READ = 0x4 + PF_READ_EXEC = PF_READ | PF_EXEC + PF_READ_WRITE = PF_READ | PF_WRITE + + def __init__(self, idx): + self.idx = idx + self.type = None + self.flags = None + self.offset = None + self.vaddr = None + self.paddr = None + self.filesz = None + self.memsz = None + self.align = None + + def load(self, f): + self.type, self.flags, self.offset, self.vaddr, self.paddr, self.filesz, self.memsz, self.align = struct.unpack(ElfPHdr.FMT, f.read(struct.calcsize(ElfPHdr.FMT))) + + def save(self, f): + f.write(struct.pack(ElfPHdr.FMT, self.type, self.flags, self.offset, self.vaddr, self.paddr, self.filesz, self.memsz, self.align)) + + def name(self): + if self.type == ElfPHdr.PT_LOAD: + if (self.flags & ElfPHdr.PF_READ_EXEC) == ElfPHdr.PF_READ_EXEC: + return '.text' + elif (self.flags & ElfPHdr.PF_READ_WRITE) == ElfPHdr.PF_READ_WRITE: + return '.data' + else: + return '.load_{0:02}'.format(self.idx) + else: + return { + ElfPHdr.PT_DYNAMIC: '.dynamic', + ElfPHdr.PT_INTERP: '.interp', + ElfPHdr.PT_TLS: '.tls', + ElfPHdr.PT_GNU_EH_FRAME: '.eh_frame_hdr', + ElfPHdr.PT_SCE_DYNLIBDATA: '.sce_dynlib_data', + ElfPHdr.PT_SCE_PROCPARAM: '.sce_process_param', + ElfPHdr.PT_SCE_MODULE_PARAM: '.sce_module_param', + ElfPHdr.PT_SCE_COMMENT: '.sce_comment', + }.get(self.type, None) + + def class_name(self): + if (self.flags & ElfPHdr.PF_READ_EXEC) == ElfPHdr.PF_READ_EXEC: + return 'CODE' + else: + return 'DATA' class ElfSHdr(object): - FMT = '<2I4Q2I2Q' - - def __init__(self, idx): - self.idx = idx - self.name = None - self.type = None - self.flags = None - self.addr = None - self.offset = None - self.size = None - self.link = None - self.info = None - self.align = None - self.entsize = None - - def load(self, f): - self.name, self.type, self.flags, self.addr, self.offset, self.size, self.link, self.info, self.align, self.entsize = struct.unpack(ElfSHdr.FMT, f.read(struct.calcsize(ElfSHdr.FMT))) - - def save(self, f): - f.write(struct.pack(ElfSHdr.FMT, self.name, self.type, self.flags, self.addr, self.offset, self.size, self.link, self.info, self.align, self.entsize)) + FMT = '<2I4Q2I2Q' + + def __init__(self, idx): + self.idx = idx + self.name = None + self.type = None + self.flags = None + self.addr = None + self.offset = None + self.size = None + self.link = None + self.info = None + self.align = None + self.entsize = None + + def load(self, f): + self.name, self.type, self.flags, self.addr, self.offset, self.size, self.link, self.info, self.align, self.entsize = struct.unpack(ElfSHdr.FMT, f.read(struct.calcsize(ElfSHdr.FMT))) + + def save(self, f): + f.write(struct.pack(ElfSHdr.FMT, self.name, self.type, self.flags, self.addr, self.offset, self.size, self.link, self.info, self.align, self.entsize)) class ElfFile(object): - def __init__(self, **kwargs): - self.ehdr = None - self.phdrs = None - self.shdrs = None - self.file_size = None - self.digest = None - self.segments = None - self.sections = None - self.ignore_shdrs = 'ignore_shdrs' in kwargs and kwargs['ignore_shdrs'] - - def load(self, f): - start_offset = f.tell() - data = f.read() - self.file_size = len(data) - self.digest = sha256(data) - f.seek(start_offset) - - self.ehdr = ElfEHdr() - self.ehdr.load(f) - - if self.ignore_shdrs: - self.ehdr.shnum = 0 - - self.phdrs = [] - self.segments = [] - if self.ehdr.has_segments(): - for i in range(self.ehdr.phnum): - f.seek(start_offset + self.ehdr.phoff + i * self.ehdr.phentsize) - phdr = ElfPHdr(i) - phdr.load(f) - self.phdrs.append(phdr) - if phdr.filesz > 0: - f.seek(start_offset + phdr.offset) - data = f.read(phdr.filesz) - else: - data = b'' - self.segments.append(data) - - self.shdrs = [] - self.sections = [] - if self.ehdr.has_sections(): - for i in range(self.ehdr.shnum): - f.seek(start_offset + self.ehdr.shoff + i * self.ehdr.shentsize) - shdr = ElfSHdr(i) - shdr.load(f) - self.shdrs.append(shdr) - if phdr.filesz > 0: - f.seek(start_offset + shdr.offset) - data = f.read(phdr.filesz) - else: - data = b'' - self.sections.append(data) - - def save(self, f, no_sections=False): - start_offset = f.tell() - - self.ehdr.save(f) - - if not no_sections: - if self.ehdr.has_sections(): - for i in range(self.ehdr.shnum): - f.seek(start_offset + self.ehdr.shoff + i * self.ehdr.shentsize) - shdr = self.shdrs[i] - shdr.save(f) - - if self.ehdr.has_segments(): - for i in range(self.ehdr.phnum): - f.seek(start_offset + self.ehdr.phoff + i * self.ehdr.phentsize) - phdr = self.phdrs[i] - phdr.save(f) + def __init__(self, **kwargs): + self.ehdr = None + self.phdrs = None + self.shdrs = None + self.file_size = None + self.digest = None + self.segments = None + self.sections = None + self.ignore_shdrs = 'ignore_shdrs' in kwargs and kwargs['ignore_shdrs'] + + def load(self, f): + start_offset = f.tell() + data = f.read() + self.file_size = len(data) + self.digest = sha256(data) + f.seek(start_offset) + + self.ehdr = ElfEHdr() + self.ehdr.load(f) + + if self.ignore_shdrs: + self.ehdr.shnum = 0 + + self.phdrs = [] + self.segments = [] + if self.ehdr.has_segments(): + for i in range(self.ehdr.phnum): + f.seek(start_offset + self.ehdr.phoff + i * self.ehdr.phentsize) + phdr = ElfPHdr(i) + phdr.load(f) + self.phdrs.append(phdr) + if phdr.filesz > 0: + f.seek(start_offset + phdr.offset) + data = f.read(phdr.filesz) + else: + data = b'' + self.segments.append(data) + + self.shdrs = [] + self.sections = [] + if self.ehdr.has_sections(): + for i in range(self.ehdr.shnum): + f.seek(start_offset + self.ehdr.shoff + i * self.ehdr.shentsize) + shdr = ElfSHdr(i) + shdr.load(f) + self.shdrs.append(shdr) + if phdr.filesz > 0: + f.seek(start_offset + shdr.offset) + data = f.read(phdr.filesz) + else: + data = b'' + self.sections.append(data) + + def save(self, f, no_sections=False): + start_offset = f.tell() + + self.ehdr.save(f) + + if not no_sections: + if self.ehdr.has_sections(): + for i in range(self.ehdr.shnum): + f.seek(start_offset + self.ehdr.shoff + i * self.ehdr.shentsize) + shdr = self.shdrs[i] + shdr.save(f) + + if self.ehdr.has_segments(): + for i in range(self.ehdr.phnum): + f.seek(start_offset + self.ehdr.phoff + i * self.ehdr.phentsize) + phdr = self.phdrs[i] + phdr.save(f) DIGEST_SIZE = 0x20 SIGNATURE_SIZE = 0x100 @@ -291,463 +291,463 @@ def save(self, f, no_sections=False): EMPTY_SIGNATURE = b'\0' * SIGNATURE_SIZE class SignedElfEntry(object): - FMT = '<4Q' - - PROPS_ORDER_SHIFT = 0 - PROPS_ORDER_MASK = 0x1 - PROPS_ENCRYPTED_SHIFT = 1 - PROPS_ENCRYPTED_MASK = 0x1 - PROPS_SIGNED_SHIFT = 2 - PROPS_SIGNED_MASK = 0x1 - PROPS_COMPRESSED_SHIFT = 3 - PROPS_COMPRESSED_MASK = 0x1 - PROPS_WINDOW_BITS_SHIFT = 8 - PROPS_WINDOW_BITS_MASK = 0x7 - PROPS_HAS_BLOCKS_SHIFT = 11 - PROPS_HAS_BLOCKS_MASK = 0x1 - PROPS_BLOCK_SIZE_SHIFT = 12 - PROPS_BLOCK_SIZE_MASK = 0xF - PROPS_HAS_DIGESTS_SHIFT = 16 - PROPS_HAS_DIGESTS_MASK = 0x1 - PROPS_HAS_EXTENTS_SHIFT = 17 - PROPS_HAS_EXTENTS_MASK = 0x1 - PROPS_HAS_META_SEGMENT_SHIFT = 20 - PROPS_HAS_META_SEGMENT_MASK = 0x1 - PROPS_SEGMENT_INDEX_SHIFT = 20 - PROPS_SEGMENT_INDEX_MASK = 0xFFFF - PROPS_DEFAULT_BLOCK_SIZE = 0x1000 - PROPS_META_SEGMENT_MASK = 0xF0000 - - def __init__(self, index): - self.index = index - - self.props = None - self.offset = None - self.filesz = None - self.memsz = None - - self.data = None - - def save(self, f): - f.write(struct.pack(SignedElfEntry.FMT, self.props, self.offset, self.filesz, self.memsz)) - - @property - def order(self): - return (self.props >> SignedElfEntry.PROPS_ORDER_SHIFT) & SignedElfEntry.PROPS_ORDER_MASK - - @order.setter - def order(self, value): - self.props &= ~(SignedElfEntry.PROPS_ORDER_MASK << SignedElfEntry.PROPS_ORDER_SHIFT) - self.props |= (value & SignedElfEntry.PROPS_ORDER_MASK) << SignedElfEntry.PROPS_ORDER_SHIFT - - @property - def encrypted(self): - return ((self.props >> SignedElfEntry.PROPS_ENCRYPTED_SHIFT) & SignedElfEntry.PROPS_ENCRYPTED_MASK) != 0 - - @encrypted.setter - def encrypted(self, value): - self.props &= ~(SignedElfEntry.PROPS_ENCRYPTED_MASK << SignedElfEntry.PROPS_ENCRYPTED_SHIFT) - if value: - self.props |= SignedElfEntry.PROPS_ENCRYPTED_MASK << SignedElfEntry.PROPS_ENCRYPTED_SHIFT - - @property - def signed(self): - return ((self.props >> SignedElfEntry.PROPS_SIGNED_SHIFT) & SignedElfEntry.PROPS_SIGNED_MASK) != 0 - - @signed.setter - def signed(self, value): - self.props &= ~(SignedElfEntry.PROPS_SIGNED_MASK << SignedElfEntry.PROPS_SIGNED_SHIFT) - if value: - self.props |= SignedElfEntry.PROPS_SIGNED_MASK << SignedElfEntry.PROPS_SIGNED_SHIFT - - @property - def compressed(self): - return ((self.props >> SignedElfEntry.PROPS_COMPRESSED_SHIFT) & SignedElfEntry.PROPS_COMPRESSED_MASK) != 0 - - @compressed.setter - def compressed(self, value): - self.props &= ~(SignedElfEntry.PROPS_COMPRESSED_MASK << SignedElfEntry.PROPS_COMPRESSED_SHIFT) - if value: - self.props |= SignedElfEntry.PROPS_COMPRESSED_MASK << SignedElfEntry.PROPS_COMPRESSED_SHIFT - - @property - def has_blocks(self): - return ((self.props >> SignedElfEntry.PROPS_HAS_BLOCKS_SHIFT) & SignedElfEntry.PROPS_HAS_BLOCKS_MASK) != 0 - - @has_blocks.setter - def has_blocks(self, value): - self.props &= ~(SignedElfEntry.PROPS_HAS_BLOCKS_MASK << SignedElfEntry.PROPS_HAS_BLOCKS_SHIFT) - if value: - self.props |= SignedElfEntry.PROPS_HAS_BLOCKS_MASK << SignedElfEntry.PROPS_HAS_BLOCKS_SHIFT - - @property - def has_digests(self): - return ((self.props >> SignedElfEntry.PROPS_HAS_DIGESTS_SHIFT) & SignedElfEntry.PROPS_HAS_DIGESTS_MASK) != 0 - - @has_digests.setter - def has_digests(self, value): - self.props &= ~(SignedElfEntry.PROPS_HAS_DIGESTS_MASK << SignedElfEntry.PROPS_HAS_DIGESTS_SHIFT) - if value: - self.props |= SignedElfEntry.PROPS_HAS_DIGESTS_MASK << SignedElfEntry.PROPS_HAS_DIGESTS_SHIFT - - @property - def has_extents(self): - return ((self.props >> SignedElfEntry.PROPS_HAS_EXTENTS_SHIFT) & SignedElfEntry.PROPS_HAS_EXTENTS_MASK) != 0 - - @has_extents.setter - def has_extents(self, value): - self.props &= ~(SignedElfEntry.PROPS_HAS_EXTENTS_MASK << SignedElfEntry.PROPS_HAS_EXTENTS_SHIFT) - if value: - self.props |= SignedElfEntry.PROPS_HAS_EXTENTS_MASK << SignedElfEntry.PROPS_HAS_EXTENTS_SHIFT - - @property - def has_meta_segment(self): - return ((self.props >> SignedElfEntry.PROPS_HAS_META_SEGMENT_SHIFT) & SignedElfEntry.PROPS_HAS_META_SEGMENT_MASK) != 0 - - @has_meta_segment.setter - def has_meta_segment(self, value): - self.props &= ~(SignedElfEntry.PROPS_HAS_META_SEGMENT_MASK << SignedElfEntry.PROPS_HAS_META_SEGMENT_SHIFT) - if value: - self.props |= SignedElfEntry.PROPS_HAS_META_SEGMENT_MASK << SignedElfEntry.PROPS_HAS_META_SEGMENT_SHIFT - - @property - def wbits(self): - return (self.props >> SignedElfEntry.PROPS_WINDOW_BITS_SHIFT) & SignedElfEntry.PROPS_WINDOW_BITS_MASK - - @wbits.setter - def wbits(self, value): - self.props &= ~(SignedElfEntry.PROPS_WINDOW_BITS_MASK << SignedElfEntry.PROPS_WINDOW_BITS_SHIFT) - self.props |= (value & SignedElfEntry.PROPS_WINDOW_BITS_MASK) << SignedElfEntry.PROPS_WINDOW_BITS_SHIFT - - @property - def block_size(self): - if self.has_blocks: - return 1 << (12 + (self.props >> SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT) & SignedElfEntry.PROPS_BLOCK_SIZE_MASK) - else: - return DEFAULT_BLOCK_SIZE - - @block_size.setter - def block_size(self, value): - self.props &= ~(SignedElfEntry.PROPS_BLOCK_SIZE_MASK << SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT) - if self.has_blocks: - value = ilog2(value) - 12 - else: - value = 0 # TODO: check - self.props |= (value & SignedElfEntry.PROPS_BLOCK_SIZE_MASK) << SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT - - @property - def segment_index(self): - return (self.props >> SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT) & SignedElfEntry.PROPS_SEGMENT_INDEX_MASK - - @wbits.setter - def segment_index(self, value): - self.props &= ~(SignedElfEntry.PROPS_SEGMENT_INDEX_MASK << SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT) - self.props |= (value & SignedElfEntry.PROPS_SEGMENT_INDEX_MASK) << SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT - - def is_meta_segment(self): # TODO: check - return (self.props & SignedElfEntry.PROPS_META_SEGMENT_MASK) != 0 - - def __repr__(self): - return 'prs:0x{0:X} ofs:0x{1:X} fsz:0x{2:X} msz:0x{3:X}'.format(self.props, self.offset, self.filesz, self.memsz) + FMT = '<4Q' + + PROPS_ORDER_SHIFT = 0 + PROPS_ORDER_MASK = 0x1 + PROPS_ENCRYPTED_SHIFT = 1 + PROPS_ENCRYPTED_MASK = 0x1 + PROPS_SIGNED_SHIFT = 2 + PROPS_SIGNED_MASK = 0x1 + PROPS_COMPRESSED_SHIFT = 3 + PROPS_COMPRESSED_MASK = 0x1 + PROPS_WINDOW_BITS_SHIFT = 8 + PROPS_WINDOW_BITS_MASK = 0x7 + PROPS_HAS_BLOCKS_SHIFT = 11 + PROPS_HAS_BLOCKS_MASK = 0x1 + PROPS_BLOCK_SIZE_SHIFT = 12 + PROPS_BLOCK_SIZE_MASK = 0xF + PROPS_HAS_DIGESTS_SHIFT = 16 + PROPS_HAS_DIGESTS_MASK = 0x1 + PROPS_HAS_EXTENTS_SHIFT = 17 + PROPS_HAS_EXTENTS_MASK = 0x1 + PROPS_HAS_META_SEGMENT_SHIFT = 20 + PROPS_HAS_META_SEGMENT_MASK = 0x1 + PROPS_SEGMENT_INDEX_SHIFT = 20 + PROPS_SEGMENT_INDEX_MASK = 0xFFFF + PROPS_DEFAULT_BLOCK_SIZE = 0x1000 + PROPS_META_SEGMENT_MASK = 0xF0000 + + def __init__(self, index): + self.index = index + + self.props = None + self.offset = None + self.filesz = None + self.memsz = None + + self.data = None + + def save(self, f): + f.write(struct.pack(SignedElfEntry.FMT, self.props, self.offset, self.filesz, self.memsz)) + + @property + def order(self): + return (self.props >> SignedElfEntry.PROPS_ORDER_SHIFT) & SignedElfEntry.PROPS_ORDER_MASK + + @order.setter + def order(self, value): + self.props &= ~(SignedElfEntry.PROPS_ORDER_MASK << SignedElfEntry.PROPS_ORDER_SHIFT) + self.props |= (value & SignedElfEntry.PROPS_ORDER_MASK) << SignedElfEntry.PROPS_ORDER_SHIFT + + @property + def encrypted(self): + return ((self.props >> SignedElfEntry.PROPS_ENCRYPTED_SHIFT) & SignedElfEntry.PROPS_ENCRYPTED_MASK) != 0 + + @encrypted.setter + def encrypted(self, value): + self.props &= ~(SignedElfEntry.PROPS_ENCRYPTED_MASK << SignedElfEntry.PROPS_ENCRYPTED_SHIFT) + if value: + self.props |= SignedElfEntry.PROPS_ENCRYPTED_MASK << SignedElfEntry.PROPS_ENCRYPTED_SHIFT + + @property + def signed(self): + return ((self.props >> SignedElfEntry.PROPS_SIGNED_SHIFT) & SignedElfEntry.PROPS_SIGNED_MASK) != 0 + + @signed.setter + def signed(self, value): + self.props &= ~(SignedElfEntry.PROPS_SIGNED_MASK << SignedElfEntry.PROPS_SIGNED_SHIFT) + if value: + self.props |= SignedElfEntry.PROPS_SIGNED_MASK << SignedElfEntry.PROPS_SIGNED_SHIFT + + @property + def compressed(self): + return ((self.props >> SignedElfEntry.PROPS_COMPRESSED_SHIFT) & SignedElfEntry.PROPS_COMPRESSED_MASK) != 0 + + @compressed.setter + def compressed(self, value): + self.props &= ~(SignedElfEntry.PROPS_COMPRESSED_MASK << SignedElfEntry.PROPS_COMPRESSED_SHIFT) + if value: + self.props |= SignedElfEntry.PROPS_COMPRESSED_MASK << SignedElfEntry.PROPS_COMPRESSED_SHIFT + + @property + def has_blocks(self): + return ((self.props >> SignedElfEntry.PROPS_HAS_BLOCKS_SHIFT) & SignedElfEntry.PROPS_HAS_BLOCKS_MASK) != 0 + + @has_blocks.setter + def has_blocks(self, value): + self.props &= ~(SignedElfEntry.PROPS_HAS_BLOCKS_MASK << SignedElfEntry.PROPS_HAS_BLOCKS_SHIFT) + if value: + self.props |= SignedElfEntry.PROPS_HAS_BLOCKS_MASK << SignedElfEntry.PROPS_HAS_BLOCKS_SHIFT + + @property + def has_digests(self): + return ((self.props >> SignedElfEntry.PROPS_HAS_DIGESTS_SHIFT) & SignedElfEntry.PROPS_HAS_DIGESTS_MASK) != 0 + + @has_digests.setter + def has_digests(self, value): + self.props &= ~(SignedElfEntry.PROPS_HAS_DIGESTS_MASK << SignedElfEntry.PROPS_HAS_DIGESTS_SHIFT) + if value: + self.props |= SignedElfEntry.PROPS_HAS_DIGESTS_MASK << SignedElfEntry.PROPS_HAS_DIGESTS_SHIFT + + @property + def has_extents(self): + return ((self.props >> SignedElfEntry.PROPS_HAS_EXTENTS_SHIFT) & SignedElfEntry.PROPS_HAS_EXTENTS_MASK) != 0 + + @has_extents.setter + def has_extents(self, value): + self.props &= ~(SignedElfEntry.PROPS_HAS_EXTENTS_MASK << SignedElfEntry.PROPS_HAS_EXTENTS_SHIFT) + if value: + self.props |= SignedElfEntry.PROPS_HAS_EXTENTS_MASK << SignedElfEntry.PROPS_HAS_EXTENTS_SHIFT + + @property + def has_meta_segment(self): + return ((self.props >> SignedElfEntry.PROPS_HAS_META_SEGMENT_SHIFT) & SignedElfEntry.PROPS_HAS_META_SEGMENT_MASK) != 0 + + @has_meta_segment.setter + def has_meta_segment(self, value): + self.props &= ~(SignedElfEntry.PROPS_HAS_META_SEGMENT_MASK << SignedElfEntry.PROPS_HAS_META_SEGMENT_SHIFT) + if value: + self.props |= SignedElfEntry.PROPS_HAS_META_SEGMENT_MASK << SignedElfEntry.PROPS_HAS_META_SEGMENT_SHIFT + + @property + def wbits(self): + return (self.props >> SignedElfEntry.PROPS_WINDOW_BITS_SHIFT) & SignedElfEntry.PROPS_WINDOW_BITS_MASK + + @wbits.setter + def wbits(self, value): + self.props &= ~(SignedElfEntry.PROPS_WINDOW_BITS_MASK << SignedElfEntry.PROPS_WINDOW_BITS_SHIFT) + self.props |= (value & SignedElfEntry.PROPS_WINDOW_BITS_MASK) << SignedElfEntry.PROPS_WINDOW_BITS_SHIFT + + @property + def block_size(self): + if self.has_blocks: + return 1 << (12 + (self.props >> SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT) & SignedElfEntry.PROPS_BLOCK_SIZE_MASK) + else: + return DEFAULT_BLOCK_SIZE + + @block_size.setter + def block_size(self, value): + self.props &= ~(SignedElfEntry.PROPS_BLOCK_SIZE_MASK << SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT) + if self.has_blocks: + value = ilog2(value) - 12 + else: + value = 0 # TODO: check + self.props |= (value & SignedElfEntry.PROPS_BLOCK_SIZE_MASK) << SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT + + @property + def segment_index(self): + return (self.props >> SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT) & SignedElfEntry.PROPS_SEGMENT_INDEX_MASK + + @wbits.setter + def segment_index(self, value): + self.props &= ~(SignedElfEntry.PROPS_SEGMENT_INDEX_MASK << SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT) + self.props |= (value & SignedElfEntry.PROPS_SEGMENT_INDEX_MASK) << SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT + + def is_meta_segment(self): # TODO: check + return (self.props & SignedElfEntry.PROPS_META_SEGMENT_MASK) != 0 + + def __repr__(self): + return 'prs:0x{0:X} ofs:0x{1:X} fsz:0x{2:X} msz:0x{3:X}'.format(self.props, self.offset, self.filesz, self.memsz) class SignedElfExInfo(object): - FMT = '<4Q32s' - - PTYPE_FAKE = 0x1 - PTYPE_NPDRM_EXEC = 0x4 - PTYPE_NPDRM_DYNLIB = 0x5 - PTYPE_SYSTEM_EXEC = 0x8 - PTYPE_SYSTEM_DYNLIB = 0x9 # including Mono binaries - PTYPE_HOST_KERNEL = 0xC - PTYPE_SECURE_MODULE = 0xE - PTYPE_SECURE_KERNEL = 0xF - - def __init__(self): - self.paid = None - self.ptype = None - self.app_version = None - self.fw_version = None - self.digest = None - - def save(self, f): - f.write(struct.pack(SignedElfExInfo.FMT, self.paid, self.ptype, self.app_version, self.fw_version, self.digest)) + FMT = '<4Q32s' + + PTYPE_FAKE = 0x1 + PTYPE_NPDRM_EXEC = 0x4 + PTYPE_NPDRM_DYNLIB = 0x5 + PTYPE_SYSTEM_EXEC = 0x8 + PTYPE_SYSTEM_DYNLIB = 0x9 # including Mono binaries + PTYPE_HOST_KERNEL = 0xC + PTYPE_SECURE_MODULE = 0xE + PTYPE_SECURE_KERNEL = 0xF + + def __init__(self): + self.paid = None + self.ptype = None + self.app_version = None + self.fw_version = None + self.digest = None + + def save(self, f): + f.write(struct.pack(SignedElfExInfo.FMT, self.paid, self.ptype, self.app_version, self.fw_version, self.digest)) class SignedElfNpdrmControlBlock(object): - FMT = ' 0: - if val.startswith('0x') or val.startswith('0X'): - val = val[2:] - if len(val) % 2 != 0 or not all(x in string.hexdigits for x in val): - return None - val = bytes.fromhex(val) - val_size = len(val) - - if not exact_size is None and val_size != exact_size: - return None - else: - if not min_size is None and val_size < min_size: - return None - if not max_size is None and val_size > max_size: - return None - - return val + exact_size = int(kwargs['exact_size']) if 'exact_size' in kwargs else None + min_size = int(kwargs['min_size']) if 'min_size' in kwargs else None + max_size = int(kwargs['max_size']) if 'max_size' in kwargs else None + + val = re.sub(r'\s+', '', val) + val_size = len(val) + if val_size > 0: + if val.startswith('0x') or val.startswith('0X'): + val = val[2:] + if len(val) % 2 != 0 or not all(x in string.hexdigits for x in val): + return None + val = bytes.fromhex(val) + val_size = len(val) + + if not exact_size is None and val_size != exact_size: + return None + else: + if not min_size is None and val_size < min_size: + return None + if not max_size is None and val_size > max_size: + return None + + return val def input_file_type(val): - if not os.access(val, os.F_OK | os.R_OK) or not os.path.isfile(val): - raise argparse.ArgumentTypeError('invalid input file: {0}'.format(val)) - return val + if not os.access(val, os.F_OK | os.R_OK) or not os.path.isfile(val): + raise argparse.ArgumentTypeError('invalid input file: {0}'.format(val)) + return val def output_file_type(val): - if os.access(val, os.F_OK) and (not os.path.isfile(val) or not os.access(val, os.F_OK | os.W_OK)): - raise argparse.ArgumentTypeError('invalid output file: {0}'.format(val)) - return val + if os.access(val, os.F_OK) and (not os.path.isfile(val) or not os.access(val, os.F_OK | os.W_OK)): + raise argparse.ArgumentTypeError('invalid output file: {0}'.format(val)) + return val def auth_info_type(val): - new_val = ensure_hex_string(val, exact_size=0x88) - if new_val is None: - raise argparse.ArgumentTypeError('invalid auth info: {0}'.format(val)) - return new_val + new_val = ensure_hex_string(val, exact_size=0x88) + if new_val is None: + raise argparse.ArgumentTypeError('invalid auth info: {0}'.format(val)) + return new_val class MyParser(argparse.ArgumentParser): - def error(self, message): - self.print_help() - sys.stderr.write('\nerror: {0}\n'.format(message)) - sys.exit(2) + def error(self, message): + self.print_help() + sys.stderr.write('\nerror: {0}\n'.format(message)) + sys.exit(2) if __name__ == '__main__': parser = MyParser(description='fake signed elf maker') From 6f8359b195efcce2f736a91b725e57e7b9cddefc Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 17 Oct 2026 02:12:54 -0400 Subject: [PATCH 02/12] Removed dead code. --- samples/install_app/make_fself.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/samples/install_app/make_fself.py b/samples/install_app/make_fself.py index 9adb3066..c3085cd3 100755 --- a/samples/install_app/make_fself.py +++ b/samples/install_app/make_fself.py @@ -16,17 +16,11 @@ def try_parse_int(x, base=0): def align_up(x, alignment): return (x + (alignment - 1)) & ~(alignment - 1) -def align_down(x, alignment): - return x & ~(alignment - 1) - def ilog2(x): if x <= 0: raise ValueError('math domain error') return len(bin(x)) - 3 -def is_intervals_overlap(p1, p2): - return p1[0] <= p2[1] and p1[1] <= p2[0] - def check_file_magic(f, expected_magic): old_offset = f.tell() try: @@ -37,18 +31,9 @@ def check_file_magic(f, expected_magic): f.seek(old_offset) return magic == expected_magic -def parse_version(version): - major, minor, patch = (version >> 8) & 0xFF, version & 0xFF, 0 # FIXME - major = 10 * (major >> 4) + (major & 0xF) - minor = 10 * (minor >> 4) + (minor & 0xF) - return '{0:d}.{1:02d}.{2:03d}'.format(major, minor, patch) - def sha256(data): return hashlib.sha256(data).digest() -def hmac_sha256(key, data): - return hmac.new(key=key, msg=data, digestmod=hashlib.sha256).digest() - class ElfError(Exception): def __init__(self, msg): self.msg = msg From 94395e37b87f16e7ef46f9e3bd25c55f6e0a66ef Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 17 Oct 2026 02:14:11 -0400 Subject: [PATCH 03/12] ElfError to ElfException. --- samples/install_app/make_fself.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/install_app/make_fself.py b/samples/install_app/make_fself.py index c3085cd3..d0e58224 100755 --- a/samples/install_app/make_fself.py +++ b/samples/install_app/make_fself.py @@ -34,7 +34,7 @@ def check_file_magic(f, expected_magic): def sha256(data): return hashlib.sha256(data).digest() -class ElfError(Exception): +class ElfException(Exception): def __init__(self, msg): self.msg = msg @@ -80,18 +80,18 @@ def __init__(self): def load(self, f): if not check_file_magic(f, ElfEHdr.MAGIC): - raise ElfError('Invalid magic.') + raise ElfException('Invalid magic.') self.magic, self.machine_class, self.data_encoding, self.version, self.os_abi, self.abi_version, self.nident_size = struct.unpack(ElfEHdr.FMT, f.read(struct.calcsize(ElfEHdr.FMT))) if self.machine_class != ElfEHdr.CLASS64 or self.data_encoding != ElfEHdr.DATA2LSB: - raise ElfError('Unsupported class or data encoding.') + raise ElfException('Unsupported class or data encoding.') self.type, self.machine, self.version, self.entry, self.phoff, self.shoff, self.flags, self.ehsize, self.phentsize, self.phnum, self.shentsize, self.shnum, self.shstridx = struct.unpack(ElfEHdr.EX_FMT, f.read(struct.calcsize(ElfEHdr.EX_FMT))) if self.machine != ElfEHdr.EM_X86_64 or self.version != ElfEHdr.EV_CURRENT: - raise ElfError('Unsupported machine type or version.') + raise ElfException('Unsupported machine type or version.') if self.phentsize != struct.calcsize(ElfPHdr.FMT) or (self.shentsize > 0 and self.shentsize != struct.calcsize(ElfSHdr.FMT)): - raise ElfError('Unsupported header entry size.') + raise ElfException('Unsupported header entry size.') if self.type not in [ElfEHdr.ET_EXEC, ElfEHdr.ET_SCE_EXEC, ElfEHdr.ET_SCE_EXEC_ASLR, ElfEHdr.ET_SCE_DYNAMIC]: - raise ElfError('Unsupported type.') + raise ElfException('Unsupported type.') def save(self, f): f.write(struct.pack(ElfEHdr.FMT, self.magic, self.machine_class, self.data_encoding, self.version, self.os_abi, self.abi_version, self.nident_size)) From 5a2cae56685c64e13f0b4ac6b6ba8dc23cbf2b27 Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 17 Oct 2026 02:15:05 -0400 Subject: [PATCH 04/12] Catch Exception, not just anything. --- samples/install_app/make_fself.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/install_app/make_fself.py b/samples/install_app/make_fself.py index d0e58224..bdc72899 100755 --- a/samples/install_app/make_fself.py +++ b/samples/install_app/make_fself.py @@ -10,7 +10,7 @@ def int_with_base_type(val): def try_parse_int(x, base=0): try: return int(x, base) if isinstance(x, str) else int(x) - except: + except Exception: return None def align_up(x, alignment): @@ -25,7 +25,7 @@ def check_file_magic(f, expected_magic): old_offset = f.tell() try: magic = f.read(len(expected_magic)) - except: + except Exception: return False finally: f.seek(old_offset) From 46169919d861d8f7b4b7e311beac7cc4358ac596 Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 17 Oct 2026 02:15:45 -0400 Subject: [PATCH 05/12] Initialize super class. --- samples/install_app/make_fself.py | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/install_app/make_fself.py b/samples/install_app/make_fself.py index bdc72899..af1abbad 100755 --- a/samples/install_app/make_fself.py +++ b/samples/install_app/make_fself.py @@ -36,6 +36,7 @@ def sha256(data): class ElfException(Exception): def __init__(self, msg): + super().__init__(msg) self.msg = msg def __str__(self): From db0f59bc13b94a906843b454b62f325ec0cb6505 Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 17 Oct 2026 02:18:04 -0400 Subject: [PATCH 06/12] PT_SCE_RELA is a number, not a tuple. --- samples/install_app/make_fself.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/install_app/make_fself.py b/samples/install_app/make_fself.py index af1abbad..d1e21d64 100755 --- a/samples/install_app/make_fself.py +++ b/samples/install_app/make_fself.py @@ -113,7 +113,7 @@ class ElfPHdr(object): PT_TLS = 0x7 PT_GNU_EH_FRAME = 0x6474E550 PT_GNU_STACK = 0x6474E551 - PT_SCE_RELA = 0x60000000, + PT_SCE_RELA = 0x60000000 PT_SCE_DYNLIBDATA = 0x61000000 PT_SCE_PROCPARAM = 0x61000001 PT_SCE_MODULE_PARAM = 0x61000002 From 97c8c44a9a92c470ee116b74a2f55ee073cedc78 Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 17 Oct 2026 02:18:21 -0400 Subject: [PATCH 07/12] Fix a typo. --- samples/install_app/make_fself.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/install_app/make_fself.py b/samples/install_app/make_fself.py index d1e21d64..8a491e36 100755 --- a/samples/install_app/make_fself.py +++ b/samples/install_app/make_fself.py @@ -638,7 +638,7 @@ def _prepare(self): def save(self, f): start_offset = f.tell() - # calculate neccessary fields + # calculate necessary fields self._prepare() # write common header From 3b0a8143ed7f3d2014d21091ae221a1600cb4369 Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 17 Oct 2026 02:18:57 -0400 Subject: [PATCH 08/12] Do not print ptype when it is None. --- samples/install_app/make_fself.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/install_app/make_fself.py b/samples/install_app/make_fself.py index 8a491e36..3def4682 100755 --- a/samples/install_app/make_fself.py +++ b/samples/install_app/make_fself.py @@ -770,7 +770,7 @@ def error(self, message): if ptype is None: ptype = try_parse_int(args.ptype) if ptype is None: - parser.error('invalid program type: 0x{0:016X}'.format(ptype)) + parser.error('invalid program type: {0}'.format(args.ptype)) if not (0 <= ptype <= 0xFFFFFFFFFFFFFFFF): parser.error('invalid program type: 0x{0:016X}'.format(ptype)) From b552521dadaf9886fa6cf4ba906bb5e3d1683d9d Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 17 Oct 2026 02:20:35 -0400 Subject: [PATCH 09/12] Ensure val is initialized with the same type. --- samples/install_app/make_fself.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/install_app/make_fself.py b/samples/install_app/make_fself.py index 3def4682..82c49b26 100755 --- a/samples/install_app/make_fself.py +++ b/samples/install_app/make_fself.py @@ -702,6 +702,8 @@ def ensure_hex_string(val, **kwargs): return None val = bytes.fromhex(val) val_size = len(val) + else: + val = b'' if not exact_size is None and val_size != exact_size: return None From 0099608f033eda11263bae1ffa02b764043fdddf Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 17 Oct 2026 02:21:29 -0400 Subject: [PATCH 10/12] Ensure correct calculation through explicit precedence. --- samples/install_app/make_fself.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/install_app/make_fself.py b/samples/install_app/make_fself.py index 82c49b26..0387d46e 100755 --- a/samples/install_app/make_fself.py +++ b/samples/install_app/make_fself.py @@ -408,7 +408,7 @@ def wbits(self, value): @property def block_size(self): if self.has_blocks: - return 1 << (12 + (self.props >> SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT) & SignedElfEntry.PROPS_BLOCK_SIZE_MASK) + return 1 << (12 + ((self.props >> SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT) & SignedElfEntry.PROPS_BLOCK_SIZE_MASK)) else: return DEFAULT_BLOCK_SIZE From f434dfc256668febbfd53b77091b11d70ed9d880 Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 17 Oct 2026 02:22:04 -0400 Subject: [PATCH 11/12] Fix what is likely a copy/paste typo. --- samples/install_app/make_fself.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/install_app/make_fself.py b/samples/install_app/make_fself.py index 0387d46e..965f0a82 100755 --- a/samples/install_app/make_fself.py +++ b/samples/install_app/make_fself.py @@ -425,7 +425,7 @@ def block_size(self, value): def segment_index(self): return (self.props >> SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT) & SignedElfEntry.PROPS_SEGMENT_INDEX_MASK - @wbits.setter + @segment_index.setter def segment_index(self, value): self.props &= ~(SignedElfEntry.PROPS_SEGMENT_INDEX_MASK << SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT) self.props |= (value & SignedElfEntry.PROPS_SEGMENT_INDEX_MASK) << SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT From 9bea4dddc3fec274e38ee6c01245f08af16bf518 Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Sat, 17 Oct 2026 02:23:19 -0400 Subject: [PATCH 12/12] Use section size to read the section, instead of the program header size. --- samples/install_app/make_fself.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/samples/install_app/make_fself.py b/samples/install_app/make_fself.py index 965f0a82..b15f584c 100755 --- a/samples/install_app/make_fself.py +++ b/samples/install_app/make_fself.py @@ -173,6 +173,8 @@ def class_name(self): class ElfSHdr(object): FMT = '<2I4Q2I2Q' + SHT_NOBITS = 0x8 + def __init__(self, idx): self.idx = idx self.name = None @@ -239,9 +241,9 @@ def load(self, f): shdr = ElfSHdr(i) shdr.load(f) self.shdrs.append(shdr) - if phdr.filesz > 0: + if shdr.size > 0 and shdr.type != ElfSHdr.SHT_NOBITS: f.seek(start_offset + shdr.offset) - data = f.read(phdr.filesz) + data = f.read(shdr.size) else: data = b'' self.sections.append(data)