Python3: 扫描库文件并获取版本号信息

news2024/11/24 11:45:04

文章目录

    • 1. 目的
    • 2. 原理
      • Linux: strings 命令
      • Windows: strings 命令
    • 3. 基于 Python 实现 strings 命令
    • 4. 基于Python的版本号查找
    • 5. 最终调用:一句话使用

在这里插入图片描述

1. 目的

在 C/C++ 开发中使用了第三方库,具体说是 .a, .lib, .dll 等文件,想通过 Python 查询出这些文件中的版本号信息。

有人可能好奇,这里简单消除可能得疑虑:

  • 为什么不用源代码,而用库?

    因为库文件提供了良好的隔离性,避免了繁杂的编译选项指定, 避免了潜在的不小心改了代码导致的不一致

  • 为什么不用包管理工具来设定和查询库文件的版本?
    因为 C/C++ 历史包袱较多,不像 Java 的 Mavan, 更不像 Rust 的 Cargo + Crates。虽然有 vcpkg, conan 和 xmake 等, 但是公司自研的库并不能很好的用这些工具管理起来

于是乎, 实际工作中不少人的工程里, 把若干个 .a 文件放在 lib 目录下,每个库文件名字中并没有包含版本号信息; 而项目的运行结果不符合预期、展开排查时, 或者递交版本时, 需要清晰的列出这些依赖库文件的版本信息。

使用 Python 的原因:跨平台开发速度快

2. 原理

查询库文件的版本号,其实是另一个通用问题的特定版本。

通用的问题是:在一个二进制文件中, 查找所有的字符串, 找出符合预设规则的那些字符串。

查询版本号,无非是对于公司的版本号有自己的规定, 可以从所有的字符串结果中进行过滤。由于不同公司、不同项目可能有不同的版本号规则,我们重点关注两点:

  • 怎样从二进制文件获取字符串
  • 怎样从若干字符串中获取想要的那个

Linux: strings 命令

在 Linux 下可以使用自带的 strings 命令, 来列出一个二进制文件中的所有字符串。以常用的 ls 命令为例,我们进行查询:

zz@Legion-R7000P% which strings  
/usr/bin/strings
zz@Legion-R7000P% strings /bin/ls | more

在这里插入图片描述

Windows: strings 命令

Windows 并不默认带有 strings 命令, 不过微软官方提供了一个版本:

https://docs.microsoft.com/zh-cn/sysinternals/downloads/strings

在这里插入图片描述

3. 基于 Python 实现 strings 命令

对于 Windows 用户, 如果安装有 Python, 则可以基于 Python 实现 strings 命令等同的函数;由于 strings 的结果是非常多的字符串,往往还需要按版本号字符串特点进行过滤(正则匹配),继续使用 Python 的正则模块进行匹配是比较容易的。

def strings(fname):
    """
    Remake `strings` command in Python

    This function behaves like `strings` command in linux/windows.
    If no desired result returned, you may just tweak the regular expression pattern.
    ref: https://gist.github.com/berdario/114b2daf9b43fe924676

    Example:
    import arczip
    for word_bytes in arczip.strings(lib_pth):
        word = word_bytes.decode()
        if ('version' in word):
            print(word)
    """
    from mmap import mmap, ACCESS_READ
    import re

    pattern = '([\w/.\s(:)-]{10,200})'
    with open(fname, 'rb') as f, mmap(f.fileno(), 0, access=ACCESS_READ) as m:
        for match in re.finditer(pattern.encode(), m):
            yield match.group(0)

代码短小精悍,简单解释下:

  • 我们认为“字符串”是可以用一个正则表达式表示的: 英文字母、空格、短横杠-、点.、冒号:
([\w/.\s(:)-]{10,200})'
  • 我们认为字符串的长度至少为10, 至多为 200. 这个限制的目的是, 如果允许的字符串长度太长, 搜索时间会变慢,太短则很多单个字符不符合预期结果
  • 使用 yield, 迭代方式返回结果
  • 支持 Windows, 支持 Linux, 基于 Python3

4. 基于Python的版本号查找

调用刚刚实现的 strings() 函数, 对得到的结果进行正则匹配,例如需要以公司名字开头,并且版本号是4位数字、用.分隔的,那么可以是这样的实现:

