def __init__(self,f,offset): f.seek(offset) self.strOffset = int(struct.unpack('<L',f.read(4))[0]) self.timeStamp = int(struct.unpack('<L',f.read(4))[0]) self.curVersion= int(struct.unpack('<L',f.read(4))[0]) self.cptVersion= int(struct.unpack('<L',f.read(4))[0]) self.name = readStringFromOffsetOfFile(f.tell(),f)
def getIMP(self,f,offset): if self.is64bit: offset = offset + 0x10 else: offset = offset + 0x8 methodIMPVM = readVMData(typeoffset,f,self.is64bit) #name offset 0x8 byte in method struct methodIMPOffset = self.extracttool.macho_utility.getFileOffFromVmAddr(methodTypeVM) methodIMP = readStringFromOffsetOfFile(methodTypeOffset,f) return methodIMP
def initName(self,f,curclassOff): f.seek(curclassOff+0x10) if self.is64bit: f.read(0x10) dataVMaddr = readVMData(f.tell(),f,self.is64bit)#vm_addr dataOffset = self.extracttool.macho_utility.getFileOffFromVmAddr(dataVMaddr) #in __DATA.__objc_const f.seek(dataOffset+0x10)#0x10 in 32bit 0x18 in 64bit if self.is64bit: f.read(0x8) nameVMaddr = readVMData(f.tell(),f,self.is64bit) cursor = f.tell() nameOffset = self.extracttool.macho_utility.getFileOffFromVmAddr(nameVMaddr) name = readStringFromOffsetOfFile(nameOffset,f) self.methods = self.initMethods(f,cursor) return name
def initLoadCommand(self): with open(self.path,'rb') as f: if self.isfat(): #find first arch pass elif self.isMachO(): f.seek(0x10) LCcount = int(struct.unpack('<L',f.read(4))[0]) #skip mach-o header #64bit is 0x20 if self.is64bit(0): f.seek(MACHO_HEADER_SIZE_64bit) else: f.seek(MACHO_HEADER_SIZE_32bit) index = 0 while index < LCcount: index = index+1 fileOff = f.tell() cmdName = int(struct.unpack('<L',f.read(4))[0]) cmdSize = int(struct.unpack('<L',f.read(4))[0]) if cmdName == 0x01 or cmdName == 0x19: #segment #self.loadcommands["LC_SEGMENT"]=f.tell() segment = Segment(f,f.tell(),self.is64bit(0)) #f.tell()will change in called-Function self.segments.append(segment) elif cmdName == 0x0c or cmdName == 0x8000001c: if cmdName == 0x0c: #LC_LOAD_DYLIB #self.loadcommands["LC_LOAD_DYLIB"]=f.tell() lcdylib = LcLoadDylib(f,f.tell()) self.libs.append(lcdylib.name) f.seek(fileOff+cmdSize) else: #LC_RPATH #self.loadcommands["LC_RPATH"]=f.tell() pdb.set_trace() f.read(4) # strOffset rpath = readStringFromOffsetOfFile(f.tell(),f) self.libs.append(rpath) f.seek(fileOff+cmdSize) elif cmdName == 0xB: #LD_DYSYMTAB self.loadcommands["LD_DYSYMTAB"]=f.tell()-0x8 f.seek(f.tell()-0x8+cmdSize) else: f.seek(f.tell()-0x8+cmdSize) continue
def getName(self,f,offset): methodnameVM = readVMData(offset,f,self.is64bit) #name offset 0x8 byte in method struct methodnameOffset = self.extracttool.macho_utility.getFileOffFromVmAddr(methodnameVM) methodname = readStringFromOffsetOfFile(methodnameOffset,f) return methodname