Win10论坛

Win10正式版系统下载主题平板

重定义Modern UI,打造完美Windows全新体验

Windows10下载|安装|新手宝典|必备软件

搜索
查看: 4044|回复: 90

[教程] 【澎湖冰洲的家】IOKit驱动详解     [复制链接]

嫉恶如仇,是非分明的冰境泽

UID
3081083
帖子
2441
PB币
36741
贡献
0
技术
15
活跃
1959

巡察使 7周年庆典勋章 我是大学生!

发表于 2020-4-13 10:13:48 |显示全部楼层
本帖最后由 penghubingzhou 于 2020-4-13 12:01 编辑

各位好,我是澎湖冰洲,从今天起,我将在远景不定时更新IOKit驱动教程!!!
其实想做这个东西,已经有很长时间了,但是始终没有下定决心。为什么呢?因为第一,我本身就是半吊子,不能算完全的开发者;第二,发这么个东西,写的不好,容易被喷。但是,昨天某些人的行为刺激了我,最终促使我下定决心,做出这个教程来。我决定,将我的教程作为一个起点,一个抛砖引玉的起点,吸引更多的IOKit大佬前来论坛,为黑苹果贡献更多驱动来。

由于本人水平有限,编写时间仓促,难免有所疏漏,还请各位批评指正,共同完善




废话说完了,该开始进入正题了

首先今天开篇,我想跟各位谈谈什么是IOKit。如果我直接跟各位提出这个东西,恐怕很多人都没法理解这个概念,但是如果我说出诸如FakeSMC、Lilu、VoodooI2C这样的项目,我想大家都会第一时间反应:咦,这不是我们用的黑苹果驱动嘛。如果你能这样想,那就对了。实际上,你们所熟知的这些驱动,都是基于IOKit框架开发的驱动。IOKit框架,是由苹果设计的,基于内核态与用户态之间过渡的一个驱动框架,这个框架封装了一些很多底层的kpi(内核接口),让你在写驱动时,会变得更加容易。


那么有的同学会说,冰洲,不过就是个封装嘛,咋就容易了?其实,如果你对比过Linux的驱动代码就会知道,封装的一个最大优势,就是减少了代码量,避免了很多重复的工作。不得不说,苹果在IOKit方面,很有远见,其他系统如windows、Linux等,大多数都是用C语言来开发驱动,可是苹果却比较标新立异,它的所有IOKit框架驱动,全部采用c++来书写(当然win也支持c++,只不过不如mac这么彻底)。至于为什么搞c++来书写,我想学过c++的同学都知道,c++是一种OOP(面向对象编程)的语言,而且混合了C的特性,既可以无伤实现与C的混合编译(使用extern关键字),同时也可以支持OOP的很多特性,如继承,封装等。可以说,是一个代替C语言开发驱动的不俗选择之一。有人会问,冰洲,OOP具体有啥好处啊?概括起来七个字:”避免重复造轮子“(感谢Linux内核开发群某位大佬的概括,很精辟)。利用OOP提供的类,可以实现多个数据对象之间的互相调用,以及类与类之间的继承,最大限度地减少开发量。具体关于OOP的优势,大家可以自行百度,这里不再赘述。


说完了这些有些懂c++的人会问,冰洲,你这不是扯淡嘛,c++用了那么多东西,又用类又用库什么的,跑起来驱动不是要卡死嘛?是的,你说的没错,所以这里,我要说明一点,苹果驱动开发所使用的C++,绝非你在用户空间编程接触的那个C++,它是基于C++、IOKit、libkern改造后的C++子集,这一点大家一定要明确。既然是子集,那么有些C++特性,在IOKit编程里,自然是不能用了。这其中,就包括了STL、运行时(Runtime)以及异常处理(exception-handling)。这三块内容,不仅对于内核编程毫无帮助,而且会极大拖慢驱动运行速度,所以在IOKit编程里,这三块是不可以用的。

10

查看全部评分

嫉恶如仇,是非分明的冰境泽

UID
3081083
帖子
2441
PB币
36741
贡献
0
技术
15
活跃
1959

巡察使 7周年庆典勋章 我是大学生!

发表于 2020-4-13 10:13:56 |显示全部楼层
本帖最后由 penghubingzhou 于 2020-4-13 10:25 编辑

接下来,我们就会以一个最简单的驱动为例,让大家见识一下,写一个IOKit驱动有多简单。(此处没有安装Xcode的同学请绕路)

一般来说,我们学习语言,都是从Hello World程序写起来的,那么我们写驱动,也从这样一个驱动写起来。


首先,打开你的Xcode,新建一个工程:






往下翻,找到”IOKit driver“




点击进去,给你的项目取一个名字,我这里取名字叫”helloworld"







选择一个保存位置,保存





这样你的项目就建设完毕了,可以看到,Xcode已经自动为你构建好了一个工程文件,里面带有一份hpp文件以及cpp文件,供你开发使用。




附件: 你需要登录才可以下载或查看附件。没有帐号?注册

