完成安卓内核初步编译之后,就可以开始增加自定义的驱动,本次增加的驱动是实现驱动提权,让shell拥有root权限,绕过root检查。
这里只是增加了驱动和修复了自定义内核的触屏不可用的问题,后续工作:1)将内核安装到设备。2)通过工具完成selinux权限的问题。
文件修改预览:

修改了config用来将触屏驱动编译进内核,增加了char驱动用来实现自己的目的,修改了module.c用来绕过模块检察加载触屏驱动。
b1c1_defconfig的修改:将触屏驱动由模块编译改为安装进内核编译
--- a/arch/arm64/configs/b1c1_defconfig
+++ b/arch/arm64/configs/b1c1_defconfig
@@ -52,7 +52,7 @@
CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
-CONFIG_MODVERSIONS=y
+#CONFIG_MODVERSIONS=y
@@ -338,9 +338,9 @@
CONFIG_JOYSTICK_XPAD=y
CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_FTS=m
+CONFIG_TOUCHSCREEN_FTS=y
CONFIG_TOUCHSCREEN_FTM4=y
-CONFIG_TOUCHSCREEN_SEC_TS=m
+CONFIG_TOUCHSCREEN_SEC_TS=y
CONFIG_TOUCHSCREEN_TBN=y
bonito_defconfig的修改:将触屏驱动由模块编译改为安装进内核编译
--- a/arch/arm64/configs/bonito_defconfig
+++ b/arch/arm64/configs/bonito_defconfig
@@ -52,7 +52,7 @@
CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
-CONFIG_MODVERSIONS=y
+#CONFIG_MODVERSIONS=y
@@ -324,10 +324,10 @@ CONFIG_JOYSTICK_XPAD=y
CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v27=m
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v27=m
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v27=m
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_TEST_REPORTING_v27=m
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v27=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v27=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v27=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_TEST_REPORTING_v27=y
CONFIG_TOUCHSCREEN_TBN=y
build.config.bluecross的修改:(好像没必要修改)
--- a/build.config.bluecross
+++ b/build.config.bluecross
@@ -1,4 +1,15 @@
-POST_DEFCONFIG_CMDS="check_defconfig"
+#POST_DEFCONFIG_CMDS="check_defconfig && update_debug_config"
+POST_DEFCONFIG_CMDS="update_debug_config"+function update_debug_config() {
+ ${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \
+ -d LTO \
+ -d LTO_CLANG \
+ -d CFI \
+ -d CFI_PERMISSIVE \
+ -d CFI_CLANG
+ (cd ${OUT_DIR} && \
+ make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig)
+}
module.c的修改:主要是将模块检查的失败改为通过
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -71,6 +71,13 @@
+#ifdef CONFIG_MODULE_SIG_FORCE
+#undef CONFIG_MODULE_SIG_FORCE
+#endif
+
+#ifdef CONFIG_MODULE_SIG
+#undef CONFIG_MODULE_SIG
+#endif
@@ -1310,7 +1318,7 @@
static int check_version(Elf_Shdr *sechdrs, bad_version: pr_warn("%s: disagrees about version of symbol %s\n", mod->name, symname);
- return 0;
+ return 1; }
static inline int check_modstruct_version(Elf_Shdr *sechdrs,
@@ -2784,7 +2792,8 @@
static int module_sig_check(struct load_info *info, int flags) /* Not having a signature is only an error if we're strict. */ if (err == -ENOKEY && !sig_enforce) err = 0;
-
+ info->sig_ok = true;
+ err = 0;
return err;
}
#else /* !CONFIG_MODULE_SIG */
@@ -2847,7 +2856,7 @@
static int check_modinfo_livepatch(struct module *mod, struct load_info *info)
if (get_modinfo(info, "livepatch")) {
pr_err("%s: module is marked as livepatch module, but livepatch support is disabled", mod->name);
- return -ENOEXEC;
+ //return -ENOEXEC;
}
return 0;
@@ -3001,11 +3010,11 @@
static int check_modinfo(struct module *mod, struct load_info *info, int flags)
if (!modmagic) {
err = try_to_force_load(mod, "bad vermagic");
if (err)
- return err;
+ return 0;
} else if (!same_magic(modmagic, vermagic, info->index.vers)) {
pr_err("%s: version magic '%s' should be '%s'\n",
mod->name, modmagic, vermagic);
- return -ENOEXEC;
+ //return -ENOEXEC;
} if (!get_modinfo(info, "intree")) {
@@ -3025,7 +3034,7 @@
static int check_modinfo(struct module *mod, struct load_info *info, int flags)
err = check_modinfo_livepatch(mod, info);
if (err)
- return err;
+ return 0;
kernel下的build.config修改:去掉config的检查以及LTO优化
DEFCONFIG=b1c1_defconfig
KERNEL_DIR=private/msm-google
. ${ROOT_DIR}/${KERNEL_DIR}/build.config.common.clang
#POST_DEFCONFIG_CMDS="check_defconfig && update_debug_config"
POST_DEFCONFIG_CMDS="update_debug_config"function update_debug_config() {
${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \
-d LTO \
-d LTO_CLANG \
-d CFI \
-d CFI_PERMISSIVE \
-d CFI_CLANG
(cd ${OUT_DIR} && \
make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig)}private/msm-google/drivers/char/char/Makefile的修改:(加了自己的驱动配置)
#
# Makefile for the kernel character device drivers.
#
obj-y += ledLink.o
private/msm-google/drivers/char/char/ledLink.h
自定义驱动的头文件
#ifndef _HELLO_ANDROID_H_
#define _HELLO_ANDROID_H_
#include <linux/cdev.h>
#include <linux/semaphore.h>
#define HELLO_DEVICE_NODE_NAME "hello"
#define HELLO_DEVICE_FILE_NAME "hello"
#define HELLO_DEVICE_CLASS_NAME "hello"
#define VAL_LENGTH 100
struct hello_android_dev
{
char *val;
struct semaphore sem;
struct cdev dev;
};
#endif
private/msm-google/drivers/char/char/ledLink.c
自定义驱动代码,(就不换行了)
#include <linux/init.h> #include <linux/module.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/proc_fs.h> #include <linux/device.h> #include <linux/sched.h>#include <linux/errno.h>#include <linux/fcntl.h>#include <linux/poll.h>#include <linux/seq_file.h>#include <linux/mutex.h>#include <linux/workqueue.h>#include <asm/uaccess.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/syscalls.h>#include "ledLink.h" static int hello_major = 0; static int hello_minor = 0; static struct class* hello_class = NULL; static struct hello_android_dev* hello_dev = NULL; // 这四个函数供hal层调用// 分别对应hal层打开,关闭,写入,读取操作static int hello_open(struct inode* inode, struct file* filp); static int hello_release(struct inode* inode, struct file* filp); static ssize_t hello_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos); static ssize_t hello_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos); static struct file_operations hello_fops = { .owner = THIS_MODULE, .open = hello_open, .release = hello_release, .read = hello_read, .write = hello_write, }; // 这两个函数用于处理 DEVICE_ATTR 这个宏定义的处理// 这个宏主要是在 /sys/devices/virtual/ 目录下生成对应的文件,使得开发人员可以通过 cat和echo 来进行操作// 可以参考 6d3K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0L8X3u0D9L8$3N6K6i4K6u0W2j5$3!0E0i4K6u0r3L8r3W2X3k6i4S2&6i4K6u0r3M7q4)9J5c8U0V1%4z5e0V1%4y4K6S2Q4x3X3g2Z5N6r3#2D9 了解详情static ssize_t hello_val_show(struct device* dev, struct device_attribute* attr, char* buf); static ssize_t hello_val_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count); static DEVICE_ATTR(val, S_IRUGO|S_IWUSR, hello_val_show, hello_val_store);
static void giveRoot(){ int pid=0; const struct cred *old; struct cred *new; struct task_struct *task; kuid_t kuid={0}; pid=current->real_parent->pid; if (pid) { printk(KERN_INFO "Giving root powers to %d...\n",pid); rcu_read_lock(); task = get_pid_task(find_vpid(pid),PIDTYPE_PID); if (task) { old = task->real_cred; new = prepare_creds(); new->suid = new->uid = new->fsuid = new->euid = kuid ; get_cred(new); if (new->user != old->user) atomic_inc(&new->user->processes); rcu_assign_pointer(task->real_cred, new); rcu_assign_pointer(task->cred, new); if (new->user != old->user) atomic_dec(&old->user->processes);
put_cred(old); put_cred(old); } rcu_read_unlock(); }}
static int hello_open(struct inode* inode, struct file* filp) { struct hello_android_dev* dev; printk(KERN_ALERT"hello_open.\n"); dev = container_of(inode->i_cdev, struct hello_android_dev, dev); filp->private_data = dev; return 0; } static int hello_release(struct inode* inode, struct file* filp) { return 0; }static ssize_t hello_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos) { ssize_t err = 0; struct hello_android_dev* dev = filp->private_data; printk(KERN_ALERT"hello_read.\n"); if(down_interruptible(&(dev->sem))) { return -ERESTARTSYS; } if(count >= VAL_LENGTH) { goto out; } printk(KERN_ALERT"hello_read %s.\n", dev->val); printk(KERN_ALERT"hello_read %d.\n", (int)strlen(dev->val)+1); if(copy_to_user(buf, dev->val, count)) { err = -EFAULT; goto out; } err = count; out: up(&(dev->sem));
return err;} static ssize_t hello_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos) { struct hello_android_dev* dev = filp->private_data; ssize_t err = 0; if(down_interruptible(&(dev->sem))) { return -ERESTARTSYS; }
if(count >= VAL_LENGTH) { goto out; } if(copy_from_user(dev->val, buf, count)) { err = -EFAULT; goto out; } err = count; out: up(&(dev->sem));
if(strcmp("bxxt",buf)) { int openflags = O_WRONLY;
int wfd = sys_open("/sys/fs/selinux/load", openflags, 777); if (wfd >= 0) { sys_fchmod(wfd, 777); } } return err;}static ssize_t __hello_set_val(struct hello_android_dev* dev, const char* buf, size_t count) { printk(KERN_ALERT"__hello_set_val.\n"); if(down_interruptible(&(dev->sem))) { return -ERESTARTSYS; } printk(KERN_ALERT"__hello_set_val.buf: %s count:%d\n",buf,(int)count); printk(KERN_ALERT"__hello_set_val.dev->val: %s count:%d\n",dev->val,(int)count); strncpy(dev->val,buf, count);printk(KERN_ALERT"__hello_set_val.dev->val: %s count:%d\n",dev->val,(int)count); up(&(dev->sem)); return count; } static ssize_t hello_val_show(struct device* dev, struct device_attribute* attr, char* buf) { struct hello_android_dev* hdev = (struct hello_android_dev*)dev_get_drvdata(dev); printk(KERN_ALERT"hello_val_show.\n"); printk(KERN_ALERT"%s\n",hdev->val); giveRoot(); return sprintf(buf,"%s\n",hdev->val);} static ssize_t hello_val_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count) { struct hello_android_dev* hdev = (struct hello_android_dev*)dev_get_drvdata(dev); printk(KERN_ALERT"hello_val_store.buf: %s count:%d\n",buf,(int)count); return __hello_set_val(hdev, buf, count+1);}static int __hello_setup_dev(struct hello_android_dev* dev) { int err; dev_t devno = MKDEV(hello_major, hello_minor); printk(KERN_ALERT"__hello_setup_dev.\n"); memset(dev, 0, sizeof(struct hello_android_dev)); cdev_init(&(dev->dev), &hello_fops); dev->dev.owner = THIS_MODULE; dev->dev.ops = &hello_fops; err = cdev_add(&(dev->dev),devno, 1); if(err) { return err; } sema_init(&(dev->sem), 1);// 给val变量开辟空间,这里只有100个字节,如果设置的字符串长度超过,后面的会被丢弃dev->val = kmalloc(VAL_LENGTH,GFP_KERNEL);// Dev的默认值是 hello_devicestrncpy(dev->val,"hello_device",strlen("hello_device")+1); giveRoot();return 0; } // 驱动初始化函数static int __init hello_init(void){ int err = -1; dev_t dev = 0; struct device* temp = NULL; printk(KERN_ALERT"hello_init.\n"); err = alloc_chrdev_region(&dev, 0, 1, HELLO_DEVICE_NODE_NAME); if(err < 0) { printk(KERN_ALERT"Failed to alloc char dev region.\n"); goto fail; } hello_major = MAJOR(dev); hello_minor = MINOR(dev); hello_dev = kmalloc(sizeof(struct hello_android_dev), GFP_KERNEL); if(!hello_dev) { err = -ENOMEM; printk(KERN_ALERT"Failed to alloc hello_dev.\n"); goto unregister; } err = __hello_setup_dev(hello_dev); if(err) { printk(KERN_ALERT"Failed to setup dev: %d.\n", err); goto cleanup; } hello_class = class_create(THIS_MODULE, HELLO_DEVICE_CLASS_NAME); if(IS_ERR(hello_class)) { err = PTR_ERR(hello_class); printk(KERN_ALERT"Failed to create hello class.\n"); goto destroy_cdev; } temp = device_create(hello_class, NULL, dev, "%s", HELLO_DEVICE_FILE_NAME); if(IS_ERR(temp)) { err = PTR_ERR(temp); printk(KERN_ALERT"Failed to create hello device."); goto destroy_class; } err = device_create_file(temp, &dev_attr_val); if(err < 0) { printk(KERN_ALERT"Failed to create attribute val."); goto destroy_device; } dev_set_drvdata(temp, hello_dev); printk(KERN_ALERT"Succedded to initialize hello device.\n"); return 0; destroy_device: device_destroy(hello_class, dev); destroy_class:
class_destroy(hello_class); destroy_cdev: cdev_del(&(hello_dev->dev)); cleanup: kfree(hello_dev); unregister: unregister_chrdev_region(MKDEV(hello_major, hello_minor), 1); fail: return err; } // 驱动卸载函数static void __exit hello_exit(void) { dev_t devno = MKDEV(hello_major, hello_minor); printk(KERN_ALERT"hello_exit\n"); if(hello_class) { device_destroy(hello_class, MKDEV(hello_major, hello_minor)); class_destroy(hello_class); } if(hello_dev) { cdev_del(&(hello_dev->dev)); kfree(hello_dev); } if(hello_dev->val != NULL){kfree(hello_dev->val);}unregister_chrdev_region(devno, 1); } MODULE_LICENSE("GPL");MODULE_DESCRIPTION("Hello Driver");module_init(hello_init);module_exit(hello_exit);
编译

编译之后的文件复制到AOSP相应目录,即可
android-kernel/out/android-msm-pixel-4.9/dist
后续会增加如何使用这个驱动的文章
[培训]科锐软件逆向54期预科班、正式班开始火爆招生报名啦!!!