这篇博客的内容学习《OS X 与 IOS内核编程》。书上有些已经过时的指导。可以参考我这个。
1.创建
- 开发环境:Xcode Version 8.2 (8C38)
- 新建项目:Generic Kernel Extention
- 测试代码:
#include <mach/mach_types.h>
#include <libkern/libkern.h>
kern_return_t HelloWorld_start(kmod_info_t * ki, void *d);
kern_return_t HelloWorld_stop(kmod_info_t *ki, void *d);
kern_return_t HelloWorld_start(kmod_info_t * ki, void *d)
{
printf("--------------------");
printf("Hello World\n");
printf("--------------------");
return KERN_SUCCESS;
}
kern_return_t HelloWorld_stop(kmod_info_t *ki, void *d)
{
printf("*********************");
printf("Goodbey World\n");
printf("*********************");
return KERN_SUCCESS;
}
编写内核与平时用于应用程序的API不同,printf()等函数也是这样.内核并不把用户控件的头文件<Stdio.h>包括在内.而是由自己的printf实现.在<libkern/libkern.h>头文件中声明.如果你试图在内核工程中包含<Stdio.h>,编译器将报告无法找到包括的头文件.
-
修改Info.plist,在OSBundleLibraries下面添加如下项:
com.apple.kpi.libkern String 16.3.0
在本例中,有了前缀com.apple我们可以将该库看做苹果提供的标准库
#######PS: 16.3.0是Mac OS X的内核版本,而不是Mac OS X的版本.你也可以通在Terminal中输入uname -r命令.查看你机器上的内核版本
成功编译工程之后,Xcode将创建一个名为HelloWorld.kext的内核扩展.
先把这个内核扩展拷贝到桌面.
查看这个内核的基本信息 ls -l
对于安全性,因为内核扩展授予了与核心操作系统代码相同的高级权限,
所以内核扩展程序只可以由以管理员权限访问系统的用户进行安装或者加载.
更进一步的安全措施是,系统对内核扩展程序包的权限要求非常严格,
它将拒绝加载还没有满足这些要求的内核扩展,特别是一下情况:
* KEXT程序包以及包含的所有文件和文件夹都必须由root用户(即用户id是0)所有
* KEXT程序包以及包含的所有文件和文件夹都必须由wheel(即组id是0)所有;
* KEXT程序包以及包含的任何目录的权限掩码都必须是0755(rwxr-xr-x)
* KEXT程序包中的所有文件的权限掩码都必须是0644(rw-r--r--)
所以加载内核前还要对内核做处理
修改Kext的组:
接下来
将HelloWorld.kext拷贝到/System/Library/Extensions中
终端执行代码 : (先cd到/System/Library/Extensions的位置)
加载内核:sudo kextload HelloWorld.kext
移除内核:sudo kextunload HelloWorld.kext
先加载内核:
直接加载会遇到的问题是: 10.11以后,无法使用未签名的第三方驱动.报错信息如下:
/System/Library/Extensions/HelloWorld.kext failed to load - (libkern/kext) not loadable (reason unspecified); check the system/kernel logs for errors or try kextutil(8).
以前的解决: Try enabling unsigned kext loading: sudo nvram kext-dev-mode=1 and reboot(重启电脑). 这个方法已经失效了
也就是在OS X EL Capitan之后,kext-dev-mode这种方式已经无效了.所以这里面可以了解到,问题是,kext需要签名.
如何签名
你可以创建一个未签名的kext用于内部测试加载,但是你需要禁用系统的完整性保护(SIP : System Integrity Protection).查看Configuring System Integrity Protection获取更多信息
你也可以使用已经签名的kext,但是这个签名的生成需要一些开发者证书,更多信息查看https://developer.apple.com/contact/kext
用第一种方法:(因为我只测试练习用,证书方面就不详细列出)
先查看SIP的状态: enble ? disable?
因为我这里是已经修改过了,所以为disable.如果是没有修改过的是enable的.
修改操作:
- 1.重启电脑,重启过程中一直按着command + R 直到进入startup界面
-
打开Terminal输入csrutil disable
- 完成后重启就可以了
接下来
开机后重新打开Terminal,重新加载和移除内核:
- 加载内核:sudo kextload HelloWorld.kext
- 移除内核:sudo kextunload HelloWorld.kext
这个时候就不会报错了.加载成功后输入kextstat查看.内容会有好多,直接拉到最下面看最新加入的一条就可以了.
最后,查看结果
查看输出,在Sierra中看内核日志与以前版本不同,以前的都知道从控制台看kernel.log,但是不能使用Console.app了,因为根本找不到kernel.log,要输入以下命令:
log show --predicate "processID == 0" --start 2017-2-14 --debug |grep HelloWorld
PS : 注意修改写时间就好了.
PS : 前面的3条HelloWorld,Goodbey World,HelloWorld是上一次(十几分钟前)测试遗留.可以忽略.
PS : 就看 --- 和 *** 的输出内容就可以了
写在最后 :
这篇文章只研究了这本书的第一章,在研究后续内容的时候,可能因为操作不当,生成一些其他内核文件,扰乱了苹果自身系统的内核文件内容的读取.
所以最后导致,电脑开不了机!!!!!开不了机!!!!!.
所以,后面的内容放弃研究了.......同时,要是你看到,也最好注意下自己的操作是否是正确.最好也备份一下.