iPhone devices have two primary types of memory, volatile (RAM) and nonvolatile (NAND Flash) memory. Each provides a different insight into the device's data.
NAND Flash
Unlike RAM, NAND Flash is nonvolatile and thus data is preserved even when the device is without power or it is rebooted. The NAND Flash is used to store not only system files but significant portions of the user's data as well.
NAND Flash memory has characteristics very different from the magnetic media found in modern hard drives. These properties make NAND Flash ideal storage for mobile devices, while at the same time presenting a number of challenges for programmers and opportunities for forensic analysts.
First, NAND Flash has no mechanical moving parts like the spinning platters and arms found in traditional magnetic hard drives. This improves the durability and reduces both the size and power consumption of the device. The memory is distributed as one or multiple chips, which often integrate both NAND Flash and RAM and are directly integrated into the circuit board of the device.
NAND Flash also has very high density and is cost effective to the manufacturer. This, of course, makes it very popular with manufacturers. One side effect of the manufacturing process and technology in general is that NAND Flash literally ships with bad blocks directly from the manufacturer. The manufacturer will generally test the memory as part of the manufacturing process and mark bad blocks in a specific structure on the NAND, which is described in their documentation. Software that then directly interacts with the NAND Flash can read the manufacturer's bad block markers and will often implement a bad block table that can logically track the bad blocks on the system and remove them from operation. This greatly speeds up bad block detection and management. So, while NAND Flash is more physically durable than spinning platters, its error rate is much higher and must be accounted for in development and use.
Another significant limitation of NAND Flash is that it has a very limited write/erase lifespan before the block is no longer capable of storing data. The lifespan varies by device and is largely impacted by the amount of data stored per NAND Flash cell, the central building block for storing the 1 or 0 bit(s). If the cell stores only a single bit (single-level cell or SLC), then the NAND Flash supports around 100,000 write/erase cycles for a 1-year data retention. However, NAND Flash rarely uses SLC, as manufacturers (and consumers) demand more data storage in devices that are of similar size or smaller. The technology has moved to multilevel cells (MLCs), where a cell can store 2, 3, or even more bits per cell. However, this not only complicates the manufacturing process and slows down the write/erase cycle but also significantly reduces the endurance of the device. A typical MLC NAND Flash storing 2 bits per cell experiences a 10-fold reduction in endurance (measured as a 1-year data retention) with a value of approximately 10,000 write/erase cycles. As the bit density per cell increases, the endurance continues to drop, which must obviously be addressed by the controlling device.
Unlike RAM and NOR Flash (which also has Flash memory and is typically used in systems such as a computer's basic input output system or BIOS), NAND Flash cannot be accessed randomly. Instead, access to data is achieved via an allocation unit, called a page, which is typically between 512 and 2048 bytes, but generally increases as the overall size of NAND Flash increases. As an example, on one 32 GB iPhone 4 device, there were shown to be 8192 bytes per page. Even though NAND Flash does not provide the fast random access like RAM, access time is still quite fast since it does not require the mechanical platter and arm movements used in traditional spinning hard drives. The pages are then organized into a larger logical unit called a block, which is typically much larger than a traditional 512 GB hard drive sector. When a block is allocated for writing, the pages inside the block are written sequentially.
Within the iPhone's file system, there is a file called “ADDataStore.sqlitedb” that contains specific details related to the NAND Flash contained within that device. With some of the earlier models, this database was empty. However, when populated, the “Scalar” table will contain information similar to the following:
key = com.apple.NANDInfo.NumVirtualBlocks
daysSince1970 = 15008
value = 1952
key = com.apple.NANDInfo.PagesPerVirtualBlock
daysSince1970 = 15008
value = 1024
key = com.apple.NANDInfo.BytesPerPage
daysSince1970 = 15008
value = 8192
key = com.apple.NANDInfo.NumLogicalReads
daysSince1970 = 15008
value = 6224374
key = com.apple.NANDInfo.NumLogicalWrites
daysSince1970 = 15008
value = 9026722
key = com.apple.NANDInfo.NumFreeVirtualBlocks
daysSince1970 = 15008
value = 1804
key = com.apple.NANDInfo.NumWearLevelOps
daysSince1970 = 15008
value = 726518
key = com.apple.NANDInfo.NumPhysicalReads
daysSince1970 = 15008
value = 6420028
key = com.apple.NANDInfo.NumPhysicalWrites
daysSince1970 = 15008
value = 10489657
key = com.apple.NANDInfo.NumPhysicalErases
Key characteristics of NAND Flash are the operations available for reading and writing:
While individual pages can be read or written, the erase operation only functions at the block level. When a block is erased, the entire block is written over with 1's (or 0xFF in hex). The erase operation is the only mechanism by which a 0 can be changed to a 1 in NAND Flash. This point is worth belaboring. In a traditional hard drive, if a value is changed from a 0 to a 1 (or vice versa), the program simply seeks the value on the hard drive and applies the appropriate voltage to change and store the new value. However, the fundamental architecture of NAND Flash provides only one mechanism to change a 0 to a 1 and that is via the erase function which is applied at the block level, not an individual page level. For this reason, a page can be written only once, and if the value of the page needs to be changed, the entire block must be erased and then the page rewritten.
Here is a specific example using a single byte for simplicity: Let us say this particular byte holds the decimal value 179 and we want to add 39 for a total value of 218. For those unfamiliar with converting numbers between base10, hex (base16), and binary (base2), the built-in calculator programs in Windows, Mac OS X, and Ubuntu Linux, all provide a programmer mode that will perform the conversions. For the numbers above, we have the conversions between numbering systems shown in
Table 3.2.
Table 3.2 Decimal, Hex, and Binary Representation of Integers
Decimal (base10) | Hex (base16) | Binary (base2) |
---|
179 | 0xB3 | 1011 0011 |
218 | 0xDA | 1101 1010 |
So the value 179 contains three 0's and two of them need to change to 1's to present our new value of 218. However, NAND Flash cannot make that change without erasing the entire block. So, if this single byte were attempted without the erase, the result would be 146, not 218. Here is how this happens:
1011 0011 (original byte, 0xB3 or 179 decimal)
1101 1010 (new byte to write, 0xDA or 218 decimal)
1001 0010 (resulting byte, 0x92 or 146 decimal)
As the byte does not contain all 1's (0xFF), the only portions of the write cycle that will succeed are 1's either remaining a 1 or changing to a 0. Whenever the write function encounters a 0 and is requested to change to a 1, it fails and simply retains the 0 value. The resulting byte is 0x92 or 146 base10 – clearly not the value intended. Another way to describe the write function is that it only changes the changed 1 values to a 0 when requested, the equivalent of the “logical and” of the two values.
In summary, a page can be written only once and, if it needs to be rewritten, the entire block must first be erased.
As one can tell, NAND Flash imposes various restrictions and limitations and thus developers and file systems must be Flash-aware to effectively work within the constraints. Two important techniques deployed are error-correcting code (ECC) and wear leveling. Both have significant implications for forensics and data recovery.
First, ECC is a technique in which an algorithm is used to detect data errors on read or write operations and correct some errors on the fly. Since NAND Flash degrades over time through usage, the system must be able to detect when a page or block is going bad and recover the data stored there. After a number of errors or failed operations is exceeded (typically three failed operations), the page or block will be marked bad and added to the bad block table.
The second important algorithm used to effectively manage NAND Flash on the iPhone is the wear-leveling code. Wear leveling spreads the writing of data across the entire NAND Flash to avoid overutilization of a single area, which would wear those blocks out more quickly. It is built into HFS Plus (Hierarchical File System Plus) with the goal of reducing writes and deletes to the NAND so that the data is preserved as long as possible. Wear-leveling is also the reason why so much information can be recovered from the device. Old data copies are not deleted, but instead marked as “unallocated.” For this reason, there are latent copies of sensitive iPhone data that can be analyzed for information but may have been deleted days, weeks, or months earlier. This analysis is discussed further in
Chapter 6.