Linux获取so/ko文件版本号教程

一、需要获取版本号的原因

从使用角度而言,有时只有特定版本的库才支持某些功能,所以我们需要确定库文件版本号。

从安全加固角度而言,有些版本存在漏洞有些版本不存在漏洞,所以我们需要获取版本号以确定当前使用版本是否需要处理。

不过就实际来看,针对库文件(尤其是ko文件)来发布的漏洞是比较少的,另一方面so和ko文件并没有强制要求实现版本号所以他们并不一定有版本号。

二、手动获取版本号方法

2.1 so文件手动获取版本号方法

2.1.1 从文件名获取版本号

很多so文件都直接将so号写到文件名中,".so"前面或后面的数字串即是其版本号,如下所示

2.1.2 使用readelf读取SONAME获取主版本号

如果文件名中没有版本号,那么退而求其次,通过readelf读取so的SONAME字段获取其主版本号。

2.2 ko文件手动获取版本号方法

2.2.1 使用modinfo获取版本号

ko文件一般不会将版本号放在文件名中,也没有类似SONAME的字段。在少数的ko文件中会设置version变量可用modinfo读取,如果没有那ko文件也就没有版本号了。

modinfo后可直接接ko文件路径,但也可以是加载到内核的模块名,已加载到内核的模块名可以用lsmod查看。

三、自动化读取so/ko文件版本python脚本

所谓自动化不过也就是将手动获取版本号的方法代码化。脚本使用python3编写,设置好main中root_dir直接运行,结果会自动保存在so_version.txt和ko_version.txt中

import os
import re
import platform

class ReadLibVersion:
    def __init__(self):
        so_version_file = "so_version.txt"
        ko_version_file = "ko_version.txt"
        self.so_version_file_obj = open(so_version_file,"w+")
        self.ko_version_file_obj = open(ko_version_file,"w+")
        system = platform.system()
        if "Windows" in system:
            self.path_split = "\\"
        else:
            self.path_split = "/"
        self.so_file_pattern = "\.so$"
        self.ko_file_pattern = "\.ko$"

    # 遍历要扫描的目录,寻找出目录下的所有so/ko文件
    def traversal_dir(self,dir):
        dir_contains = os.listdir(dir)
        for tmp in dir_contains:
            tmp_path = f"{dir}{self.path_split}{tmp}"
            if os.path.isfile(tmp_path):
                # 如果是so文件,则调用so版本号获取函数获取版本号
                if re.search(self.so_file_pattern,tmp_path) is not None:
                    # 首先从文件名获取版本号
                    so_version = self.read_so_version_by_name(tmp_path)
                    if so_version != "-":
                        self.so_version_file_obj.writelines(f"{tmp_path}\t\t{so_version}\r\n")
                    else:
                        # 如果从文件名获取不到版本号,那么就通过readelf读SONAME获取主版本号
                        so_version = self.read_so_version_by_readelf(tmp_path)
                        self.so_version_file_obj.writelines(f"{tmp_path}\t\t{so_version}\r\n")
                # 如果是ko文件,则通过modinfo读取version变量获取版本号
                elif re.search(self.ko_file_pattern,tmp_path) is not None:
                    ko_version = self.read_ko_version_by_modinfo(tmp_path)
                    self.ko_version_file_obj.writelines(f"{tmp_path}\t\t{ko_version}\r\n")
            elif os.path.isdir(tmp_path):
                sub_dir = tmp_path
                self.traversal_dir(sub_dir)

    # 从文件名获取so文件版本号
    def read_so_version_by_name(self,file_path):
        file = file_path.split(f"{self.path_split}")[-1]
        ver_pattern = "[.|\d]+\d"
        so_versions = re.findall(ver_pattern,file)
        if len(so_versions) >0:
            so_version = so_versions[0]
        else:
            so_version = "-"
        return so_version
        pass

    # 使用readelf读SONAME获取so文件主版本号
    def read_so_version_by_readelf(self,file_path):
        so_version = "-"
        readelf_result = os.popen(f"readelf -d  {file_path} |grep SONAME").read().strip()
        if readelf_result != "":
            so_version = readelf_result.split()[-1]
        return so_version
        pass

    # 使用modinfo读取version变量获取ko文件版本号
    def read_ko_version_by_modinfo(self,file_path):
        ko_version = "-"
        modinfo_result = os.popen(f"modinfo {file_path}|grep ^version:").read().strip()
        if modinfo_result != "":
            ko_version = modinfo_result.split()[-1]
        return ko_version
        pass

    def __del__(self):
        self.so_version_file_obj.close()
        self.ko_version_file_obj.close()
        pass

if __name__ == "__main__":
    # 要扫描的目录
    root_dir = "/usr/lib"
    read_lib_version_obj = ReadLibVersion()
    read_lib_version_obj.traversal_dir(root_dir)

