IDA отладка ядра Android - поиск адреса check_flags () - PullRequest
0 голосов
/ 10 ноября 2019

Новичок в IDA, не уверен, что то, что я вижу, является правильным или неправильным.

Загруженное изображение ядра zImage с моего телефона (aarch64, Samsung S7 Edge). Загруженные kallsyms, добавленные в IDA

Хотите использовать адрес ptmx_fops и перезаписать check_flags, получить смещение check_flags путем обращения к syscall fcntl

Попытка найти смещение функции check_flags (), используемой здесь:

fs / fcntl.c

#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)

static int setfl(int fd, struct file * filp, unsigned long arg)
{
    struct inode * inode = file_inode(filp);
    int error = 0;

    /*
     * O_APPEND cannot be cleared if the file is marked as append-only
     * and the file is open for write.
     */
    if (((arg ^ filp->f_flags) & O_APPEND) && IS_APPEND(inode))
        return -EPERM;

    /* O_NOATIME can only be set by the owner or superuser */
    if ((arg & O_NOATIME) && !(filp->f_flags & O_NOATIME))
        if (!inode_owner_or_capable(inode))
            return -EPERM;

    /* required for strict SunOS emulation */
    if (O_NONBLOCK != O_NDELAY)
           if (arg & O_NDELAY)
           arg |= O_NONBLOCK;

    if (arg & O_DIRECT) {
        if (!filp->f_mapping || !filp->f_mapping->a_ops ||
            !filp->f_mapping->a_ops->direct_IO)
                return -EINVAL;
    }

    if (filp->f_op->check_flags)
        error = filp->f_op->check_flags(arg);
    if (error) 
        return error;

    /*
     * ->fasync() is responsible for setting the FASYNC bit.
     */
    if (((arg ^ filp->f_flags) & FASYNC) && filp->f_op->fasync) {
        error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);
        if (error < 0)
            goto out;
        if (error > 0)
            error = 0;
    }
    spin_lock(&filp->f_lock);
    filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
    spin_unlock(&filp->f_lock);

 out:
    return error;
}

Слышал, что:

Функция check_flags используется в setfl () из fcntl.c. Большую часть времени он встроен в sys_fcntl, поэтому вы можете найти этот адрес в kallsyms и найти его оттуда.

В IDA Однако я вижу это:

enter image description here

enter image description here

enter image description here

Вопросы:

  1. Какнайти смещение check_flags () здесь (в коде: if (filp->f_op->check_flags))? Какой подход использовать?
  2. Почему разборка указывает на секции unk_ *? Они указывают на местоположения DCB? Что это такое?
  3. Попытался сделать ярлык

Также есть исходный код ядра и попытался экспортировать

fs / btrfs / ioctl.c

static int check_flags(unsigned int flags)
{
    if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
              FS_NOATIME_FL | FS_NODUMP_FL | \
              FS_SYNC_FL | FS_DIRSYNC_FL | \
              FS_NOCOMP_FL | FS_COMPR_FL |
              FS_NOCOW_FL))
        return -EOPNOTSUPP;

    if ((flags & FS_NOCOMP_FL) && (flags & FS_COMPR_FL))
        return -EINVAL;

    return 0;
}

EXPORT_SYMBOL(check_flags);

Перекомпилировано, но символ отсутствует в vmlinux и System.map: /

Конфигурация ядра:

CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y

Есть идеи?

Может быть, это также поможет:

drivers / tty / pty.c

static struct file_operations ptmx_fops;

ptmx_fops.open = ptmx_open;

Любая идея, как определить смещение check_flags:

drivers / tty / pty.c

struct file_operations {
    struct module *owner;
    loff_t (*llseek) (struct file *, loff_t, int);
    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
    ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
    ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
    ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
    int (*iterate) (struct file *, struct dir_context *);
    unsigned int (*poll) (struct file *, struct poll_table_struct *);
    long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
    long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
    int (*mmap) (struct file *, struct vm_area_struct *);
    int (*open) (struct inode *, struct file *);
    int (*flush) (struct file *, fl_owner_t id);
    int (*release) (struct inode *, struct file *);
    int (*fsync) (struct file *, loff_t, loff_t, int datasync);
    int (*aio_fsync) (struct kiocb *, int datasync);
    int (*fasync) (int, struct file *, int);
    int (*lock) (struct file *, int, struct file_lock *);
    ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
    unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
    int (*check_flags)(int);
    int (*flock) (struct file *, int, struct file_lock *);
    ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
    ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
    int (*setlease)(struct file *, long, struct file_lock **, void **);
    long (*fallocate)(struct file *file, int mode, loff_t offset,
              loff_t len);
    int (*show_fdinfo)(struct seq_file *m, struct file *f);
    struct file* (*get_lower_file)(struct file *f);
};

Обновление 1:

статическая struct file_operations ptmx_fops;

ptmx_fops.open = ptmx_open;

Структура выглядит15 байтов

/usr/bin/aarch64-linux-gnu-nm -a --target elf64-littleaarch64 vmlinux| grep ptmx_fops
ffffffc00229aa00 b ptmx_fops
ffffffc00229aaf0 b ptmx_fops2

Здесь я экспортировал check_flags как статические в драйверах / tty / pty.c

/usr/bin/aarch64-linux-gnu-nm -a --target elf64-littleaarch64 vmlinux| grep check_flags
ffffffc0001aa098 t bad_file_check_flags
ffffffc0003ff854 t check_flags
ffffffc0001a0c04 T fiemap_check_flags
ffffffc00042416c t kbase_check_flags

Но я хочу использовать системный ..... Итак, как найти, какой байт является check_flags 15 байтов в структуре?

Обновление 2

Puuuuuh ... Я сделал это ... загрузил мой Custom Kernel вSamsung S7 Edge .... теперь я могу отладить его

Обновление 3

На самом деле мне удалось

https://github.com/marcinguy/CVE-2019-2215#update-5

...