def _readProtocolRefListsAt(machO, vmaddrs): """Return the an iterable of addresses to protocols from the iterable *vmaddrs* pointing to ``old_protocol_list``\\s.""" # struct old_protocol_list { # struct old_protocol_list *next; # long count; # struct old_protocol *list[1]; # }; f = machO.file stack = list(vmaddrs) while True: newStack = [] for vmaddr in stack: machO.seek(machO.fromVM(vmaddr)) (next, count) = readStruct(f, machO.makeStruct('2^')) if next: newStack.append(next) for addr in peekPrimitives(f, '^', count, machO.endian, machO.is64bit): yield addr if not newStack: break stack = newStack
def _loadSections(self, machO): segStruct = machO.makeStruct('16s4^2i2L') sectStruct = machO.makeStruct(Section.STRUCT_FORMAT) (segname, self.vmaddr, self._vmsize, self._fileoff, self._filesize, self.maxprot, self.initprot, nsects, _) = readStruct(machO.file, segStruct) self.segname = fromStringz(segname) machO_fileOrigin = machO._fileOrigin sectVals = peekStructs(machO.file, sectStruct, count=nsects) # get all section headers sectionsList = (Section.createSection(i) for i in sectVals ) # convert all headers into Section objects sections = DataTable('className', 'sectname', 'ftype') for s in sectionsList: if s.offset < machO_fileOrigin: s.offset += machO_fileOrigin sections.append(s, className=type(s).__name__, sectname=s.sectname, ftype=s.ftype) self.sections = sections self._hasAnalyzedSections = False self._shouldImportMappings = machO.mappings.mutable
def f(machO, vmaddr, *args, **kwargs): if vmaddr: machO.seek(machO.fromVM(vmaddr)) count = readStruct(machO.file, machO.makeStruct('2L'))[1] lst = [method(machO, *args, **kwargs) for _ in range(count)] lst.reverse() # it is needed because the methods defined early will often appear later in the binary. return lst else: return []
def readProperty(machO): """Read an ``objc_property`` at current position to a :class:`~objc.property.Property`.""" # struct objc_property { # const char *name; # const char *attributes; # }; (namePtr, attribPtr) = readStruct(machO.file, machO.makeStruct('2^')) name = machO.derefString(namePtr) attrib = machO.derefString(attribPtr) return Property(name, attrib)
def readMethod(machO, optional): """Read a ``method_t`` at current position to a :class:`~objc.method.Method`.""" # typedef struct method_t { # SEL name; # const char *types; # IMP imp; # } method_t; (namePtr, encPtr, imp) = readStruct(machO.file, machO.makeStruct('3^')) name = machO.derefString(namePtr) encoding = machO.derefString(encPtr) return Method(name, encoding, imp, optional)
def _readProtocolRefListAt(machO, vmaddr): """Return the an iterable of addresses to protocols from *vmaddr*.""" # typedef struct protocol_list_t { # // count is 64-bit by accident. # uintptr_t count; # protocol_ref_t list[0]; // variable-size # } protocol_list_t; if vmaddr: machO.seek(machO.fromVM(vmaddr)) ptrStru = machO.makeStruct('^') count = readStruct(machO.file, ptrStru)[0] return peekPrimitives(machO.file, '^', count, machO.endian, machO.is64bit) else: return []
def readIvar(machO): """Read an ``ivar_t`` at current position to an :class:`~objc.ivar.Ivar`.""" # typedef struct ivar_t { # // *offset is 64-bit by accident even though other # // fields restrict total instance size to 32-bit. # uintptr_t *offset; # const char *name; # const char *type; # // alignment is sometimes -1; use ivar_alignment() instead # uint32_t alignment __attribute__((deprecated)); # uint32_t size; # } ivar_t; (offsetPtr, namePtr, encPtr, _, _) = readStruct(machO.file, machO.makeStruct('3^2L')) offset = machO.deref(offsetPtr, machO.makeStruct('^'))[0] name = machO.derefString(namePtr) encoding = machO.derefString(encPtr) return Ivar(name, encoding, offset)
def readIvar(machO): """Read an ``ivar_t`` at current position to an :class:`~objc.ivar.Ivar`.""" # typedef struct ivar_t { # // *offset is 64-bit by accident even though other # // fields restrict total instance size to 32-bit. # uintptr_t *offset; # const char *name; # const char *type; # // alignment is sometimes -1; use ivar_alignment() instead # uint32_t alignment __attribute__((deprecated)); # uint32_t size; # } ivar_t; (offsetPtr, namePtr, encPtr, _, _) = readStruct(machO.file, machO.makeStruct('3^2L')) offset = machO.deref(offsetPtr, machO.makeStruct('L'))[0] name = machO.derefString(namePtr) encoding = machO.derefString(encPtr) return Ivar(name, encoding, offset, offsetPtr)
def _loadSections(self, machO): segStruct = machO.makeStruct('16s4^2i2L') sectStruct = machO.makeStruct(Section.STRUCT_FORMAT) (segname, self.vmaddr, self._vmsize, self._fileoff, self._filesize, self.maxprot, self.initprot, nsects, _) = readStruct(machO.file, segStruct) self.segname = fromStringz(segname) machO_fileOrigin = machO._fileOrigin sectVals = peekStructs(machO.file, sectStruct, count=nsects) # get all section headers sectionsList = (Section.createSection(i) for i in sectVals) # convert all headers into Section objects sections = DataTable('className', 'sectname', 'ftype') for s in sectionsList: if s.offset < machO_fileOrigin: s.offset += machO_fileOrigin sections.append(s, className=type(s).__name__, sectname=s.sectname, ftype=s.ftype) self.sections = sections self._hasAnalyzedSections = False self._shouldImportMappings = machO.mappings.mutable