Question

I used Cydia Substrate to hook a set of C file IO functions: open, read, write, pread, pwrite, lseek... I found that sqlite3 implementation in iOS 4 and 5 does actually call open function to get a file descriptor from the db file. The file descriptor is then used to read/write the db when it is queried/updated.

However when I do the same test with iOS 6, I found that open (and other functions: close, fstat) didn't get call. I'm very sure that my function hook works because I saw open/close/fstat got called in other places.

The following log is printed when I do test with iOS 6:

ssize_t pread_vg(int, void *, size_t, off_t) fildes=9 nbyte=100 offset = 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=512 offset = 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=10 nbyte=8 offset = 512
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=12 offset = 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=9 nbyte=4096 offset = 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=9 nbyte=4096 offset = 4096
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=9 nbyte=4096 offset = 8192
 Success create table
ssize_t pread_vg(int, void *, size_t, off_t) fildes=9 nbyte=100 offset = 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=9 nbyte=4096 offset = 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=9 nbyte=16 offset = 24
ssize_t pread_vg(int, void *, size_t, off_t) fildes=9 nbyte=4096 offset = 8192
ssize_t pread_vg(int, void *, size_t, off_t) fildes=9 nbyte=4096 offset = 4096
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=512 offset = 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=4 offset = 512
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=4096 offset = 516
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=4 offset = 4612
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=4 offset = 4616
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=4096 offset = 4620
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=4 offset = 8716
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=4 offset = 8720
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=4096 offset = 8724
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=4 offset = 12820
ssize_t pread_vg(int, void *, size_t, off_t) fildes=10 nbyte=8 offset = 13312
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=10 nbyte=12 offset = 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=9 nbyte=4096 offset = 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=9 nbyte=4096 offset = 4096
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=9 nbyte=4096 offset = 8192
 Contact added
ssize_t pread_vg(int, void *, size_t, off_t) fildes=9 nbyte=100 offset = 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=9 nbyte=4096 offset = 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=9 nbyte=16 offset = 24
ssize_t pread_vg(int, void *, size_t, off_t) fildes=9 nbyte=4096 offset = 4096
 Match found: Sandiago 9939182

Below is same code, but run on iOS 5:

int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents/contacts oflag=514
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents/contacts oflag=514 --> 6
int fstat_vg(int, struct stat *) fd=6 --> 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=100 offset = 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=100 offset = 0 --> 0
int fstat_vg(int, struct stat *) fd=6 --> 0
int fstat_vg(int, struct stat *) fd=6 --> 0
int fstat_vg(int, struct stat *) fd=6 --> 0
int fstat_vg(int, struct stat *) fd=6 --> 0
int fstat_vg(int, struct stat *) fd=6 --> 0
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents/contacts-journal oflag=514
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents/contacts-journal oflag=514 --> 7
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents oflag=0
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents oflag=0 --> 8
int open_vg(const char *, int, ...) path=/dev/urandom oflag=0
int open_vg(const char *, int, ...) path=/dev/urandom oflag=0 --> 9
ssize_t read_vg(int, void *, size_t) fildes=9 nbyte=256 --> 256
int close_vg(int) fildes=9 --> 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=512 offset = 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=512 offset = 0 --> 512
ssize_t pread_vg(int, void *, size_t, off_t) fildes=7 nbyte=8 offset = 512
ssize_t pread_vg(int, void *, size_t, off_t) fildes=7 nbyte=8 offset = 512 --> 0
int close_vg(int) fildes=8 --> 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=12 offset = 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=12 offset = 0 --> 12
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 0 --> 4096
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 4096
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 4096 --> 4096
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 8192
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 8192 --> 4096
int close_vg(int) fildes=7 --> 0
Success create table
int close_vg(int) fildes=6 --> 0
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents/contacts oflag=514
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents/contacts oflag=514 --> 6
int fstat_vg(int, struct stat *) fd=6 --> 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=100 offset = 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=100 offset = 0 --> 100
int fstat_vg(int, struct stat *) fd=6 --> 0
int fstat_vg(int, struct stat *) fd=6 --> 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 0 --> 4096
int fstat_vg(int, struct stat *) fd=6 --> 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=16 offset = 24
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=16 offset = 24 --> 16
int fstat_vg(int, struct stat *) fd=6 --> 0
int fstat_vg(int, struct stat *) fd=6 --> 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 8192
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 8192 --> 4096
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 4096
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 4096 --> 4096
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents/contacts-journal oflag=514
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents/contacts-journal oflag=514 --> 7
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents oflag=0
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents oflag=0 --> 8
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=512 offset = 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=512 offset = 0 --> 512
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4 offset = 512
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4 offset = 512 --> 4
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4096 offset = 516
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4096 offset = 516 --> 4096
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4 offset = 4612
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4 offset = 4612 --> 4
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4 offset = 4616
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4 offset = 4616 --> 4
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4096 offset = 4620
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4096 offset = 4620 --> 4096
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4 offset = 8716
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4 offset = 8716 --> 4
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4 offset = 8720
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4 offset = 8720 --> 4
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4096 offset = 8724
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4096 offset = 8724 --> 4096
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4 offset = 12820
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=4 offset = 12820 --> 4
ssize_t pread_vg(int, void *, size_t, off_t) fildes=7 nbyte=8 offset = 13312
ssize_t pread_vg(int, void *, size_t, off_t) fildes=7 nbyte=8 offset = 13312 --> 0
int close_vg(int) fildes=8 --> 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=12 offset = 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=7 nbyte=12 offset = 0 --> 12
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 0
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 0 --> 4096
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 4096
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 4096 --> 4096
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 8192
ssize_t pwrite_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 8192 --> 4096
int close_vg(int) fildes=7 --> 0
Contact added
int close_vg(int) fildes=6 --> 0
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents/contacts oflag=514
int open_vg(const char *, int, ...) path=/var/mobile/Applications/B5E571B3-9119-416E-8132-954EB3AE2F05/Documents/contacts oflag=514 --> 6
int fstat_vg(int, struct stat *) fd=6 --> 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=100 offset = 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=100 offset = 0 --> 100
int fstat_vg(int, struct stat *) fd=6 --> 0
int fstat_vg(int, struct stat *) fd=6 --> 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 0 --> 4096
int fstat_vg(int, struct stat *) fd=6 --> 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=16 offset = 24
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=16 offset = 24 --> 16
int fstat_vg(int, struct stat *) fd=6 --> 0
int fstat_vg(int, struct stat *) fd=6 --> 0
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 4096
ssize_t pread_vg(int, void *, size_t, off_t) fildes=6 nbyte=4096 offset = 4096 --> 4096
Match found: Bukit Merah View 84049398
int close_vg(int) fildes=6 --> 0

It's very obvious that it call pread/pwrite on 2 file descriptors 9 and 10 (which I think is the db and the db-journal file). How did it get the file descriptor without calling open?

Était-ce utile?

La solution

I tried looking into libsqlite3.dylib, there is no open function in imported symbol list, but instead there was guarded_open_np. I suspect that in iOS 4 and iOS 5, guarded_open_np is built using open. In iOS 6, it may be implemented without using open any more.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top