# 匹配版本号
def containVersion(word):
    versionPattern = r"_\d{1,3}.\d{1,3}.\d{1,10}.\d{1,5}"
    match = re.search(versionPattern, word)
    if (match is not None):
        return True
    return False

# 给定库文件, 打印匹配到的版本号
def print_module_version(lib_pth):
    for word_bytes in strings(lib_pth):
        word = word_bytes.decode()
        if (word.startswith('YourCompany') and containVersion(word)):
            print(word)
        elif (word.startswith('your_company') and containVersion(word)):
            print(word)

5. 最终调用:一句话使用

if __name__ == '__main__':
    print_module_version('D:/work/kaku-project/lib/windows-x64/libObjectDetection.lib')
    print_module_version('D:/work/kaku-project/lib/windows-x64/libObjectDetection.dll')
    print_module_version('D:/work/kaku-project/lib/linux-arm64/libObjectDetection.a')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/530427.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++: 通过CMake配置AddressSanitizer并执行内存泄漏和越界检查

文章目录 1. 目的2. 区分编译和链接选项3. 在CMake中全局开启ASan1. 目的 在 C/C++ 工程中, 得益于 Google 工程师开发的 Address Sanitizer 这一神器, 可以快速、准确的发现不规范的内存使用, 包括而不限于: 内存泄漏检查, 例如忘记释放, 或原本持有内存的的指针被赋予…

[230522] 托福阅读词汇题 |持续更新|5月15日

infiniteimmensevast breakthroughdiscovery pivotalessential perceivedapparent 明显的 statutorilylegally 法律上 triggerprompt 引发 adolescentyouthful 青少年的 theorizedproposed 提出 replenishrenew 补充 prospersucceed pursueresearch signalindicate …

WPF MaterialDesign 初学项目实战(4)侧边栏路由管理

原视频内容 WPF项目实战合集(2022终结版) 24P 其他内容 WPF MaterialDesign 初学项目实战(0):github 项目Demo运行 WPF MaterialDesign 初学项目实战(1)首页搭建 WPF MaterialDesign 初学项目实战(2)首…

ESLint配置详解

ESLint配置详解 ESLint 是一个代码检查工具,用来检查代码是否符合指定的规范,防止在多人协作开发时代码格式不统一。 安装 全局安装 npm install eslint -g当前项目安装 npm install eslint -D安装之后运行eslint --init进行初始化,使用…

你真的理解分布式数据的分区吗?

分布式数据存储是指将数据分散存储在多个节点或服务器上的技术。而分区是将数据划分为逻辑上的片段或部分,每个分区可以在分布式系统中的不同节点上存储。分区主要是为了可扩展性。不同的分区可以放在不共享集群中的不同节点上,可以帮助实现负载均衡、高…

玩转Google开源C++单元测试框架Google Test系列(gtest)之四 - 参数化

一、前言 在设计测试案例时,经常需要考虑给被测函数传入不同的值的情况。我们之前的做法通常是写一个通用方法,然后编写在测试案例调用它。即使使用了通用方法,这样的工作也是有很多重复性的,程序员都懒,都希望能够少…

Liunx基础命令 - cd命令

cd命令 – 切换目录 cd命令来自英文词组“change directory”的缩写,其功能是用于更改当前所处的工作目录,路径可以是绝对路径,也可以是相对路径,若省略不写则会跳转至当前使用者的家目录。 **语法格式:**cd [参数] …

VMware Workstation 17 Pro安装配置CentOS 7与ssh工具链接配置

VMware Workstation 17 Pro安装配置CentOS 7与ssh工具链接配置 下载安装虚拟机VMware Workstation 17 Pro 虚拟机官网:点击直达 下载Cent os 7 镜像文件 123网盘地址:点击直达 提取码1213 在虚拟机中安装Cent os 7 第一步 点击 创建新的虚拟机 第二步 默…

解释什么是蓝绿发布?

蓝绿发布(Blue-green release)是一种软件部署策略,主要用于应对新版本软件在生产环境中的测试和部署。这种策略将新版本软件分为两个阶段:蓝色阶段和绿色阶段。蓝色阶段通常在开发和测试环境中进行,而绿色阶段则在生产环境中进行。 蓝色阶段…

