我使用 Cydia Substrate 来挂钩一组 C 文件 IO 函数:open、read、write、pread、pwrite、lseek... 我发现 iOS 4 和 5 中的 sqlite3 实现实际上确实调用open
函数来从 db 获取文件描述符文件。然后文件描述符在查询/更新时用于读取/写入数据库。
但是,当我对 iOS 6 进行相同的测试时,我发现open
(和其他函数:close、fstat)没有被调用。我很确定我的函数挂钩可以工作,因为我看到 open/close/fstat 在其他地方被调用。
当我使用 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
下面是相同的代码,但在 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
很明显,它在 2 个文件描述符 9 和 10(我认为是 db 和 db-journal 文件)上调用了 pread/pwrite。它是如何在不调用 open 的情况下获取文件描述符的?