这种类型的可执行文件,在大多情况下也不会对用户造成影响。因为在图形环境下,一般是通过启动器(.desktop文件)来启动程序的,并不会有什么变化,而命令行下面以文件路径执行也不存在问题。但如果想要在图形环境下的文件管理器中以鼠标双击的方式运行,就不太行了,因为很多文件管理器(尤其是基于GTK的)只认application/x-executable类型。
如果有程序的源代码,倒是可以自己给gcc加上-fno-pie和-no-pie参数重新编译,这样编译出来的可执行文件的mime类型仍然是application/x-executable。不过重新编译毕竟是个麻烦事儿,不用pie也引入了一些安全隐患,更别说需要双击执行的程序不见得能找到源代码。
所以最好的方法,就是让linux能将编译时开启了pie编译选项的可执行文件仍然认成application/x-executable
具体方法如下:
用文本编辑器以root权限打开 /usr/share/mime/packages/freedesktop.org.xml,找到其中如下一段
代码: 全选
<mime-type type="application/x-executable">
<comment>executable</comment>
<comment xml:lang="af">uitvoerbaar</comment>
... 很多的comment ....
<comment xml:lang="zh-TW">可執行檔</comment>
<generic-icon name="application-x-executable"/>
<magic priority="40">
<match type="string" value="\177ELF" offset="0">
<match type="byte" value="1" offset="5">
<match type="little16" value="2" offset="16"/>
</match>
</match>
<match type="string" value="\177ELF" offset="0">
<match type="byte" value="2" offset="5">
<match type="big16" value="2" offset="16"/>
</match>
</match>
<match type="string" value="MZ" offset="0"/>
<match type="little16" value="0x521c" offset="0"/>
<match type="host16" value="0420" offset="0"/>
<match type="host16" value="0421" offset="0"/>
<match type="little16" value="0603" offset="0"/>
</magic>
</mime-type>
代码: 全选
<magic priority="60">
<match type="string" value="\177ELF" offset="0"><match type="byte" value="1" offset="4"><match type="byte" value="1" offset="5"><match type="little16" value="3" offset="16"><match type="little32" value="52" offset="28"><match type="little32" value="3" offset="84"/></match></match></match></match></match>
<match type="string" value="\177ELF" offset="0"><match type="byte" value="2" offset="4"><match type="byte" value="1" offset="5"><match type="little16" value="3" offset="16"><match type="little32" value="64" offset="32"><match type="little32" value="0" offset="36"><match type="little32" value="3" offset="120"/></match></match></match></match></match></match>
</magic>
代码: 全选
sudo update-mime-database /usr/share/mime
==========================================================
稍微解释一下上面添加的内容。基本的xml文件格式就不说了。
依据mime类型文件格式规范 https://specifications.freedesktop.org/ ... -0.21.html ,用<magic>元素来匹配文件中特定位置的字节,如果能匹配上,就将对应的mime类型加入备选列表,此类型的优先级为priority属性指定的数值。以备选列表中优先级最大的类型作为最终的mime类型。由于同文件中application/x-sharedlib类型的优先级被设置为50,所以需要选一个更大一点的值,我设置成了60。
后面的两行<match>元素,参考ELF文件头格式( https://wiki.osdev.org/ELF#Header ),将其中的一行展开进行详细解说。
代码: 全选
<match type="string" value="\177ELF" offset="0"> <!-- ELF文件格式的Magic number -->
<match type="byte" value="1" offset="4"> <!-- 1 = 32位, 2 = 64位 -->
<match type="byte" value="1" offset="5"> <!-- 大小端:1 = little endian, 2 = big endian -->
<match type="little16" value="3" offset="16"> <!-- 类型:shared -->
<match type="little32" value="52" offset="28"> <!-- Program header表的起始位置,52 = 紧接在ELF文件头之后 -->
<match type="little32" value="3" offset="84"/> <!-- Program header表中第二段的段类型,3 = interp ,位置84 = 起始位置52+第一段长度32-->
</match>
</match>
</match>
</match>
</match>
当然,上面的两行匹配规则并不完美,只能匹配到一般情况下用gcc编译出来的可执行文件。这一般情况是指
1、Program header紧接ELF header
2、interp段位于Program header表中第二项
如果不符合这两点,就匹配不上,需要根据具体文件添加新的匹配规则。可以使用readelf -h xxx和readelf -l xxx来查看具体的变化
另外这两行是针对x86平台这种采用小端模式的,如果是在大端模式的平台上,还需要将little16/32改成big16/32,针对64位规则的offset="32"和offset="36"的值对调一下
最后再补充一点,linux上的程序判断mime类型,并不一定会用上面提到的freedesktop.org提供的mime数据库。像是file命令,就用的是libmagic库,它的数据库又是另外的文件。所以经过上面的修改后,用mimetype xxx会列出application/x-executable,而用20.04中的file -i xxx仍然显示application/x-sharedlib。不过这和本文主旨无关了