C语言运算符:赋值与计算

目录 赋值运算符 算术运算符 赋值运算符 下表列出了 C 语言支持的赋值运算符: 运算符描述实例简单的赋值运算符,把右边操作数的值赋给左边操作数C A B 将把 A B 的值赋给 C加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操…

C语言基础知识:关系运算符与逻辑运算符

目录 1、关系运算符介绍 2、应用示例 3、逻辑运算符介绍 4、逻辑表达式的书写 5、不得不说的逻辑非 1、关系运算符介绍 关系运算(Relational Operators),用于判断条件,决定程序的流程。 关系数学中的表示C语言的表示小于&l…

GPT神奇应用:生成菜谱

正文共 662 字,阅读大约需要 2 分钟 料理新手/爱好者必备技巧,您将在2分钟后获得以下超能力: 快速生成菜谱 Beezy评级 :B级 *经过简单的寻找, 大部分人能立刻掌握。主要节省时间。 推荐人 | Kim 编辑者 | Linda ●图…

VMWare 虚拟机创建 + 初始化

目录 概述 1. VMware创建虚拟机 2. IP 配置 nmtui nmcli 3. Yum 源配置 光盘的Packages作为Yum源 配置开机自动挂载(光盘) 配置私有Yum仓库 跟新私有yum仓库 报错和修复 4. 文件共享系统配置 跟新配置文件/etc/hosts /etc/yum.repo.d/ftp.repo 同步配置文件 测试…

HLS入门实现一个led灯的闪烁

文章目录 前言一、HLS是什么?与VHDL/Verilog编程技术有什么关系?1、HLS简介2、开发流程3、HLS与VHDL/Verilog编程技术有什么关系? 二、2. HLS有哪些关键技术问题?目前存在什么技术局限性?1.关键技术问题2、技术局限性 三、使用 HLS 完成 le…

第十二章创建模式—享元模式

文章目录 享元模式概述结构 实例优缺点和使用场景使用场景JDK源码解析 结构型模式描述如何将类或对象按某种布局组成更大的结构,有以下两种: 类结构型模式:采用继承机制来组织接口和类。 对象结构型模式:釆用组合或聚合来组合对象…

渗透测试--2.漏洞探测和利用

目录 一.漏洞分类 二.漏洞探测 三.漏洞利用 四.漏洞扫描 1.Nessus 2.Web应用漏洞扫描器——DVWA 五.Metasploit漏洞利用 一.漏洞分类 网络漏洞 系统漏洞 应用漏洞 人为不当配置 二.漏洞探测 渗透测试是一种测试网络、应用程序和系统安全性的方法,旨在发现…

Xilinx FPGA DDR3设计(三)DDR3 IP核详解及读写测试

引言:本文我们介绍下Xilinx DDR3 IP核的重要架构、IP核信号管脚定义、读写操作时序、IP核详细配置以及简单的读写测试。 01.DDR3 IP核概述 7系列FPGA DDR接口解决方案如图1所示。 图1、7系列FPGA DDR3解决方案 1.1 用户FPGA逻辑(User FPGA Logic&#…

玩转Google开源C++单元测试框架Google Test系列(gtest)之七 - 深入解析gtest

一、前言 “深入解析”对我来说的确有些难度,所以我尽量将我学习到和观察到的gtest内部实现介绍给大家。本文算是抛砖引玉吧,只能是对gtest的整体结构的一些介绍,想要了解更多细节最好的办法还是看gtest源码,如果你看过gtest源码…

麒麟操作系统软件更新灾难连篇之一:中文输入法消失

今天在麒麟操作系统开QQ总是过一会儿就闪退,于是进软件商店看看是否有更新。 真是不看不知道,一看吓一跳,居然有几十个软件更新,照常理,软件升级后应该是更加好用,于是先把QQ、五笔字型、搜狗输入法等几个常…

centos7.9搭建redis6.0.6哨兵模式

redis6.0.6哨兵模式搭建文档 1.准备工作1.1 ip规划安装依赖(三台机器都操作)1.3 gcc升级(三台机器都操作) 2.安装redis(三台机器都操作)2.1 获取安装包2.2 解压2.3 编译2.4 验证上一步是否正确2.5 安装2.6…