很久前就想了解驱动程序的想法,这里现做一个简单的开始,从demo做起,看到Android驱动程序的基本运行流程,这对漏洞分析、检测和挖掘都是必要的。同样,本篇基本也是自己学习过程的记录,无干货。本篇大多数内容来自Linux设备驱动之Ioctl控制。
一、用户层
不管是漏洞检测,还是poc中,我们见到最多的函数就是ioctl()函数,这个函数就是用户层调用内核程序的接口。
/*
fd:文件描述符
cmd:控制命令
...:可选参数:插入*argp,具体内容依赖于cmd
*/
int ioctl(int fd,unsigned long cmd,...);
函数第一个参数文件句柄,可以通过open()获得,第二个参数是指令的值,和驱动程序里的switch()里的case值是对应的,第三个是可选参数,通常是一个指针,指向某个变量或者结构体。函数执行成功,返回0,出错返回-1。
下面来看一个用户层demo程序(代码取自Linux设备驱动之Ioctl控制,如有冒犯请联系删除),和后面驱动程序是对应的,首先定义头文件。
#ifndef _MEMDEV_H_
#define _MEMDEV_H_
#include <linux/ioctl.h>
#ifndef MEMDEV_MAJOR
#define MEMDEV_MAJOR 0 /*预设的mem的主设备号*/
#endif
#ifndef MEMDEV_NR_DEVS
#define MEMDEV_NR_DEVS 2 /*设备数*/
#endif
/*mem设备描述结构体*/
struct mem_dev
{
char *data;
unsigned long size;
};
/* 定义幻数 */
#define MEMDEV_IOC_MAGIC 'k'
/* 定义命令 */
#define MEMDEV_IOCPRINT _IO(MEMDEV_IOC_MAGIC, 1)
#define MEMDEV_IOCGETDATA _IOR(MEMDEV_IOC_MAGIC, 2, int)
#define MEMDEV_IOCSETDATA _IOW(MEMDEV_IOC_MAGIC, 3, int)
#define MEMDEV_IOC_MAXNR 3
#endif /* _MEMDEV_H_ */
#ifndef MEMDEV_SIZE
#define MEMDEV_SIZE 4096
#endif
用户层代码:
#include <stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include "memdev.h" /* 包含命令定义 */
int main()
{
int fd = 0;
int cmd;
int arg = 0;
char Buf[4096];
/*打开设备文件*/
fd = open("/dev/memdev0",O_RDWR);
if (fd < 0)
{
printf("Open Dev Mem0 Error!\n");
return -1;
}
/* 调用命令MEMDEV_IOCPRINT */
printf("<--- Call MEMDEV_IOCPRINT --->\n");
cmd = MEMDEV_IOCPRINT;
if (ioctl(fd, cmd, &arg) < 0)
{
printf<