在类UNIX系统上,可执行文件和shell脚本一般都是不带后缀名的,操作系统内置的程序加载器会自动检测文件的权限和内容是否是一个可执行的程序。这么做的好处是可以在输入命令的时候少打很多字。坏处自然是不对文件做彻底的检查就无法确定其是否是可执行文件,这会带来一些安全问题。
Linux则更进一步,提供了一套叫binfmt_misc的机制让用户自定义哪些格式的文件是可执行文件,进一步提升了系统灵活性。
这篇文章就简单讲解一下Linux的binfmt_misc的工作原理和应用。阅读这篇文章需要一些知识储备:
当然上面这些都只需要简单了解即可,下面就进入正文吧。
binfmt_misc全称是“Miscellaneous Binary Format”,它提供了一种用户接口,可以让用户注册自定义的可执行文件格式给内核。
内核在执行程序时会先检查用户和程序文件的权限,然后让程序加载器根据规则加载并执行程序,binfmt_misc所做的就是添加用户的自定义规则到加载器的规则集合中,使得除了传统意义上的可执行文件(ELF文件或者有Shebang的脚本)之外的其他文件也可以直接被执行。
举个例子,在Linux模拟Windows环境运行exe程序的模拟器wine,可以通过binfmt_misc机制把exe文件对应的执行规则注册进加载器的规则集合,之后用户就可以像使用普通的Linux程序一样直接执行exe文件,内核会检查到wine注册的规则,自动调用wine来模拟运行exe程序。
知道binfmt_misc是什么之后,下面我们来看看binfmt_misc提供的用户注册接口。
说是用户接口,但因为涉及到操作内核数据以及影响整个系统的行为,所以binfmt_misc提供的接口都需要root权限,接口的操作结果会对所有用户立即生效。
binfmt_misc接口的操作结果只在系统运行中生效,关机重启之后之前人工注册的规则就消失了,所以有持久化需求的需要主动把注册命令写入启动脚本之类的东西里。
binfmt_misc提供的接口不是系统调用,也不是特殊的命令,而是在/proc/sys/fs/binfmt_misc目录下的一系列文件,通过读取和写入这些文件,可以实现注册规则、删除规则、暂停规则、查看规则状态等操作。
接口文件主要有这几个:
/proc/sys/fs/binfmt_misc/register,一个不能读取只能写入的文件,写入固定格式的数据可以注册规则到内核/proc/sys/fs/binfmt_misc/status,可读可写的文件,读取时获取当前内核是否开启binfmt_misc机制,返回值是enabled/disabled;写入则可以关闭或重新开启binfmt_misc,允许写入的值只有0(关闭binfmt_misc)、1(重新打开)、-1(删除所有注册规则)。/proc/sys/fs/binfmt_misc/,所有注册的规则都会生成一个和规则名相同的文件,读取整个文件会获得规则的详细信息,写入则可以控制整个规则,允许写入的值有0(暂时让规则失效)、1(重新生效)、-1(删除这个规则,对应的文件也会在写入完成之后被删除)。这些接口都比较简单,你可以通过命令行或者任意一种可以读写系统文件的编程语言来操作它们。
接口中最核心的是/proc/sys/fs/binfmt_misc/register,向它写入数据才能完成我们自定义规则的注册。
注册规则的数据格式是:name:type:offset:magic:mask:interpreter:flags,每个部分都以冒号开头,字段可以省略但前导冒号需要保留,比如我们想省略mask和flags字段,就得写成:name:type:offset:magic::interpreter:。下面解释一下每个字段的意义:
/,也不能出现一些其他在文件名中不允许出现的字符。不同规则直接不能重名。M和E,其中M表示通过文件头来识别文件,E则表示通过扩展名来识别文件。M时才有效,表示读取文件头信息时需要从文件开头跳过多少个字节。.),对于一些特殊数据比如
登录查看全部
参与评论
手机查看
返回顶部