原文地址:https://www.cnblogs.com/lsdb/p/9994539.html

时间: 2024-11-09 11:53:26

Linux获取so/ko文件版本号教程的相关文章

linux获取目录下文件

查看当前目录下的文件:find . -type f查看当前目录下的文件夹: find . -type d如果文件file1不为空: if [ -s file1 ];then       echo "file1 不为空"fi #!/bin/sh for f in `find ./testdir -type f`; do         if [ -s $f ];then                 echo $f is not empty.                 echo 

Linux获取apk包名,版本号

1.将来aapt和apktool拷贝到/usr/bin/下面 2.运行aapt报错:-bash: /usr/bin/aapt: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory解决:反查需要的文件在哪个包中yum whatprovides */ld-linux.so.2在获取的列表中选择安装glibc-2.12-1.132.el6_5.1.i686yum -y install glibc-2.12-1.132.e

linux shell 脚本获取和替换文件中特定内容

1.从一串字符串中获取特定的信息 要求1:获取本机IP:menu.lst为系统镜象的IP配置文件,需要从中获取到本机IP信息(从文件获取信息) 1 timeout 1 2 default 0 3 4 title live 5 find --set-root /casper/vmlinuz 6 kernel /casper/vmlinuz boot=casper ignore_uuid showmounts ip=eth0,10.0.66.66,255.255.240.0,10.0.64.3 7

Linux内核驱动将多个C文件编译成一个ko文件的方法——每个C文件里都有module_init与module_exit

以两个C文件为例: 将本该被分别编译成adc_device.ko和adc_driver.ko的adc_device.c.adc_driver.c编译成一个ko文件! 采用方法: 第一步.修改C文件 1.去掉adc_device.c文件里module_init(xxx).module_exit(yyy)中xxx.yyy 函数原型的关键字static 2.注销adc_device.c文件里module_init(xxx).module_exit(yyy)函数 3.在adc_driver.c文件里添加

Linux 目录结构及文件基本操作

整理来自 https://www.shiyanlou.com/courses/running/59 在讲 Linux 目录结构之前,你首先要清楚一点东西,那就是 Linux 的目录与 Windows 的目录的区别,或许对于一般操作上的感受来说没有多大不同,但从它们的实现机制来说是完全不同的. 一种不同是体现在目录与存储介质(磁盘,内存,DVD 等)的关系上,以往的 Windows 一直是以存储介质为主的,主要以盘符(C 盘,D 盘...)及分区的来实现文件管理,然后之下才是目录,目录就显得不是那

Linux获取网络接口信息

linux获取网络接口信息需要用到的函数为ioctl(),结构体struct ifreq,struct ifconf 1.ioctl()函数原型及作用 1 #include <sys/ioctl.h> 2 3 int ioctl(int d, int request, ...); 4 5 //参数 6 //int d:是一个文件描述符 7 //int request :表示要请求的信息.如IP地址.网络掩码等 8 //......:可变参数,根据request而定 下面是ioctl请求的req

Linux共享库.so文件的命名和动态链接

Linux中的.so文件 是动态链接的产物 共享库理解为提供各种功能函数的集合,对外提供标准的接口 Linux中命名系统中共享库的规则 主版本号:不同的版本号之间不兼容 次版本号:增量升级 向后兼容 发行版本号:对应次版本的错误修正和性能提升,不影响兼容性 Linux中的共享库并不都是这样的格式 比如GLibc的共享库命名为:libc-x.y.z.so 动态链接器也是GLibc的一部分,使用ld-x.y.z.so命名 libm(数学库)等 SO-NAME机制 系统和程序中要链接的共享库的格式一般

ubuntu/linux mint 创建proc文件的三种方法(二)

在做内核驱动开发的时候,可以使用/proc下的文件,获取相应的信息,以便调试. 大多数/proc下的文件是只读的,但为了示例的完整性,都提供了写方法. 方法一:使用create_proc_entry创建proc文件(简单,但写操作有缓冲区溢出的危险): 方法二:使用proc_create和seq_file创建proc文件(较方法三简洁): 方法三:使用proc_create_data和seq_file创建proc文件(较麻烦,但比较完整): 示例四:在proc文件中使用内核链表的一个示例(用的方

ubuntu/linux mint 创建proc文件的三种方法(四)

在做内核驱动开发的时候,可以使用/proc下的文件,获取相应的信息,以便调试. 大多数/proc下的文件是只读的,但为了示例的完整性,都提供了写方法. 方法一:使用create_proc_entry创建proc文件(简单,但写操作有缓冲区溢出的危险): 方法二:使用proc_create和seq_file创建proc文件(较方法三简洁): 方法三:使用proc_create_data和seq_file创建proc文件(较麻烦,但比较完整): 示例四:在proc文件中使用内核链表的一个示例(用的方