嫉恶如仇,是非分明的冰境泽

UID
3081083
帖子
2441
PB币
36741
贡献
0
技术
15
活跃
1959

巡察使 7周年庆典勋章 我是大学生!

发表于 2020-4-13 10:14:00 |显示全部楼层
本帖最后由 penghubingzhou 于 2020-4-13 12:08 编辑

接下来,让我们开始给我们的项目添加代码进去。

首先打开helloworld.hpp文件,添加如下代码进去:


  1. #include <IOKit/IOService.h>
  2. #include <IOKit/IOLib.h>

  3. class Hello_World : public IOService{
  4.      OSDeclareDefaultStructors(Hello_World);
  5. public:
  6.     //初始化模块
  7.     virtual bool init(OSDictionary* dict) override;
  8.    
  9.     //释放卸载模块
  10.     virtual void free(void) override;
  11.    
  12.     //匹配模块
  13.     virtual IOService* probe(IOService* provider, SInt32* score) override;
  14.    
  15.     //启动模块
  16.     virtual bool start(IOService* provider) override;
  17.    
  18.     //停止模块
  19.     virtual void stop(IOService* provider) override;
  20. };
复制代码


接下来,在helloworld.cpp 里 插入这些代码:

  1. #include "helloworld.hpp"

  2. //用C++ define关键字声明超类,从而使用父类函数
  3. #define super IOService

  4. OSDefineMetaClassAndStructors(Hello_World, IOService)

  5. //在头文件中定义函数的具体实现


  6. bool Hello_World::init(OSDictionary* dict){
  7.     bool ret = super::init(dict);
  8.     IOLog("驱动加载中");
  9.     return ret;
  10. }


  11. void Hello_World::free(void) {
  12.     IOLog("驱动正在释放");
  13.     super::free();
  14. }


  15. IOService* Hello_World::probe(IOService* provider, SInt32* score) {
  16.     IOService* myservice = super::probe(provider, score);
  17.     IOLog("驱动正在匹配");
  18.     return myservice;
  19. }


  20. bool Hello_World::start(IOService* provider) {
  21.     bool ret = super::start(provider);
  22.     IOLog("驱动正在启动");
  23.     return ret;
  24. }


  25. void Hello_World::stop(IOService* provider) {
  26.     IOLog("驱动正在停止");
  27.     super::stop(provider);
  28. }
复制代码


做完这些,再打开info.plist,在IOKitPersonalities项目下,点击旁边加号,添加如下字典类型:




在OSBundleLibraries下面,添加如下字典内容:





这样,我们的驱动,就算构建好了。接下来,点击左上角的“播放”按钮(其实是编译,不过为了便于大家理解,我用了这个形象化的说法),等待显示“build successfully”之后,点击“Product”文件夹,右击“helloworld.kext”,点击“Show in Finder”,就会显示编译好的驱动文件:




将这个驱动拖拽到桌面上,接下来,我们将开始加载这个驱动。打开终端,输入以下命令:


  1. sudo -i
  2. chmod -Rf 755  /path/to/helloworld.kext
  3. chown -R root:wheel /path/to/helloworld.kext
  4. kextutil /path/to/helloworld.kext
复制代码


其中/path/to/helloworld.kext为你刚才拖拽的helloworld.kext路径。注意,在加载前,请先关闭系统的SIP保护,方法请在论坛内搜寻,这里不再重复。


如果加载完成,你会看到这个加载没有任何错误显示,并且等待终端返回提示符后,你可以再输入  kextstat | grep helloworld ,来证明驱动是否加载:


  1.   kextstat | grep helloworld                        
  2.   165    0 0xffffff7f831d9000 0x4000     0x4000     as.phbz.helloworld (1) F3E8D1DB-74B8-332C-9E76-0FDC5C541BFD <4 3>
复制代码
如果有类似的返回输出,证明驱动成功加载。


接下来,我们运行这个命令,来让驱动卸载:


  1. kextunload /path/to/helloworld.kext
复制代码


卸载完成时,屏幕不会有任何输出,直接返回提示符。现在我们想知道,这个驱动究竟都干了些什么。让我们打开“控制台”app(系统自带)来看一下。打开“控制台”,在搜索里输入“kernel”进行检索,可以检索到这些信息:




这里面,输出了我们刚才在代码里写入的所有中文,它证明了我们的驱动从匹配到加载再到卸载的全过程。我们管驱动从加载到消亡叫做一个驱动的生命周期。这样的一个生命周期里,驱动将完成一系列的任务,驱动我们的各类硬件。


虽然我们已经成功让这个驱动加载了,可是,我们仍然有些问题没有解决:它的工作流程是什么?它的具体运行机制是什么?那些写的字典内容是什么?我们为什么要按照这么模块的结构来写?……环绕在这个helloworld驱动上的疑点依旧很多。这些疑点,我将在下一节内容中继续讲述,敬请期待~


附件: 你需要登录才可以下载或查看附件。没有帐号?注册

