使用ioctl“实现”自定义的系统调用

最近做的项目跟Linux内核的关系比较大,我们的项目需要在用户态触发一些 内核态的代码运行。众所周知,内核态的代码是不能直接被用户态代码调用的, 用户态代码触发内核态代码的必须要经过系统调用。

为什么选择 ioctl

那么该如何实现我们的需求呢?有几种方法:

改写内核,扩大系统调用表,添加新的系统调用

利用内核模块,覆盖没被使用或这使用频率很低的一个系统调用的处理函数

利用已有的系统调用,比如ioctl,来“实现”自定义的系统调用。

第一种方法需要修改内核,适用面比较窄;第二种方法hack意味很浓,没有 被使用的系统调用号有限,不同模块可能都使用这种机制,可能会产生冲突。最 终我们选择了第三种方法。下面将一一道来。

ioctl系统调用是用户态控 制设备的接口,其用户态原型为

 

int ioctl(int d, int request, 

...)

 

第一个参数是打开的设备文件的文件描述符,通常是 open系统调用的返回值;第二个参数request是可以自定义的请求号;第三个参 数可以是一个指针,指向一段用户态内存,用来传递参数,也可以是一个整形数 据。函数原型中的'...'并非表示ioctl是可变参数函数,只是为了告诉 编译器不要检查第三个参数。

在较新内核中,ioctl的内核态原型为 unlock_ioctl

 

long unlocked_ioctl(struct file *file, 

unsigned int request, unsigned long arg);

 

这个原型可以 在struct file_operation的定义中找到,还有一个compat_ioctl,用于内核为 64位,用户空间为32位的情形,跟我们的需求关系不大。

传入的request 和arg就来自于ioctl系统调用的第二个和第三个参数。在内核态中,可以根据 request的值,来调用约定的函数,“实现”自定义的系统调用。

需要注 意的是,request的值并不是可以随随便便自定义的,需要遵循一些规则,可以 参考《选择ioctl命令》(注意它用的ioctl的原型是老内核的)。

ioctl 是用来操作设备的,因此我们需要一个虚拟的设备,以便ioctl能够工作。

如何实现

实现虚拟设备需要通过内核模块来实现。这篇文章写了 如何写一个入门的内核模块。

在内核模块初始化代码中

用alloc_chrdev_region申请一个设备号

初始化一个struct file_operations类型的全局变量,将open、close、 unlocked_ioctl等成员赋值为我们实现的函数。

利用cdev_add将设备号与file_operations关联起来

用class_create创建一个设备类

用device_create创建一个虚拟设备

在内核模块销毁代码中

用cdev_del解除设备号与设备操作之间的关联

用device_destroy销毁设备

用class_destroy销毁设备类

用unregister_chrdev_region释放设备号。

在自定义的unlocked_ioctl中

通过switch-case,根据request号进入某个case

如果目标函数没有参数,那么直接调用即可

如果要传递给目标函数的参数直接存储在arg中,则直接读取arg再调用即 可。

如果要传递给目标函数的参数是arg所指向的一段用户态内存,则需要从用 户态拷贝到内核态。较少的数据可以用get_user和put_user来读写,较多的数据 可以用copy_from_user和copy_to_user来读写。准备好参数之后,调用目标函数 。

编写字符设备驱动可以参考《Linux Device Driver》,网络上也有大量的 教程,在此不再赘述。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索函数
, 内核
, 参数
, 系统
, linux 驱动 lcd ioctl
, 用户态与内核态通信
, 设备
, 内核参数
, 一个
, requests模块
自调用
ioctl系统调用、linux ioctl系统调用、linux系统调用实现、系统调用实现机制、ioctl调用出错 u盘,以便于您获取更多的相关知识。

时间: 2024-09-30 19:09:25

使用ioctl“实现”自定义的系统调用的相关文章

破解索尼PS4系列:利用网页漏洞实现相关的ROP攻击(一)

本文讲的是破解索尼PS4系列:利用网页漏洞实现相关的ROP攻击(一), 目前关于PS4的黑客攻击还非常的少,但这并不能说明PS4 系统非常安全,黑客不会对其发动攻击.本文的目的就是找出PS4的一系列漏洞,最终来获得PS4的内核执行代码. PlayStation 4(简称PS4),是索尼电脑娱乐公司(SCE)推出的家用游戏机.是PlayStation游戏机系列的第四代游戏主机.PlayStation 4采用以AMD为基础的x86-64架构处理器(8核) 除了有一个记录良好的架构处理器,PS4中使用

