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

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

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

不过就实际来看,针对库文件(尤其是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)

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

  1. Linux 驱动程序/内核模块/ko文件

    Linux 驱动程序/内核模块/ko文件 一.内核模块加载机制 1.解析 Linux 内核可装载模块的版本检查机制 二.驱动/内核模块 编译 1.The Linux Kernel Module Pro ...

  2. [ARM-Linux开发] 嵌入式 linux如何生成ko文件

    hello.c文件如下 驱动程序: #include <Linux/***.h> 是在linux-2.6.29/include/linux下面寻找源文件. #include <asm ...

  3. linux获取目录下文件

    查看当前目录下的文件: find . -type f 查看当前目录下的文件夹: find . -type d 如果文件file1不为空: if [ -s file1 ];then      echo  ...

  4. Linux下编写和加载 .ko 文件(驱动模块文件)

    一..ko 文件介绍 .ko文件是kernel object文件(内核模块),该文件的意义就是把内核的一些功能移动到内核外边, 需要的时候插入内核,不需要时卸载. 二.优点 (1)这样可以缩小内核体积 ...

  5. Linux系列教程(四)——Linux常用命令之文件和目录处理命令

    这个系列教程的前面我们讲解了如何安装Linux系统,以及学习Linux系统的一些方法.那么从这篇博客开始,我们就正式进入Linux命令的学习.学习命令,首先要跟大家纠正的一点就是,我们不需要记住每一条 ...

  6. Linux中生成Core Dump系统异常信息记录文件的教程

    Linux中生成Core Dump系统异常信息记录文件的教程 http://www.jb51.net/LINUXjishu/473351.html

  7. Linux下编写和加载 .ko 文件(编写linux驱动)

    一..ko 文件介绍 .ko文件是kernel object文件(内核模块),该文件的意义就是把内核的一些功能移动到内核外边, 需要的时候插入内核,不需要时卸载. 二.优点 (1)这样可以缩小内核体积 ...

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

    以两个C文件为例: 将本该被分别编译成adc_device.ko和adc_driver.ko的adc_device.c.adc_driver.c编译成一个ko文件! 採用方法: 第一步.改动C文件 1 ...

  9. Linux+apache+mono+asp.net安装教程

    Linux+apache+mono+asp.net安装教程(CentOS上测试的) 一.准备工作: 1.安装linux系统(CentOS,这个就不多讲了) 2.下载所需软件 http-2.4.4.ta ...

随机推荐

  1. 认识拨号计划-dialplan

    拨号计划是 FreeSWITCH 中至关重要的一部分.它的主要作用就是对电话进行路由(从这一点上来说,相当于一个路由表).说的简明一点,就是当一个用户拨号时,对用户所拨的号码进行分析,进而决定下一步该 ...

  2. [js]js杂项陆续补充中...

    hasOwnProperty判断对象是否有这个属性 p = { 'name': 'maotai', 'age': 22 }; console.log(p.hasOwnProperty('names') ...

  3. C#设计模式(6)——原型模式(Prototype Pattern)(转)

    一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在 ...

  4. linq 表分组后关联查询

    测试linq,获取有教师名额的学校.比如学校有5个教师名额,teacher数量没超过5个,发现有空额 var query = (from teacher in _repositoryTeacher.T ...

  5. 宝岛探险,DFS&BFS

    问题描述: 小哼通过秘密方法得到一张不完整的钓鱼岛航拍地图.钓鱼岛由一个主岛和一些附属岛屿组成,小哼决定去钓鱼岛探险.下面这个10*10的二维矩阵就是钓鱼岛的航拍地图.图中数字表示海拔,0表示海洋,1 ...

  6. Vue系列之 => webpack基础使用

    webpack安装方式 1,运行 npm i webpack -g 全局安装. 2,在项目根目录中运行 npm i webpack --save-dev 安装到项目依赖中 项目目录 进入src运行, ...

  7. 杂谈迁移tomcat项目到docker,以及遇到的问题

    1.迁移tomcat项目异常简单,下一个tomcat的container,然后直接把webapps放进去就行了. #tomcat版本随原始项目版本而变,具体版本列表查看:https://hub.doc ...

  8. vue条件语句v-if、v-else、v-else-if用法

    vue条件语句v-if.v-else.v-else-if用法 v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建.v-if 也是惰性的:如果在初始渲 ...

  9. hisicv200 exfat支持

    由于项目中需要128Gsd卡支持.所以内核里面需要支持exfat 1.exfat 由于版权问题,所以linux kernel一直都没法支持,由于某些公司在linux kernel 3.9版本开源exf ...

  10. ACM题集以及各种总结大全(转)

    ACM题集以及各种总结大全! 虽然退役了,但是整理一下,供小弟小妹们以后切题方便一些,但由于近来考试太多,顾退役总结延迟一段时间再写!先写一下各种分类和题集,欢迎各位大牛路过指正. 一.ACM入门 关 ...