Author: GeneBlue

0X01 前言

内核驱动是漏洞的高发区,了解Android驱动代码的编写是分析、利用驱动漏洞的基础。本文以一个“hello”驱动为例,简单介绍内核驱动编写、编译的基本过程,包括内核模块的内建编译和动态加载方式的编译。

0X02 编写

在 ./goldsifh/drivers 文件夹下新建hello目录,在hello目录中新建hello.c文件:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/miscdevice.h> MODULE_LICENSE("GPL");
MODULE_AUTHOR("GeneBlue");
MODULE_DESCRIPTION("Hello Kernel Device");
MODULE_VERSION("1.0"); #define CMD_COMMAND 0x1336 long hello_ioctl(struct file *filp, //ioctl函数
unsigned int cmd,
unsigned long arg){
switch(cmd){
case CMD_COMMAND:
printk("Hello Module hello_ioctl() exced");
break;
default:
printk("Hello Module unknown ioctl cmd");
}
return 0;
} struct file_operations hello_fops = { //设备的操作函数指针表
unlocked_ioctl: hello_ioctl
}; static struct miscdevice hello_device = { //注册为misc设备的基本属性
minor: MISC_DYNAMIC_MINOR,
name: "hello",
fops: &hello_fops,
mode: 777
}; static int __init hello_begin(void){
int ret;
ret = misc_register(&hello_device); //注册为misc设备
if(ret)
printk("Failed to register misc device");
else
printk("Hello Module successfully loaded"); return ret;
} static void __exit hello_exit(void){
int ret = misc_deregister(&hello_device); //设备卸载
if(ret)
printk("Hello module exit");
} module_init(hello_begin); //模块初始化函数
module_exit(hello_exit); //模块卸载函数

写驱动模块时都要包含
module.h 头文件,该头文件定义了一些编写模块时常用宏或函数;  kernel.h
提供常用的内核函数,如printk(); fs.h  提供文件表和文件结构,如file_operations;
miscdevice.h 提供注册为misc设备的常用函数。

0X03 编译

在编译之前,要确保下载下来的内核代码已经可以顺利地编译运行,具体可以参考这里

在hello目录中,要增加Makefile配置文件用于编译。在Makefile中添加:

obj-y +=  hello.o

表示内建编译,即直接编译到内核文件zImage中。然后在
goldfish/drivers/Makefile
中包含新建的驱动设备

obj-y += hello/

这样,再次编译内核后,驱动设备即可包含在内核中。

有的时候,我们需要在手机中编写可动态加载的驱动模块,可动态加载模块非常便于调试,在
kmsg中可直接看到调试信息,这个时候需要重新编译手机内核,开启内核的动态加载属性。在编译的内核的时候,使用

make menuconfig

命令,并在menuconfig中做如下配置:





如果不开启该选项就直接 insmod 加载hello.ko,一般情况下都会报如下错误:

insmod: init_module 'hello.ko' failed (Function not implemented)

[内建编译的情况]--编译完内核之后,还需要将内核拷贝到aosp的源码中,替换掉默认的内核文件,在我的Android源码中默认的内核文件存放在如下路径中:

/android-4.4.4_r1/device/lge/hammerhead-kernel/zImage-dtb

编译Android源码生成新的boot.img文件,然后只要将boot.img刷入到手机即可。

完成内核的准备工作之后,下面就要编译动态加载模块hello.ko,依然是上述的  hello.c  文件,在任意位置建一个目录,拷贝hello.c并编写  Makefile
 如下:

obj-m := hello.o  

KERNELDIR := /home/geneblue/Android/Source/kernel/msm/
PWD :=$(shell pwd)
ARCH=arm
CROSS_COMPILE=/home/geneblue/Android/Source/tsinghua_aosp/android-4.4.4_r1/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/arm-linux-androideabi-
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
CFLAGS_MODULE=-fno-pic modules:
make -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules
clean:
rm *.o *.ko *.mod.c *.order *.symvers

注意,Makefile中要加上  CFLAGS_MODULE=-fno-pic  选项,不然insmod加载编译好的  hello.ko relocation节
 会错误:

insmod: init_module 'hello.ko' failed (Exec format error)
kmsg:
<3>[ 1646.589131] hello: unknown relocation: 27

最后,使用  make
 命令即可编译生成正确的   hello.ko   文件。

0X04 运行

使用模拟器来加载新编好的内核,并在
adb shell  中,root权限下查看新编的驱动:

# root权限下
# ll /dev | grep hello # dmesg | grep Hello

这样,一个最简单的设备驱动已经可以正确运行了。

将 hello.ko 文件
push  到手机中,root权限下用
insmod 来加载即可。

# 加载内核模块
# insmod hello.ko # 查看加载的内核模块
# lsmod

0X05 参考


