def dump_onenand_page(self, page, block): """ dump a page in a spesific block """ tx = pack32L(block) + pack32L(page) + pack32L(1) return self.__send_command(self.Commands.ONENAND_READ, tx)[:self.__onenand_page_size]
def scan_mem(self, start=0, end=0x100000000, step=0x10000): """ Sends the ScanMem command, with size 0, only to check validity of memory parts. """ ranges = [] cur = 0 rangeStart = 0 buf = self.__send_command( self.Commands.SCANMEM, pack32L(start) + pack32L(end - 1) + pack32L(0) + pack32L(step)) buf += "\x00" # If the last block is valid, this will make the code work. for i, v in enumerate(buf): v = ord(v) if cur == 0: if v == 0: continue rangeStart = start + i * step else: # 1 if v == 1: continue ranges.append((rangeStart, start + i * step)) cur = v return ranges
def internal_nand_update(self, page_size, total_page_size): self.page_size = page_size self.total_page_size = total_page_size self._ProtocolRETeam__send_command( self.Commands.INTERNAL_NAND_UPDATE, pack32L(self.page_size) + pack32L(self.total_page_size))
def init_onenand(self, addr, ahb_addr=0x20000000): """ get the address of the nand, and send an INIT command. display the result values and returns (number of blocks, pages in block) """ #send command and parse replay init_data = self.__send_command(self.Commands.INIT_ONE_NAND, pack32L(addr) + pack32L(ahb_addr)) init_data_a = struct.unpack("<" + "I" * 16, init_data) #print replay print " number of blocks:", init_data_a[0] print " pages in block :", init_data_a[1] print " page size (b) :", init_data_a[2] print " manufacturer ID :", init_data_a[3] print " device id :", init_data_a[4] print " size (mb) :", init_data_a[5] print " VCC 0-1.8 1-2.65:", init_data_a[6] print " muxing (1-demux):", init_data_a[7] print " cores (0-single):", init_data_a[8] print " boot type :", init_data_a[9] print " Version ID :", init_data_a[10] print " data buffer size:", init_data_a[11] print " boot buffer size:", init_data_a[12] print " data buf number :", init_data_a[13] print " boot buf number :", init_data_a[14] print " tech 0-slc 1-mlc:", init_data_a[15] pages_in_block, number_of_blocks = init_data_a[1], init_data_a[0] page_size = init_data_a[2] self.__onenand_page_size = init_data_a[2] return (number_of_blocks, pages_in_block, page_size ) # return number of blocks
def test(self, number, param2=0, param3=0): """ send 4 bytes to test method of bootloader """ return self.__send_command( self.Commands.TEST, pack32L(number) + pack32L(param2) + pack32L(param3))
def write_ram(self, address, data, max_retry_count=10): """ write a bootloader chunk to a spesific address """ tx = pack32L(address) + pack32L(len(data)) + data return self.__send_command(self.Commands.WRITE_RAM, tx, max_retry_count=max_retry_count)
def nand_read(self, addr, multi_page=False, multi_page_init=False, use_dma=True): """ return a single page """ return self.__send_command( self.Commands.NAND_READ, pack32L(addr) + pack32L(int(multi_page)) + pack32L(int(use_dma)))
def nand_probe(self, chipset_type, base_address): data = pack32L(chipset_type) + pack32L(base_address) result = self._ProtocolRETeam__send_command( self.Commands.CMD_PROB_NAND, data) if (len(result) < 8): raise repr(result) maker_id = unpack32L(result[:4]) device_id = unpack32L(result[4:]) print "maker id: %08X" % maker_id print "device id: %08X" % device_id return (maker_id, device_id)
def internal_nand_read(self, page, param1=None, param2=None): out = pack32L(page) if (None != param1): out += pack32L(param1) if (None != param2): out += pack32L(param2) data = self._ProtocolRETeam__send_command( self.Commands.INTERNAL_NAND_READ, out) if ("\xff\xff\xff\xff" == data): return self.total_page_size * "\xFF" return data
def internal_nand_init(self, start_addr=0, end_addr=0, version=1): nand_type_string = {1: "1 - Nand", 2: "2 - OneNand", 3: "3 - OrNand"} cmd = pack32L(start_addr) + pack32L(end_addr) + pack32L(version) tout = self.framer.get_timeout() self.framer.set_timeout(20) self.framer.base.flush() try: data = self._ProtocolRETeam__send_command( self.Commands.INTERNAL_NAND_INIT, cmd) except Exception, e: if "recv error" in repr(e): raise Exception("Can't find internal! %r" % (e))
def init_alloc(self, addr_start=0, addr_end=0x800000): tout = self.framer.get_timeout() self.framer.set_timeout(0.1) try: ret = self._ProtocolRETeam__send_command(self.Commands.INIT_ALLOC, \ pack32L(addr_start) + pack32L(addr_end), sleep = 1) self.framer.set_timeout(tout) return unpack32L(ret) except Exception, e: if "FramerRETeam: got only empty head!" in repr(e): pass else: raise
def rpc(self, address, arg0=0, arg1=0, arg2=0, arg3=0, arg4=0): """ invalidate cache """ data = "".join( [pack32L(i) for i in [address, arg0, arg1, arg2, arg3, arg4]]) ret = self.__send_command(self.Commands.RPC, data)
def internal_read(self, page, ecc_state = 1): addr = page * self.max_page_size_info txdata = pack32L(addr) + pack16L(ecc_state) + struct.pack("<" + "I"*3, self.max_block_cnt_info, self.max_block_size_info, self.max_page_size_info) txdata += "\x00" * (self.header_len - len(txdata)) data = self.send_command(self.Commands.CMD_NAND_IMAGE_READ_PAGE, \ self.Commands.CMD_NAND_IMAGE_READ_PAGE, txdata) page_data = data[self.header_len:] return page_data
def __poke(self, command, addr, data, codeword_size, max_codeword_size): if ((len(data) % codeword_size) > 0) or (len(data) > max_codeword_size * codeword_size): raise Exception( "ProtocolQualcommDiag: __poke got invalid data length: " + repr(len(data))) padding = "\x00" * ((max_codeword_size * codeword_size) - (len(data))) return self.__send_command( command, tx=pack32L(addr) + chr(len(data) / codeword_size) + data + padding)
def authenticate(self): """ send 32 bit value, get back challange. send response, get back some value if it's the correct response """ challange = unpack32L( self._ProtocolRETeam__send_command(self.Commands.CHALLENGE_REQ)) print "Authenticate, Received: %X" % challange resp = gen_response(challange) return self._ProtocolRETeam__send_command(self.Commands.CHALLENGE_RES, pack32L(resp))
def mmc_init(self, version=0): data = self.__send_command(self.Commands.INIT_MMC, pack32L(version)) product_name = data[6:6 + 6][::-1] block_count = unpack32L(data[16:16 + 4]) block_size = unpack32L(data[20:24]) card_mid = unpack16L(data[14:16]) print "Product Name: ", product_name print "Manufacturer Id: 0x%X" % card_mid print "Block Count: 0x%X" % block_count print "Block Size : 0x%X" % block_size print "Capacity: : %d(MB)" % ((block_count * block_size) / (1024 * 1024)) return block_count, block_size
def read_mem_chunks(self, start=0, end=0x100000000, step=0x1000, chunkSize=4): """ Sends the ScanMem command in order to read the chunks. """ assert chunkSize > 0 buf = self.__send_command( self.Commands.SCANMEM, pack32L(start) + pack32L(end - 1) + pack32L(chunkSize) + pack32L(step)) chunks = [] numSteps = len(buf) / (chunkSize + 1) for i in range(numSteps): tmpChunk = buf[i * (chunkSize + 1):(i + 1) * (chunkSize + 1)] if tmpChunk[0] == '\0': continue chunks.append((start + i * step, tmpChunk[1:])) return chunks
def change_baudrate(self, baud=921600, par=PARITY_NONE, reconnect=False, delay=0, test=True, use_enum=True): if (use_enum): if baud == 921600: send = 1 elif baud == 460800: send = 2 elif baud == 230400: send = 4 elif baud == 115200: send = 8 elif baud == 57600: send = 16 else: raise Exception("ProtocolRETeamBootloader: unknown baudrate") else: send = baud self.framer.send(self.Commands.CHANGE_BAUD, pack32L(send)) time.sleep(delay) if reconnect: self.framer.close() self.framer.connect() self.framer.set_baudrate(baud) self.framer.set_parity(par) if (test): time.sleep(0.1) self.framer.recv_no_wait() #If the changing fails, then ping with raise an exception try: self.ping("TEST", False) except Exception, e: raise Exception("Change Baudrate: " + repr(e))
def get_next_filesystem_item_name(self, seq=1, is_dirs=False, parent_dir='/'): """ iterate over files in a directory of the phone filesystem seq number 0 means first, any other means next (but maybe best to have a counter, just make sure it elapse to 1 rather than 0) send:0x59,cmd(0x0B=files/0x0A=dirs),seq[4],dir_name_len[1],sz_dir_name[len] get: 0x59,cmd(0x0B/0x0A),status[1],seq[4],attributes[4],creation_date[4],logical_size[4],physical_size[4],path_part_len[1],path_and_name_len[1],sz_name[path_and_name_len] if status 0 a valid name is returned status 0x0D means bad filename (probably a dir) so just ignore status 0x1C end of file list exception is raised by send_command() if listing a protected directory like ".efs_private" since device replies with 0x13 (DIAG_BAD_CMD) """ nullTerm = '\x00' cmd = self.FS_Item_Types.FILE #files if is_dirs: cmd = self.FS_Item_Types.DIRECTORY #dirs cmd_params = chr(cmd) + pack32L(seq) + chr( len(parent_dir) + len(nullTerm)) + parent_dir + nullTerm return self.__send_command(self.Commands.DIAG_FS_OP_F, cmd_params)
def kafig_init(self, nandAddress): self.__send_command(self.Commands.KAFIG_INIT, pack32L(nandAddress)) infoData = self.__send_command(self.Commands.KAFIG_INFO) chipName, pageSize, blockSize, numBlocks, extraPageSize, wordSize = struct.unpack( "16s5L", infoData) if chipName[0] == "\0": raise Exception("Unsupported K9F1G NAND chip") numPagesInBlock = blockSize / pageSize chipName = chipName.replace("\0", "") print "Kafig NAND chip: '%s'" % chipName print "\tPage Size: %d" % pageSize print "\tBlock Size: %d" % blockSize print "\tExtra Page Bytes: %d" % extraPageSize print "\tWord Size: %d" % wordSize print "\tNum Blocks: %d" % numBlocks print "Total Size: %dMbit" % ( (pageSize + extraPageSize) * numPagesInBlock * numBlocks / 1024 / 1024 * 8) self.__kafigPagesInBlock = numPagesInBlock return chipName, pageSize, blockSize, numBlocks, extraPageSize, wordSize
def dump_ram(self, addr, size): """ dump a section of ram """ tx = pack32L(size) + pack32L(addr) return self.__send_command(self.Commands.RAM_READ, tx)[:size]
def mmc_read(self, block_start, block_count, ram_address): result = (self.__send_command( self.Commands.READ_MMC, pack32L(block_start) + pack32L(block_count) + pack32L(ram_address))) return struct.unpack("<l", result)[0]
def branch(self, addr, params=[]): """Branch to a given address.""" return self.__send_command( self.Commands.BRANCH, pack32L(addr) + "".join(map(pack32L, params)))
def init_bootloader(self, param_vector): print "Initializing bootloader using these values: ", map( hex, param_vector) init_data = self.__send_command( self.Commands.INIT_BTL, "".join([pack32L(x) for x in param_vector]))
def nand_read(self, page): return self._ProtocolRETeam__send_command(self.Commands.CMD_READ_NAND, pack32L(page))
def kafig_read(self, pageNum): blockNum = pageNum / self.__kafigPagesInBlock pageNum = pageNum % self.__kafigPagesInBlock return self.__send_command(self.Commands.KAFIG_READ, pack32L(blockNum) + pack32L(pageNum))
def nand_init(self, page_size, spare_size, block_size, block_count, width): return unpack32L(self.__send_command(self.Commands.INIT_NAND, pack32L(page_size)+pack32L(spare_size) + \ pack32L(block_size) + pack32L(block_count) + pack32L(width) ))
def auth(self): hash_res = hashlib.md5( "This is a Cellebrite Proprietary Program").digest() to_send = ''.join(pack32L(ord(c)) for c in hash_res[:4]) + hash_res[4:8] return self.__send_command(self.Commands.AUTH, to_send)
def nand_probe(self, version, chip_select=0): nand_id = self.__send_command(self.Commands.PROB_NAND, pack32L(version) + pack32L(chip_select)) maker_id = ord(nand_id[0]) device_id = ord(nand_id[1]) return maker_id, device_id
def init_samsung_nand(self, addr): """ init samsung nands """ self.__send_command(self.Commands.INIT_ONE_NAND, pack32L(addr))