Digital Forensics

iPhone Forensics

Retrieve text messages, notes, call history etc from a backup file

It is possible to retrieve almost all the information stored on an iPhone from the backup file. You cannot retrieve stored music (as it is not backed up), or wifi passwords (as they are only stored on ecrypted backups). See Apples' Knowledge Base for more information.

The backup files are stored in the following places:

Operating SystemBackup Location
Windows\Users\(username)\AppData\Roaming\Apple Computer\MobileSync\Backup\
Windows XP\Documents and Settings\(username)\Application Data\Apple Computer\MobileSync\Backup\
Mac~/Library/Application Support/MobileSync/Backup/

The backup folder is a long hexadecimal name unique to each device. Within the folder are lots of hexadecimal files, which are consistant for all devices. Some important databases are listed:

ContentsReal NameBackup Name
SMS Messagessms.db3d0d7e5fb2ce288813306e4d4636395e047a3d28
Call Historycall_history.db2b2b0084a1bc3a5ac8c27afdf14afb42c61a19ca

The above are stored as SQLite3 databases, so you will need an SQLite viewer to see their contents

Photos and other files are stored individually, and all you need to do is add a .jpg extension onto a photo file and you will be able to view it.

Settings and other details are often stored in Apple's Property List format. These need to have a .plist extension and can be viewed these with a PList viewer

Manipulating the files

There are good reasons to manipulate these files - perhaps you want to filter 10,000 text messages to find those sent on a certain date, or to delete all messages older than a year to save space on your own device. One good way of doing this is to use the Python programming language.

Download Python from the downloads page and install it. Note that Python 2 and Python 3 versions are somewhat different in style and syntax (Python 3 is not "better" or newer than Python 2) so choose one you are comfortable with (I use Python 2 here). When you install Python in Windows, you have the option to add the executable to your PATH environment variable. I recommend you check this, so you can run Python from any location using the command line. You can run Python in Windows using the Command Prompt (Start - All Programs - Accessories)

Happily Python already comes installed with a SQLite module sqlite3, and is made available by a binding called pysqlite. However, you may not have the latest version of the SQL Database Library. This may cause the misleading error message:

sqlite3.DatabaseError: file is encrypted or is not a database

Check which version you have installed with Python in the command prompt

Python 2.7.8 ...[some info]
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> sqlite3.sqlite_version

In my case, version 3.6.2 is not up-to-date enough to open the sms.db file, though it will open notes.sqlite without any issues.

To solve this, download the latest version from, either build it yourself, or copy the precompiled binary (sqlite.dll) to your Python DLL folder (in my case C:\Python27\DLLs), and confirm:

>>> sqlite3.sqlite_version

Now I can open the sms.db correctly.

The SMS database - sms.db

In Python, you must import the module, connect to the database, set the 'cursor' position, then use the execute command to run SQLite commands. Then use fetchone() or fetchall() to return the row(s). For example:

import sqlite3
connection = sqlite3.connect("sms.db")
with connection:
cur = connection.cursor()
cur.execute("SELECT ROWID,date_delivered,text FROM message")
rows = cur.fetchall()
for result in rows:
print result

Now if you have a lot of messages, the above code could be running for a while, and it may not be very useful. To get something a bit more meaningful, we can examine the way messages are stored on iOS. There are lots of tables, here are a few of them (I haven't written all the fields, just some of the useful ones):

Table NameFields
messageROWID, guid, text, service_center, subject, date_read, date_delivered,...many more
chatROWID, guid, account_id, account_login, display_name,...more
attachmentROWID, guid, created_date, filename, mime_type, is_outgoing, user_info,...more

These ones are only really used to join tables:

Table NameFields
chat_handle_joinchat_id, handle_id
chat_message_joinchat_id, message_id
message_attachment_joinmessage_id, attachment_id

So there is a lot of information available, you will most likely want to select just a few relevant bits and join your own tables to present the data how you wish.