Android内核模块编译执行的更多相关文章

  1. Android反编译(三)之重签名

    Android反编译(三) 之重签名 [目录] 1.原理 2.工具与准备工作 3.操作步骤 4.装X技巧 5.问题 1.原理 1).APK签名的要点 a.所有的应用程序都必须有数字证书 ,Androi ...

  2. Android反编译(一)之反编译JAVA源码

    Android反编译(一) 之反编译JAVA源码 [目录] 1.工具 2.反编译步骤 3.实例 4.装X技巧 1.工具 1).dex反编译JAR工具  dex2jar   http://code.go ...

  3. Android 反编译

    Android 反编译 步骤:1.下载apktool 工具,这一步 主要是反编译 xml 文件. 步骤:2 把xx.smali 文件转为java 工具 (单个) 图形界面 下载dex2jar  和xj ...

  4. ApkDec android反编译工具

    转自:http://www.newasp.net/soft/70498.html 下载 ApkDec是一款免费的绿色APK反编译工具 forandroid ,由android开发者社区开发. ApkD ...

  5. Android 反编译工具简介

    Android 反编译工具: 所需工具:1 apktool : 用于获取资源文件 2 dex2Jar : 用于将classes.dex转化成jar文件 2 jd-gui: 将jar文件转化成java文 ...

  6. android 单独编译某个模块

    第一次下载好Android源代码工程后,我们通常是在Android源代码工程目录下执行make命令,经过漫长的等待之后,就可以得到Android系统镜像system.img了.以后如果我们修改了And ...

  7. 【转】Android源代码编译命令m/mm/mmm/make分析--不错

    原文网址:http://blog.csdn.net/luoshengyang/article/details/19023609 在前文中,我们分析了Android编译环境的初始化过程.Android编 ...

  8. android的编译和运行过程深入分析

    android的编译和运行过程深入分析 作者: 字体:[增加 减小] 类型:转载 首先来看一下使用Java语言编写的Android应用程序从源码到安装包的整个过程,此过程对了解android的编译和运 ...

  9. Android 自动编译、打包生成apk文件 3 - 使用SDK Ant方式

      相关文章列表: < Android 自动编译.打包生成apk文件 1 - 命令行方式> < Android 自动编译.打包生成apk文件 2 - 使用原生Ant方式> &l ...

随机推荐

  1. Mybatis系列全解(二):Mybatis简介与环境搭建

    封面:洛小汐 作者:潘潘 Mybatis 是一套持久层框架,灵活易用,特别流行. 前言 Mybatis系列全解,我们预计准备10+篇文章,让我们了解到 Mybatis 的基本全貌,真正从入门到上手,从 ...

  2. Tomcat8弱口令+后台getshell

    漏洞原因 用户权限在conf/tomcat-users.xml文件中配置: <?xml version="1.0" encoding="UTF-8"?&g ...

  3. 解决.NET Core Ajax请求后台传送参数过大请求失败问题

    解决.NET Core Ajax请求后台传送参数过大请求失败问题 今天在项目上遇到一个坑, 在.Net Core中通过ajax向mvc的controller传递对象时,控制器(controller)的 ...

  4. FreeBSD WIFI 配置详细介绍

    首先运行ifconfig,看看能不能找到你的网卡,如果能,那么你可以走了﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉运行sysctl net.wlan.devices,他可以告诉你,找到的无线网卡编辑/b ...

  5. 选择 FreeBSD 而不是 Linux 的技术性原因2

    ZFSZFS 文件系统是 FreeBSD 上的一等公民.这不仅意味着可以在 ZFS 上安装根目录,安装程序也支持这一点,而且还意味着很多基础系统工具都已经紧密地集成或构建了对 ZFS 的支持.在 Fr ...

  6. 使用css3和javascript开发web拾色器实例

    本实例中的web拾色器功能使用css3实现页面效果,即在页面上显示的元素用css3样式来实现的.再使用js生成拾色器颜色数据,并控制各元素的鼠标事件.当事件作为反应时,获取到对应的数据并显示颜色值. ...

  7. 【odoo14】第五章、服务器侧开发-基础

    本章包含如下内容: 定义模型方法和使用api装饰器 向用户反馈错误信息 针对不同的对象获取空数据集 创建新纪录 更新数据集数据 搜索数据 组合数据集 过滤数据集 遍历记录集 排序数据集 重写已有业务逻 ...

  8. MySQL入门(2)——存储引擎

    MySQL入门(2)--存储引擎 查询MySQL支持的存储引擎 查询全部支持的引擎: show engines; ";"可以使用"\g"等价替换,而使用&quo ...

  9. 15款NOSQL数据库

    1.MongoDB 介绍 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.主要解决的是海量数据的访问效率问题,为WEB应用提供可扩展的高性能数据存储解决方案.当数据量达到50GB以上 ...

  10. MySQL按天备份二进制日志

    #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:guozhen.zhang     import MySQLdbimport timeimp ...