Python读取exe中导入的dll名称

Python读取exe中导入的dll名称

Python读取exe中导入的dll名称_第1张图片

1、脚本介绍

在项目中经常添加一些Qt模块,但是如果每次打包人工的去搜索复制,也是一件挺烦人的事情。所以写个脚本去做这件事情,顺理成章的事情。顺便学下python语法。

2、用法

  • 将下面的代码保存,命名为:dependency_walker.py

python.exe .\dependency_walker.py -p "c:\abc.exe,path2"

  • 同时会将用到Qt dll保存到当前目录下,命名为:recorder.txt
  • 我在项目用到的Qt 5.15.2.0 所以就设置了一个环境变量,你可能需要修改为你的

3、代码

需要安装pereader,colorama2个库

执行命令pip install pereaderpip install colorama

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2022-6-27 10:39:28
# @Author  : shixiong.Liu ([email protected])

import os
import sys
import argparse
import colorama
import pereader
import shutil


class App:
    def __init__(self):
        self._clear()

    def _clear(self):
        self.path = ""
        self.Qt5_path = ""
        self.all_dll_lists = []

    def _parse_args(self, args):
        parser = argparse.ArgumentParser(description='Tools for analyze file contains dll')
        parser.add_argument('-p', '--path', help='files path, format:"path1, path2, path3"')
        args = parser.parse_args(args)
        self.path = args.path

    def _parse_dll(self, path):
        pe = pereader.PE(path, is_entropy=True)
        for dll in pe.directory_entry_import.dlls:
            if dll.name not in self.all_dll_lists:
                self.all_dll_lists.append(dll.name)
                if dll.name.find("Qt5") == 0:
                    new_dll_path = ""
                    if self.Qt5_path.find("bin") == -1:
                        new_dll_path = self.Qt5_path + "\\bin\\" + dll.name
                    else:
                        new_dll_path = self.Qt5_path + "\\" + dll.name
                    if os.path.exists(new_dll_path):
                        self._parse_dll(new_dll_path)
                        shutil.copy(new_dll_path, os.curdir)
                        print(dll.name)
                    else:
                        print(colorama.Fore.RED + "Not find file " + new_dll_path)

    def _write_to_file(self):
        file = open(".\\recorder.txt", mode="w+", )
        self.all_dll_lists.sort()
        new_text_content = ""
        for name in self.all_dll_lists:
            new_text_content += name + "\r"
        file.write(new_text_content)
        file.close()
        print(colorama.Fore.GREEN + "write recorder file finished.")

    def run(self, args):
        self._parse_args(args)
        self.Qt5_path = os.getenv("QTDIR5_15_2_0")
        if self.Qt5_path == "" :
            print(colorama.Fore.RED + 'Not find QTDIR5_15_2_0 environment')
        else:
            print(colorama.Fore.GREEN + 'find QTDIR5_15_2_0 environment:' + self.Qt5_path)
            for path in self.path.split(","):
                print(colorama.Fore.GREEN + "path:" + path)
                self._parse_dll(path)
            self._write_to_file() 


if __name__ == '__main__':
    colorama.init(autoreset=True)
    try:
        app = App()
        if not app.run(sys.argv[1:]):
            sys.exit(-1)
    except KeyboardInterrupt:
        pass
    sys.exit(0)

4、总结

通过这种分析PE的结构,也是有缺点的,项目通过隐式加载的就没有问题,但是显示加载就没法读取。

说起来Python还真是香,要是用C++,估计的要干好几天时间。

你可能感兴趣的:(Python之小脚本大威力,python,开发语言)