iPhone: Vital Database(s) Exposed!!!
Author: bughira | Filed under: General Talks, Information Security, iPhoneYeah, you guessed it right. Apple iPhone uses some database(everyone has to) in backend to store all its vital information like -
1) Call History
2) Address Book
3) SMS (Text Messages)
4) Notes
5) VoiceMails
6) Calendar Events.
And the database is SQLite:the most widely deployed SQL database engine in the world.
No userName/Password security applied to the any of the above mentioned databases. This means anyone has access to above databases from anywhere like – iTunes backup folder or by any other hacky way, can breach into users privacy. Want to know how? Read on…
I got emails asking can we read CallHistory from iPhone and how to read those files. So this blog is dedicated to all of them.
======================
Bit Theory: Definitely not Crap.
======================
SQLite database has exposed C/C++ API’s that can be used to connect to DB files and execute queries on it. Official Website of SQLite has decent documentation of the API’s.
For basic database operations, we need only few API’s and here is brief about them.
1) int sqlite3_open(
const char *filename, /* Database filename (UTF-8 ) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
This API opens connection to SQLite Database file and returns a database connection object. This is the first step for any SQLite based application.
2) int sqlite3_prepare(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
This API converts SQL text into a prepared statement object and return a pointer to that object. This interface requires a database connection pointer created by a prior call to sqlite3_open() and a text string containing the SQL statement to be prepared.
3) int sqlite3_step(sqlite3_stmt*);
This API is used to evaluate a prepared statement that has been previously created by the sqlite3_prepare() interface. The statement is evaluated up to the point where the first row of results are available. To advance to the second row of results, invoke sqlite3_step() again. Continue invoking sqlite3_step() until the statement is complete. Statements that do not return results (ex: INSERT, UPDATE, or DELETE statements) run to completion on a single call to sqlite3_step().
4) int sqlite3_finalize(sqlite3_stmt *pStmt);
This API destroys a prepared statement created by a prior call to sqlite3_prepare(). Every prepared statement must be destroyed using a call to this routine in order to avoid memory leaks.
5) int sqlite3_close(sqlite3 *);
This routine closes a database connection previously opened by a call to sqlite3_open(). All prepared statements associated with the connection should be finalized prior to closing the connection.
The API sqlite3_exec() interface is a convenience wrapper that carries out all four of the above API’s with a single function call. A callback function passed into sqlite3_exec() is used to process each row of the result set.
6) int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluted */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
The 3rd parameter is an optional callback that is invoked once for each row of any query results produced by the SQL statements. You need to handle all printing and displaying of fetched data in the callback function.
The return value SQLITE_OK of sqlite3_exec() indicated all SQL statements run successfully while non-zero return value indicates the other side of execution.
Please visit here for detailed information of other API’s.
Comming back to iPhone and different DB’s used by it, we can always retrieve all the information from them. You just need to put all above API’s in C syntax and done.
====================================
Apple iPhone CallHistory Database:
====================================
DB Name: call_history.db
Important Table: Call
Schema: CREATE TABLE call(ROWID INTEGER PRIMARY KEY AUTOINCREMENT, address TEXT, data INTEGER, duration INTEGER, flags INTEGER, id INTEGER)
Important Columns from table Call: Address, Date, Duration, ID ( This can be used to query out Caller ID information from AddressBook Database.)
I have written some small tools that can give you all Address Book information from command line.
Here is the snip of output of my tool.
[bughira@toolchain sqlite_progs]$ ./get_address_book DB/AddressBook.sqlitedb
———- GetMe_iPhone_AddressBook ———-
Author: Bughira (bughira@gmail.com)
http://bughira.wordpress.com
———————————————-
[+] Trying to Fetch the contacts from AddressBook.
[+] Done!! AddressBook.txt file should have all the fetched contacts.
[bughira@toolchain sqlite_progs]$ tail AddressBook.txt
First = Bill
Last = Gates
value = +1 (214) 269-2813
First = Linus
Last = Torvalds
value = +1 (647) 469-2869
First = Richard
Last = Stallman
value = +1 (407) 834-1891
<Rest of the output is cut for brevity>
I have a demo of this in coming week, I’ll upload the code of my tool once I am done with it.
For all those lazy bumps who don’t want to code and all desperadoes who can’t wait that long, A GUI based SQLite browser is available. You can always use it and fire queries on the database and perform database manipulations. You can download SQLiteBrowser here.
Happy Hacking…
Tags: call history, iPhone SMS, iPhone SQLite DB

August 2nd, 2008 at 10:43 pm
Thanks for the post
September 17th, 2008 at 8:47 pm
Hi,
do you have any idea, how we have to fill up the fields LastSort, FirstSort, FirstSortSection and LastSortSection of ABPerson? I check to leave it empty, in this case the contact app on the iPhone crashes
This fields seams to be (somehow) in relation to the Tables ABPersonSearch, FirstSortSectionCount and LastSortSectionCount
Regards
horchi
December 30th, 2008 at 7:55 am
hello
i have a problem i have accessed the call table from call_Histor.db now i have to perform some delete operation on call table how can i do that.I have done the code for that but unable to delete data from table outside application document folder.
Regards
tarun sharma
January 7th, 2009 at 6:15 am
Though i have not tried deleting enteris from ne of the tables… i think u should first check the permissions and if possible try to do chdir() to application document directory and run your deletion code after that..
January 7th, 2009 at 6:17 am
@Horchi…
As per my information, these fields are reserved for future enhancements in upcoming firmware versions…
February 4th, 2009 at 9:54 am
I searched for call_history.db in iphone, but i cant get it, please tell me the path, where is it located?
February 4th, 2009 at 11:01 am
hey,
Its located in /private/var/mobile/Library/CallHistory/call_history.db in 1.1.4 Firmware.
I am not sure what is its location on latest one…
February 4th, 2009 at 11:31 am
Thanks, I am having one more doubt, can we find the current foreground and background running process and application? I searched a lot, but cant find solution, can you help me?
February 4th, 2009 at 11:54 am
Theres already tool written by Robota software called iPhone System Information.
This tool will show you all the system specific information for iPhone like No of Running processes, Memory etc. You can choose to Kill, chance Priority of the processes by sending them signals and more.. Google to know more..
February 4th, 2009 at 12:08 pm
Thanks for your kind information
March 15th, 2009 at 8:46 am
Does the phone need to be jailbroken for the SQLite APIs to access to the databases?
March 15th, 2009 at 12:19 pm
Yes, indeed…
September 29th, 2009 at 12:44 pm
Hi……Good article.
plz tel me how you access call_history.db on iphone device programmatically
Plz help me thanks
September 29th, 2009 at 9:57 pm
alpana,
This is just an sqlite database, you can use libsqlite on linux and access the database. Let me know if you need anything else..
all the best
September 30th, 2009 at 10:12 am
Thanks for Your Response
i want to create an application for iphone device that access /var/mobile/Library/CallHistory/call_history.db database.But i am unable to access above database Through my application.
Any solution
Thanks
October 5th, 2009 at 5:34 pm
Mitali,
Like i commented before write application using libsqlite. There are pretty simple API’s like sqlite3_open(), sqlite3_exec() etc to perform operations on the DB.
Visit documentation from sqlite.org for more information.
November 29th, 2009 at 10:48 pm
The problem is .. we cant access Call_history.db by sqlite3_open().
Is there any solution?
November 30th, 2009 at 10:34 pm
@shikhar: I vl check with my iphone and update you soon..
December 2nd, 2009 at 11:01 pm
Bughira – thanks for posting this information. When we try to do the same, we get a no access error. I believe that the database is sandboxed on the iPhone and other apps are not allowed to access it – even on jailbroken iPhones. Have you been able to do this in an iPhone app? We can easily do this when connecting the phone to the computer. Your help will be sincerely appreciated!