linux elf文件添加启动验证

linux elf文件添加启动验证,第1张

我们采用完全符合PKCS[8]系列标准的签名验证算法,并兼容所有符合X509格式的证书,以RSA[6][7]非对称密钥体制为基础来完成对ELF文件代码的签名验证。

为了便于描述,我们引入以下几个基本概念1.完全摘要值--指对ELF文件的所有数据以及签名相关数据计算出来的摘要值;2.不闷兄搜完全摘要值--指对ELF文件的一部分重要数据(主要是ELF文件头)蚂历以及签名相关数。

对ELF文件的签名是通过签名工具完成的,与 *** 作系统核心无关,同时也尘姿和平台无关。签名过程完全遵循第二节中所描述的标准和原理。

CSDN的一位不愿意透漏姓氏的底层搬砖人员不用了,后面看看慢慢把文章输出到上。

[TOC]

先看图:

首先看一下普通外部模块编译的过程,这里用 ldd3 的某些驱动来演示,执行下面命令:

过程显示如下:

配置内核的 CONFIG_FUSE_FS=m ,编译成模块,执行下面命令:(指定 M=./fs/fuse 在这个内核版本有问题)

过程如下:

对比这两个过程,可以发现实际上的过程并无太大差异,可以从下图看出:

那么问题来了,这个 hello.mod.c 和 fuse.mod.c 是从哪里来的?这就要说到 scripts/mod/modpost 这个工具了。

直接看源码,首先是 main() 函数里面烂态对入参进行判断,获取内核的符号信息文件(linux内核顶层的Module.symvers),以及依赖的当前编译路径下的符号信息文件和要输出的符号信息文件(模块编译路径下的Module.symvers)。当然,一般情况下,模块里有 EXPORT_SYMBOL* 才会有模块信息导出。然后还有一些警告选项的配置,就不多说了。接下来就是 .mod.c 文件的生成过程了,看下面的函数就可以看到一些关键信息: __this_module , __module_depends 等。最后导出符号信息,结束。

read_dump() 映射了 Module.symvers 文件后,遍历文件的每一行,禅历蠢然后获取符号名称,所在的模块(或者是 vmlinux )以及符号的类型,最前面的 crc 暂时就不管了。排布类型如下:

读出符号和所在的模块信息后,对信息进行一个记录,模块就放到模块的记录链表中,符号放到记录符号的链表中。

模块的查找和申请也很简单,就是链表的 *** 作:

导出模块符号时,需要注意到不能出现相同的符号,否则这里会给出警告:

在符号的记录与查找时,利用了hash数组去加快查找速度:

至于导出符号的类型,可以看 export_list :

至于 write_dump() ,遍历hash数组判断是否需贺陪要导出相关符号即可。

read_symbols_from_files() 从 -T 选项输入的 .o 文件中读取相关的符号信息,而主要是这个 read_symbols() 函数。

read_symbols() 就是对 ELF 文件校验后,读出里面的符号表信息,并记录在当前运行的环境中。

parse_elf() 解析 elf 文件,主要是校验 ELF 头,读取各个 section 的位置后,找到与模块信息相关的 sectnon ,比如 .modinfo 模块信息, __ksymtab 导出符号等,最主要的其实是符号表 SHT_SYMTAB ,这里面记录的就是函数名、变量名等字符串信息。将符号表的起始地址和结束地址记录,方便后续使用。

get_modinfo() 是从前面 parse_elf() 记录的 .modinfo 里面获取相关的信息,比如里面的 license , version 。

比如这样: license=GPL 。

handle_modversions() 主要就是把未定义的符号和要导出的符号先记录下来。

check_exports() 检查模块所用到的符号是否与GPL协议相悖。

检查协议的如下:

导出的符号的过程在上面的 export_from_secname() 或 export_from_sec() ,在 handle_modversions() 时:

输出头文件信息、 .gnu.linkonce.this_module 节,以及 init , exit 等相关信息。

add_versions() 增加 modversion_info ,警告为定义符号等。

其实到 .mod.c 生成了,整个模块到生成模块基本就完成了。剩下的就是把 .mod.c 生成的 .mod.o 和原来的 .o 文件进行一个链接。

这个直接看就好了,对各种 ___ksymtab , ___ksymtab_gpl 等符号进行排序, init_array 进行 ALIGN(8) 对齐。

好了,模块生成就暂时这样把。

魔数,magic number,这真是让人迷惑不解,什么样的数字是魔数呢?魔数又是什么意思呢?哈哈,其实魔数的本意就是让人感到迷惑的数,看到某个数,不知道其代表何意,用东北话说,都蒙圈了。

魔数,其实也称为神奇数字,我们大多数人是在学习计算机过程中接触到这个词的。它被用来为重要的数据定义标签,用独特的数字唯-地标识该数据,这种独特的数字是只有少数人才能掌握其奥秘的“神秘力量吵键”。

故,直接出现的一个数字,只要其意义不明确,感觉很诡异,就称之为魔数。魔数应用的地方太多了,如elf 文件头。

ELF Header :

Magic : 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

这个Magic 后面的一长串就是魔数, elf 解析器(通常是程序加载器)用它来校验文件的类型是否是elf。

主引导记录最后的两个字节的内容是0x55, 0xaa,这表明这个扇区里面有可加载的程序, BIOS 就键链用它来校验该扇区是否可引导。

有人说只要为这些数字赋予实际的意义不就行了吗。其实,无论怎么给这组陌生的数字赋予名称,它都不像熟悉的出生日期那样直观易懂(如对于19590318,不解释大家也会知道0318 是3 月18 日),反而还要额外增加一些内容来解释,得不偿失,所以这就是魔数不得不存在的原因。

我们知道,一个硬盘上可以有很多分区,每个分区的格式又可以不同。就拿Linux 来说,既能识别ext3,又能识别ext4 。可能有同学会说,这两个分区的文件系统都是Linux 自己专用的,当然认得自己的东西了。

可是自己的东西也得有个辨别的地方,否则凭什么说“认得”呢。

其实这是魔数的作用,文件系统也有自己的魔数,魔数的神秘力量在此施展了。各分区都有超级稿碰孙块,一般位于本分区的第2 个扇区,比如若各分区的扇区以0 开始索引,其第1 个扇区便是超级块的起始扇区。超级块里面记录了此分区的信息,其中就有文件系统的魔数, 一种文件系统对应一个魔数,比对此值便知道文件系统类型了。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12304437.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存