UID
4858114
帖子
307
PB币
2686
贡献
0
技术
24
活跃
2653
发表于 2020-4-13 10:17:47 |显示全部楼层
好,我来盖一层楼,加块瓦

Rank: 2Rank: 2

UID
2586400
帖子
363
PB币
345
贡献
0
技术
0
活跃
1175
发表于 2020-4-13 10:18:56 |显示全部楼层
感谢大佬分享,让更多人了解苹果驱动开发!!

Rank: 5Rank: 5Rank: 5

UID
1439670
帖子
995
PB币
787
贡献
0
技术
0
活跃
1092
发表于 2020-4-13 10:20:21 |显示全部楼层
支持了  技术大佬  膜拜

Rank: 7Rank: 7Rank: 7

UID
1740070
帖子
1476
PB币
1254
贡献
0
技术
104
活跃
2193
发表于 2020-4-13 10:23:57 |显示全部楼层
不懂帮顶,希望能做出N卡的驱动。

Rank: 5Rank: 5Rank: 5

UID
4835164
帖子
688
PB币
571
贡献
0
技术
0
活跃
773
发表于 2020-4-13 10:24:59 |显示全部楼层
活捉!!!!

Rank: 5Rank: 5Rank: 5

UID
1636165
帖子
545
PB币
115
贡献
0
技术
12
活跃
934
发表于 2020-4-13 10:28:30 |显示全部楼层
不懂帮顶!!

Rank: 7Rank: 7Rank: 7

UID
4824794
帖子
1435
PB币
71
贡献
0
技术
0
活跃
746
发表于 2020-4-13 10:35:27 |显示全部楼层
支持大佬!

xiaoleGun (小学生一枚)

Rank: 7Rank: 7Rank: 7

UID
4862408
帖子
696
PB币
40
贡献
0
技术
1
活跃
533
发表于 2020-4-13 10:35:57 |显示全部楼层
必须顶     

霸气侧漏

Rank: 2Rank: 2

UID
1211991
帖子
198
PB币
580
贡献
0
技术
0
活跃
371
发表于 2020-4-13 10:43:33 |显示全部楼层

感谢大佬分享,让更多人了解苹果驱动开发!!

大尾巴狐狸苏卡卡

Rank: 9

UID
4864259
帖子
1263
PB币
353
贡献
0
技术
5
活跃
904
发表于 2020-4-13 10:43:53 |显示全部楼层
以前 IOKit 大佬遍地跑的,现在黑苹果越来越简单了,愿意再写驱动的反而少了,以至于会点 IO80211Family 都到远景耀武扬威了。
支持版主出品 IOKit 教程!

Rank: 2Rank: 2

UID
4814087
帖子
110
PB币
184
贡献
0
技术
0
活跃
616
发表于 2020-4-13 10:44:18 |显示全部楼层
好教程,顶一个

Rank: 7Rank: 7Rank: 7

UID
564458
帖子
1506
PB币
97
贡献
0
技术
17
活跃
2546
发表于 2020-4-13 10:44:18 |显示全部楼层
这个必须支持一个,对苹果类的程序和驱动开发很感兴趣

Rank: 7Rank: 7Rank: 7

UID
4803496
帖子
1833
PB币
1897
贡献
0
技术
0
活跃
2266
发表于 2020-4-13 10:44:25 |显示全部楼层
膜拜大神
头像被屏蔽

UID
4868259
帖子
12
PB币
34
贡献
0
技术
0
活跃
1
发表于 2020-4-13 11:05:47 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

嫉恶如仇,是非分明的冰境泽

UID
3081083
帖子
2441
PB币
36741
贡献
0
技术
15
活跃
1959

巡察使 7周年庆典勋章 我是大学生!

发表于 2020-4-13 11:07:07 |显示全部楼层
本帖最后由 penghubingzhou 于 2020-4-13 11:16 编辑
wuguqunzong 发表于 2020-4-13 11:05
感觉这一系列动作都是安排好的!以前可没有大神站出来教这个。呵呵

如果不是你们某些人逼迫我,我根本没必要这么做,如果现在教程放出来你还这么多话,请你绕路

ps:下次再想做黑粉之前,选个好点的号,别选个今天才注册的号出来糊弄人。

Rank: 7Rank: 7Rank: 7

UID
1414068
帖子
1182
PB币
5258
贡献
0
技术
0
活跃
1431
发表于 2020-4-13 11:12:14 |显示全部楼层
占位,跟大佬学习

Rank: 1

UID
4817239
帖子
89
PB币
30
贡献
0
技术
0
活跃
139
发表于 2020-4-13 11:25:21 |显示全部楼层
前排支持,大佬们加油
回顶部
Copyright (C) 2005-2021 pcbeta.com, All rights reserved
Powered by Discuz!  苏ICP备17027154号
请勿发布违反中华人民共和国法律法规的言论,会员观点不代表远景论坛官方立场。
远景在线 | 远景论坛 | 苹果论坛 | Win10论坛 | Win8论坛 | Win7论坛 | WP论坛 | Office论坛 | 电脑硬件 | 安卓软件