Ejemplo n.º 1
0
    def __init__(self, filename, device_infos, ppn=False):
        self.device_infos = device_infos
        self.partition_table = None
        self.lockers = {}
        self.iosVersion = 0
        self.hasMBR = False
        self.metadata_whitening = False
        self.filename = filename
        self.encrypted = device_infos["hwModel"] not in ["M68AP", "N45AP", "N82AP", "N72AP"]
        self.initGeometry(device_infos["nand"])
        
        if os.path.basename(filename).startswith("ce_"):
            self.image = NANDImageSplitCEs(os.path.dirname(filename), device_infos["nand"])
        elif filename == "remote":
            self.image = NANDRemote(self.pageSize, self.metaSize, self.pagesPerBlock, self.bfn)
        else:
            self.image = NANDImageFlat(filename, device_infos["nand"])
        
        s, page0 = self.readPage(0,0)
        self.nandonly = (page0 != None) and page0.startswith("ndrG")
        if self.nandonly:
            self.encrypted = True
        
        magics = ["DEVICEINFOBBT"]
        nandsig = None
        if page0 and page0[8:14] == "Darwin":
            print "Found old style signature", page0[:8]
            nandsig = page0
        else:
            magics.append("NANDDRIVERSIGN")

        #sp0 = {}
        sp0 = self.readSpecialPages(0, magics)
        print "Found %s special pages in CE 0" % (", ".join(sp0.keys()))
        if not self.nandonly:
            print "Device does not boot from NAND (=> has a NOR)"
        
        vfltype = '1'   #use VSVFL by default
        if not nandsig:    
            nandsig = sp0.get("NANDDRIVERSIGN")
        if not nandsig:
            print "NANDDRIVERSIGN not found, assuming metadata withening = %d" % self.metadata_whitening
        else:
            nSig, flags = struct.unpack("<LL", nandsig[:8])
            #assert nandsig[3] == chr(0x43)
            vfltype = nandsig[1]
            self.metadata_whitening = (flags & 0x10000) != 0
            print "NAND signature 0x%x flags 0x%x withening=%d, epoch=%s" % (nSig, flags, self.metadata_whitening, nandsig[0])
               
        if not self.nandonly:
            if self.device_infos.has_key("lockers"):
                self.lockers = EffaceableLockers(self.device_infos.lockers.data)
        else:
            unit = self.findLockersUnit()
            if unit:
                self.lockers = EffaceableLockers(unit[0x40:])
                self.lockers.display()
                if not self.device_infos.has_key("lockers"):
                    self.device_infos.lockers = plistlib.Data(unit[0x40:0x40+960])
                    EMF = self.getEMF(device_infos["key89B"].decode("hex"))
                    dkey = self.getDKey(device_infos["key835"].decode("hex"))
                    self.device_infos.EMF = EMF.encode("hex")
                    self.device_infos.DKey = dkey.encode("hex")

            deviceuniqueinfo = sp0.get("DEVICEUNIQUEINFO")
            if not deviceuniqueinfo:
                print "DEVICEUNIQUEINFO not found"
            else:
                scfg = parse_SCFG(deviceuniqueinfo)
                print "Found DEVICEUNIQUEINFO, serial number=%s" % scfg.get("SrNm","SrNm not found !")
        
        if vfltype == '0':
            print "Using legacy VFL"
            self.vfl = VFL(self)
            self.ftl = FTL(self, self.vfl)
        elif not ppn:
            print "Using VSVFL"
            self.vfl = VSVFL(self)
            self.ftl = YAFTL(self.vfl)