破解索尼PS4系列:用户代码执行(二)

本文讲的是破解索尼PS4系列:用户代码执行(二), 本文会重点讲解如何在WebKit进程中进行代码执行. 代码执行 正如上一篇文章讲过的那样,ROP只是以一种聪明的方式执行内存中加载的现有代码,而ROP在技术上完全可以实现图灵完备(Turing complete),不过对于一些基本测试,ROP链反而显得有点复杂,让人感觉不太实用. 不过现在,我们已经能够利用ROP来设置内存,这样我们就可以将自己的代码写进去并执行它. 简而言之,这意味着我们可以编译C代码,例如PS4-SDK中包含的这些样本,并将

Linux下通过ioctl系统调用来获取和设置网络信息

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/ioctl.h> #include <net/if.h> #include <arpa/inet.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> 

Android自定义View之仿vivo i管家病毒扫描动画效果

技术是永无止境的,如果真的爱技术,那就勇敢的坚持下去.我很喜欢这句话,当我在遇到问题的时候.当我觉得代码枯燥的时候,我就会问自己,到底是不是真的热爱技术,这个时候,我心里总是起着波澜,我的答案是肯定的,我深深的爱着这门技术. 今天我们继续聊聊Android的自定义View系列.先看看效果吧: 这个是我手机杀毒软件的一个动画效果,类似于雷达搜索,所以用途还是很广泛的,特别是先了解一下这里的具体逻辑和写法,对技术的进步一定很有用. 先简单的分析一下这里的元素,主要有四个圆.一个扇形.还有八条虚线.当

第十九章-Delphi自定义部件开发(二)(3)

这三句表达式使用RegisterPropertyEditor三种不同的用法: ● 第一种最典型 它注册了用于所有TComponent类型属性的属性编辑器TComponentProperty.通常,当为某种类型属性注册属性编辑器时,它就能应用于所有这种类型的属性,因此,第二和第三个参数为nil. ● 第二个表达式注册特定类型的属性编辑器 它为特定部件的特定属性注册属性编辑器,在这种情况下,编辑器用于所有部件的Name属性. ● 第三个表达式介于第一个和第二个表达式之间 它为部件TMenu的TMen

linux系统调用和库函数调用的区别

1.系统调用 系统调用提供的函数如open, close, read, write, ioctl等,需包含头文件unistd.h .以write为例:其函数原型为 size_t write(int fd, const void *buf, size_t nbytes),其操作对象为文 件描述符或文件句柄fd(file descriptor),要想写一个文件,必须先以可写权限用open系统调用打开一个文 件,获得所打开文件的fd,例如 fd=open(\"/dev/video\", O_

Linux系统调用fsync函数详解

  功能描述: 同步内存中所有已修改的文件数据到储存设备. 用法: #include int fsync(int fd); 参数: fd:文件描述词. 返回说明: 成功执行时,返回0.失败返回-1,errno被设为以下的某个值 EBADF: 文件描述词无效 EIO : 读写的过程中发生错误 EROFS, EINVAL:文件所在的文件系统不支持同步 强制把系统缓存写入文件sync和fsync函数,, fflush和fsync的联系和区别2010-05-10 11:25传统的U N I X实现在内核

Linux系统调用详解(实现机制分析)--linux内核剖析(六)

系统调用概述 计算机系统的各种硬件资源是有限的,在现代多任务操作系统上同时运行的多个进程都需要访问这些资源,为了更好的管理这些资源进程是不允许直接操作的,所有对这些资源的访问都必须有操作系统控制.也就是说操作系统是使用这些资源的唯一入口,而这个入口就是操作系统提供的系统调用(System Call).在linux中系统调用是用户空间访问内核的唯一手段,除异常和陷入外,他们是内核唯一的合法入口. 一般情况下应用程序通过应用编程接口API,而不是直接通过系统调用来编程.在Unix世界,最流行的API

自定义View系列教程07--详解ViewGroup分发Touch事件

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Android多分辨率适配框架(3)- 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View