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 _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
# This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # from macho.sections.section import Section, S_CSTRING_LITERALS from macho.utilities import readString from macho.symbol import SYMTYPE_CSTRING, Symbol def _stringReader(file, curAddr, final): while curAddr < final: (string, length) = readString(file, returnLength=True) if length: yield Symbol(string, curAddr, SYMTYPE_CSTRING) curAddr += length+1 class CStringSection(Section): """The C string (``__TEXT,__cstring``) section.""" def analyze(self, segment, machO): machO.addSymbols(_stringReader(machO.file, self.addr, self.addr + self.size)) Section.registerFactoryFType(S_CSTRING_LITERALS, CStringSection.byFType)
# You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # from macho.sections.section import Section from macho.utilities import peekFixedLengthString from macho.symbol import Symbol, SYMTYPE_CFSTRING import macho.loadcommands.segment # to ensure macho.macho.fromVM is defined. def _stringReader(machO, addressesAndLengths): origin = machO.origin machO_fromVM = machO.fromVM machO_file = machO.file for addr, (_, _, strAddr, strLen) in addressesAndLengths: fileoff = machO_fromVM(strAddr) string = peekFixedLengthString(machO_file, strLen, position=fileoff+origin) yield Symbol(string, addr, SYMTYPE_CFSTRING) class CFStringSection(Section): """The CoreFoundation string (``__DATA,__cfstring``) section.""" def analyze(self, segment, machO): cfstrStruct = machO.makeStruct('4^') addressesAndLengths = self.asStructs(cfstrStruct, machO, includeAddresses=True) machO.addSymbols(_stringReader(machO, addressesAndLengths)) Section.registerFactory('__cfstring', CFStringSection)
def _analyze2(self, machO, classes, protoRefsMap): addresses = self.asPrimitives('^', machO) self.categories = readCategoryList(machO, addresses, classes, protoRefsMap) def analyze(self, segment, machO): # Make sure the classlist section is ready if exists. protoRefsMap = machO.anySectionProperty('className', 'ObjCProtoListSection', 'protocols', default={}) classes = machO.anySectionProperty('className', 'ObjCClassListSection', 'classes', default={}) if protoRefsMap is None or classes is None: return True if self.segname == '__OBJC': self._analyze1(machO, classes, protoRefsMap) else: self._analyze2(machO, classes, protoRefsMap) Section.registerFactory('__objc_catlist', ObjCCategoryListSection) # __DATA,__objc_catlist Section.registerFactory('__category_list', ObjCCategoryListSection) # __OBJC2,__category_list Section.registerFactory('__category', ObjCCategoryListSection) # __OBJC,__category (ABI 1.0)
if dysymtab is None: # Make sure the DYSYMTAB command exists. return False elif not dysymtab.isAnalyzed: # and loaded return True elif not dysymtab.indirectsymoff: # and has the indirect symbol table. return False symtab = machO.loadCommands.any('className', 'SymtabCommand') if symtab is None: return False elif not symtab.isAnalyzed: return True stride = self.reserved[1] or machO.pointerWidth count = self.size // stride symbols = machO.symbols symbols_append = symbols.append indirectSyms = dysymtab.indirectSymbols(self.reserved[0], self.size // stride, machO) addresses = range(self.addr, self.addr + count*stride, stride) machO.provideAddresses(zip(indirectSyms, addresses)) Section.registerFactoryFType(S_NON_LAZY_SYMBOL_POINTERS, SymbolPtrSection.byFType) # Section.registerFactoryFType(S_LAZY_SYMBOL_POINTERS, SymbolPtrSection.byFType) # # - The __la_symbol_ptr adds nothing of value to the symbol table. # Section.registerFactoryFType(S_LAZY_DYLIB_SYMBOL_POINTERS, SymbolPtrSection.byFType) Section.registerFactoryFType(S_SYMBOL_STUBS, SymbolPtrSection.byFType)
from macho.sections.section import Section from macho.utilities import peekFixedLengthString from macho.symbol import Symbol, SYMTYPE_CFSTRING import macho.loadcommands.segment # to ensure macho.macho.fromVM is defined. def _stringReader(machO, addressesAndLengths): origin = machO.origin machO_fromVM = machO.fromVM machO_file = machO.file for addr, (_, _, strAddr, strLen) in addressesAndLengths: fileoff = machO_fromVM(strAddr) string = peekFixedLengthString(machO_file, strLen, position=fileoff + origin) yield Symbol(string, addr, SYMTYPE_CFSTRING) class CFStringSection(Section): """The CoreFoundation string (``__DATA,__cfstring``) section.""" def analyze(self, segment, machO): cfstrStruct = machO.makeStruct('4^') addressesAndLengths = self.asStructs(cfstrStruct, machO, includeAddresses=True) machO.addSymbols(_stringReader(machO, addressesAndLengths)) Section.registerFactory('__cfstring', CFStringSection)
""" def _analyze1(self, machO, protoRefsMap): addressesAndClassTuples = self.asStructs(machO.makeStruct('12^'), machO, includeAddresses=True) self.classes = analyzeClassList(machO, addressesAndClassTuples, protoRefsMap) def _analyze2(self, machO, protoRefsMap): addresses = self.asPrimitives('^', machO) self.classes = readClassList(machO, addresses, protoRefsMap) def analyze(self, segment, machO): # Make sure the protocol sections is ready if exists. protoRefsMap = machO.anySectionProperty('className', 'ObjCProtoListSection', 'protocols', default={}) if protoRefsMap is None: return True if self.segname == '__OBJC': self._analyze1(machO, protoRefsMap) else: self._analyze2(machO, protoRefsMap) Section.registerFactory('__objc_classlist', ObjCClassListSection) # __DATA,__objc_classlist Section.registerFactory('__class_list', ObjCClassListSection) # __OBJC2,__class_list Section.registerFactory('__class', ObjCClassListSection) # __OBJC,__class # how about __DATA,__objc_nlclslist? what does it do?
* ``'name'`` (unique, string, the name of the class) * ``'addr'`` (unique, integer, the VM address to the class) """ def _analyze1(self, machO, protoRefsMap): addressesAndClassTuples = self.asStructs(machO.makeStruct("12^"), machO, includeAddresses=True) self.classes = analyzeClassList(machO, addressesAndClassTuples, protoRefsMap) def _analyze2(self, machO, protoRefsMap): addresses = self.asPrimitives("^", machO) self.classes = readClassList(machO, addresses, protoRefsMap) def analyze(self, segment, machO): # Make sure the protocol sections is ready if exists. protoRefsMap = machO.anySectionProperty("className", "ObjCProtoListSection", "protocols", default={}) if protoRefsMap is None: return True if self.segname == "__OBJC": self._analyze1(machO, protoRefsMap) else: self._analyze2(machO, protoRefsMap) Section.registerFactory("__objc_classlist", ObjCClassListSection) # __DATA,__objc_classlist Section.registerFactory("__class_list", ObjCClassListSection) # __OBJC2,__class_list Section.registerFactory("__class", ObjCClassListSection) # __OBJC,__class # how about __DATA,__objc_nlclslist? what does it do?
""" def _analyze1(self, machO, classes, protoRefsMap): cats = self.asStructs(machO.makeStruct('5^L~^'), machO) # assert False, "Analyzing ABI 1.0 for the __OBJC,__category section is not implemented yet." self.categories = analyzeCategoryList(machO, cats, classes, protoRefsMap) def _analyze2(self, machO, classes, protoRefsMap): addresses = self.asPrimitives('^', machO) self.categories = readCategoryList(machO, addresses, classes, protoRefsMap) def analyze(self, segment, machO): # Make sure the classlist section is ready if exists. protoRefsMap = machO.anySectionProperty('className', 'ObjCProtoListSection', 'protocols', default={}) classes = machO.anySectionProperty('className', 'ObjCClassListSection', 'classes', default={}) if protoRefsMap is None or classes is None: return True if self.segname == '__OBJC': self._analyze1(machO, classes, protoRefsMap) else: self._analyze2(machO, classes, protoRefsMap) Section.registerFactory('__objc_catlist', ObjCCategoryListSection) # __DATA,__objc_catlist Section.registerFactory('__category_list', ObjCCategoryListSection) # __OBJC2,__category_list Section.registerFactory('__category', ObjCCategoryListSection) # __OBJC,__category (ABI 1.0)
return False elif not dysymtab.isAnalyzed: # and loaded return True elif not dysymtab.indirectsymoff: # and has the indirect symbol table. return False symtab = machO.loadCommands.any('className', 'SymtabCommand') if symtab is None: return False elif not symtab.isAnalyzed: return True stride = self.reserved[1] or machO.pointerWidth count = self.size // stride symbols = machO.symbols symbols_append = symbols.append indirectSyms = dysymtab.indirectSymbols(self.reserved[0], self.size // stride, machO) addresses = list(range(self.addr, self.addr + count * stride, stride)) machO.provideAddresses(list(zip(indirectSyms, addresses))) Section.registerFactoryFType(S_NON_LAZY_SYMBOL_POINTERS, SymbolPtrSection.byFType) # Section.registerFactoryFType(S_LAZY_SYMBOL_POINTERS, SymbolPtrSection.byFType) # # - The __la_symbol_ptr adds nothing of value to the symbol table. # Section.registerFactoryFType(S_LAZY_DYLIB_SYMBOL_POINTERS, SymbolPtrSection.byFType) Section.registerFactoryFType(S_SYMBOL_STUBS, SymbolPtrSection.byFType)
A :class:`~data_table.DataTable` of :class:`~objc.protocol.Protocol`\\s, with the following columns: * ``'name'`` (string, the name of the protocol) * ``'addr'`` (unique, integer, the VM address to the protocol) """ def _analyze1(self, machO): protos = self.asStructs(machO.makeStruct('5^'), machO, includeAddresses=True) self.protocols = analyzeProtocolList(machO, protos) def _analyze2(self, machO): # In ABI 2.0, the __DATA,__objc_protolist contains a list of file offsets # in native width and endian. These offsets will point to a protocol_t # structure as described in objc-runtime-new.h. addresses = self.asPrimitives('^', machO) self.protocols = readProtocolList(machO, addresses) def analyze(self, segment, machO): if self.segname == '__OBJC': return self._analyze1(machO) else: return self._analyze2(machO) Section.registerFactory('__objc_protolist', ObjCProtoListSection) # __DATA,__objc_protolist Section.registerFactory('__protocol_list', ObjCProtoListSection) # __OBJC2,__protocol_list Section.registerFactory('__protocol', ObjCProtoListSection) # __OBJC,__protocols (ABI 1.0)
# This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # from macho.sections.section import Section, S_CSTRING_LITERALS from macho.utilities import readString from macho.symbol import SYMTYPE_CSTRING, Symbol def _stringReader(file, curAddr, final): while curAddr < final: (string, length) = readString(file, returnLength=True) if length: yield Symbol(string, curAddr, SYMTYPE_CSTRING) curAddr += length + 1 class CStringSection(Section): """The C string (``__TEXT,__cstring``) section.""" def analyze(self, segment, machO): machO.addSymbols( _stringReader(machO.file, self.addr, self.addr + self.size)) Section.registerFactoryFType(S_CSTRING_LITERALS, CStringSection.byFType)