当前位置: 首页 > news >正文

【Python】反编译PyInstaller打包的exe

查看exe基本信息

需要反编译的exe

查看exe文件的打包工具,查看exe信息的软件叫Detect It Easy(查壳工具)

由图我们可以看出当前选中的exe文件是由名叫PyInstaller的打包工具打包好的exe

反编译

exe反编译工具:pyinstxtractor.py

使用方法

python pyinstxtractor.py XXXXX.exe

反编译工具内容,读者只需要将其复制粘贴即可用,并命名为pyinstxtractor.py

"""
PyInstaller Extractor v2.0 (Supports pyinstaller 6.3.0, 6.2.0, 6.1.0, 6.0.0, 5.13.2, 5.13.1, 5.13.0, 5.12.0, 5.11.0, 5.10.1, 5.10.0, 5.9.0, 5.8.0, 5.7.0, 5.6.2, 5.6.1, 5.6, 5.5, 5.4.1, 5.4, 5.3, 5.2, 5.1, 5.0.1, 5.0, 4.10, 4.9, 4.8, 4.7, 4.6, 4.5.1, 4.5, 4.4, 4.3, 4.2, 4.1, 4.0, 3.6, 3.5, 3.4, 3.3, 3.2, 3.1, 3.0, 2.1, 2.0)
Author : Extreme Coders
E-mail : extremecoders(at)hotmail(dot)com
Web    : https://0xec.blogspot.com
Date   : 26-March-2020
Url    : https://github.com/extremecoders-re/pyinstxtractorFor any suggestions, leave a comment on
https://forum.tuts4you.com/topic/34455-pyinstaller-extractor/This script extracts a pyinstaller generated executable file.
Pyinstaller installation is not needed. The script has it all.For best results, it is recommended to run this script in the
same version of python as was used to create the executable.
This is just to prevent unmarshalling errors(if any) while
extracting the PYZ archive.Usage : Just copy this script to the directory where your exe residesand run the script with the exe file name as a parameterC:\\path\\to\\exe\\>python pyinstxtractor.py <filename>
$ /path/to/exe/python pyinstxtractor.py <filename>Licensed under GNU General Public License (GPL) v3.
You are free to modify this source.CHANGELOG
================================================Version 1.1 (Jan 28, 2014)
-------------------------------------------------
- First Release
- Supports only pyinstaller 2.0Version 1.2 (Sept 12, 2015)
-------------------------------------------------
- Added support for pyinstaller 2.1 and 3.0 dev
- Cleaned up code
- Script is now more verbose
- Executable extracted within a dedicated sub-directory(Support for pyinstaller 3.0 dev is experimental)Version 1.3 (Dec 12, 2015)
-------------------------------------------------
- Added support for pyinstaller 3.0 final
- Script is compatible with both python 2.x & 3.x (Thanks to Moritz Kroll @ Avira Operations GmbH & Co. KG)Version 1.4 (Jan 19, 2016)
-------------------------------------------------
- Fixed a bug when writing pyc files >= version 3.3 (Thanks to Daniello Alto: https://github.com/Djamana)Version 1.5 (March 1, 2016)
-------------------------------------------------
- Added support for pyinstaller 3.1 (Thanks to Berwyn Hoyt for reporting)Version 1.6 (Sept 5, 2016)
-------------------------------------------------
- Added support for pyinstaller 3.2
- Extractor will use a random name while extracting unnamed files.
- For encrypted pyz archives it will dump the contents as is. Previously, the tool would fail.Version 1.7 (March 13, 2017)
-------------------------------------------------
- Made the script compatible with python 2.6 (Thanks to Ross for reporting)Version 1.8 (April 28, 2017)
-------------------------------------------------
- Support for sub-directories in .pyz files (Thanks to Moritz Kroll @ Avira Operations GmbH & Co. KG)Version 1.9 (November 29, 2017)
-------------------------------------------------
- Added support for pyinstaller 3.3
- Display the scripts which are run at entry (Thanks to Michael Gillespie @ malwarehunterteam for the feature request)Version 2.0 (March 26, 2020)
-------------------------------------------------
- Project migrated to github
- Supports pyinstaller 3.6
- Added support for Python 3.7, 3.8
- The header of all extracted pyc's are now automatically fixed
"""from __future__ import print_function
import os
import struct
import marshal
import zlib
import sys
from uuid import uuid4 as uniquenameclass CTOCEntry:def __init__(self, position, cmprsdDataSize, uncmprsdDataSize, cmprsFlag, typeCmprsData, name):self.position = positionself.cmprsdDataSize = cmprsdDataSizeself.uncmprsdDataSize = uncmprsdDataSizeself.cmprsFlag = cmprsFlagself.typeCmprsData = typeCmprsDataself.name = nameclass PyInstArchive:PYINST20_COOKIE_SIZE = 24           # For pyinstaller 2.0PYINST21_COOKIE_SIZE = 24 + 64      # For pyinstaller 2.1+MAGIC = b'MEI\014\013\012\013\016'  # Magic number which identifies pyinstallerdef __init__(self, path):self.filePath = pathself.pycMagic = b'\0' * 4self.barePycList = [] # List of pyc's whose headers have to be fixeddef open(self):try:self.fPtr = open(self.filePath, 'rb')self.fileSize = os.stat(self.filePath).st_sizeexcept:print('[!] Error: Could not open {0}'.format(self.filePath))return Falsereturn Truedef close(self):try:self.fPtr.close()except:passdef checkFile(self):print('[+] Processing {0}'.format(self.filePath))searchChunkSize = 8192endPos = self.fileSizeself.cookiePos = -1if endPos < len(self.MAGIC):print('[!] Error : File is too short or truncated')return Falsewhile True:startPos = endPos - searchChunkSize if endPos >= searchChunkSize else 0chunkSize = endPos - startPosif chunkSize < len(self.MAGIC):breakself.fPtr.seek(startPos, os.SEEK_SET)data = self.fPtr.read(chunkSize)offs = data.rfind(self.MAGIC)if offs != -1:self.cookiePos = startPos + offsbreakendPos = startPos + len(self.MAGIC) - 1if startPos == 0:breakif self.cookiePos == -1:print('[!] Error : Missing cookie, unsupported pyinstaller version or not a pyinstaller archive')return Falseself.fPtr.seek(self.cookiePos + self.PYINST20_COOKIE_SIZE, os.SEEK_SET)if b'python' in self.fPtr.read(64).lower():print('[+] Pyinstaller version: 2.1+')self.pyinstVer = 21     # pyinstaller 2.1+else:self.pyinstVer = 20     # pyinstaller 2.0print('[+] Pyinstaller version: 2.0')return Truedef getCArchiveInfo(self):try:if self.pyinstVer == 20:self.fPtr.seek(self.cookiePos, os.SEEK_SET)# Read CArchive cookie(magic, lengthofPackage, toc, tocLen, pyver) = \struct.unpack('!8siiii', self.fPtr.read(self.PYINST20_COOKIE_SIZE))elif self.pyinstVer == 21:self.fPtr.seek(self.cookiePos, os.SEEK_SET)# Read CArchive cookie(magic, lengthofPackage, toc, tocLen, pyver, pylibname) = \struct.unpack('!8sIIii64s', self.fPtr.read(self.PYINST21_COOKIE_SIZE))except:print('[!] Error : The file is not a pyinstaller archive')return Falseself.pymaj, self.pymin = (pyver//100, pyver%100) if pyver >= 100 else (pyver//10, pyver%10)print('[+] Python version: {0}.{1}'.format(self.pymaj, self.pymin))# Additional data after the cookietailBytes = self.fileSize - self.cookiePos - (self.PYINST20_COOKIE_SIZE if self.pyinstVer == 20 else self.PYINST21_COOKIE_SIZE)# Overlay is the data appended at the end of the PEself.overlaySize = lengthofPackage + tailBytesself.overlayPos = self.fileSize - self.overlaySizeself.tableOfContentsPos = self.overlayPos + tocself.tableOfContentsSize = tocLenprint('[+] Length of package: {0} bytes'.format(lengthofPackage))return Truedef parseTOC(self):# Go to the table of contentsself.fPtr.seek(self.tableOfContentsPos, os.SEEK_SET)self.tocList = []parsedLen = 0# Parse table of contentswhile parsedLen < self.tableOfContentsSize:(entrySize, ) = struct.unpack('!i', self.fPtr.read(4))nameLen = struct.calcsize('!iIIIBc')(entryPos, cmprsdDataSize, uncmprsdDataSize, cmprsFlag, typeCmprsData, name) = \struct.unpack( \'!IIIBc{0}s'.format(entrySize - nameLen), \self.fPtr.read(entrySize - 4))try:name = name.decode("utf-8").rstrip("\0")except UnicodeDecodeError:newName = str(uniquename())print('[!] Warning: File name {0} contains invalid bytes. Using random name {1}'.format(name, newName))name = newName# Prevent writing outside the extraction directoryif name.startswith("/"):name = name.lstrip("/")if len(name) == 0:name = str(uniquename())print('[!] Warning: Found an unamed file in CArchive. Using random name {0}'.format(name))self.tocList.append( \CTOCEntry(                      \self.overlayPos + entryPos, \cmprsdDataSize,             \uncmprsdDataSize,           \cmprsFlag,                  \typeCmprsData,              \name                        \))parsedLen += entrySizeprint('[+] Found {0} files in CArchive'.format(len(self.tocList)))def _writeRawData(self, filepath, data):nm = filepath.replace('\\', os.path.sep).replace('/', os.path.sep).replace('..', '__')nmDir = os.path.dirname(nm)if nmDir != '' and not os.path.exists(nmDir): # Check if path exists, create if notos.makedirs(nmDir)with open(nm, 'wb') as f:f.write(data)def extractFiles(self):print('[+] Beginning extraction...please standby')extractionDir = os.path.join(os.getcwd(), os.path.basename(self.filePath) + '_extracted')if not os.path.exists(extractionDir):os.mkdir(extractionDir)os.chdir(extractionDir)for entry in self.tocList:self.fPtr.seek(entry.position, os.SEEK_SET)data = self.fPtr.read(entry.cmprsdDataSize)if entry.cmprsFlag == 1:try:data = zlib.decompress(data)except zlib.error:print('[!] Error : Failed to decompress {0}'.format(entry.name))continue# Malware may tamper with the uncompressed size# Comment out the assertion in such a caseassert len(data) == entry.uncmprsdDataSize # Sanity Checkif entry.typeCmprsData == b'd' or entry.typeCmprsData == b'o':# d -> ARCHIVE_ITEM_DEPENDENCY# o -> ARCHIVE_ITEM_RUNTIME_OPTION# These are runtime options, not filescontinuebasePath = os.path.dirname(entry.name)if basePath != '':# Check if path exists, create if notif not os.path.exists(basePath):os.makedirs(basePath)if entry.typeCmprsData == b's':# s -> ARCHIVE_ITEM_PYSOURCE# Entry point are expected to be python scriptsprint('[+] Possible entry point: {0}.pyc'.format(entry.name))if self.pycMagic == b'\0' * 4:# if we don't have the pyc header yet, fix them in a later passself.barePycList.append(entry.name + '.pyc')self._writePyc(entry.name + '.pyc', data)elif entry.typeCmprsData == b'M' or entry.typeCmprsData == b'm':# M -> ARCHIVE_ITEM_PYPACKAGE# m -> ARCHIVE_ITEM_PYMODULE# packages and modules are pyc files with their header intact# From PyInstaller 5.3 and above pyc headers are no longer stored# https://github.com/pyinstaller/pyinstaller/commit/a97fdfif data[2:4] == b'\r\n':# < pyinstaller 5.3if self.pycMagic == b'\0' * 4: self.pycMagic = data[0:4]self._writeRawData(entry.name + '.pyc', data)else:# >= pyinstaller 5.3if self.pycMagic == b'\0' * 4:# if we don't have the pyc header yet, fix them in a later passself.barePycList.append(entry.name + '.pyc')self._writePyc(entry.name + '.pyc', data)else:self._writeRawData(entry.name, data)if entry.typeCmprsData == b'z' or entry.typeCmprsData == b'Z':self._extractPyz(entry.name)# Fix bare pyc's if anyself._fixBarePycs()def _fixBarePycs(self):for pycFile in self.barePycList:with open(pycFile, 'r+b') as pycFile:# Overwrite the first four bytespycFile.write(self.pycMagic)def _writePyc(self, filename, data):with open(filename, 'wb') as pycFile:pycFile.write(self.pycMagic)            # pyc magicif self.pymaj >= 3 and self.pymin >= 7:                # PEP 552 -- Deterministic pycspycFile.write(b'\0' * 4)        # BitfieldpycFile.write(b'\0' * 8)        # (Timestamp + size) || hash else:pycFile.write(b'\0' * 4)      # Timestampif self.pymaj >= 3 and self.pymin >= 3:pycFile.write(b'\0' * 4)  # Size parameter added in Python 3.3pycFile.write(data)def _extractPyz(self, name):dirName =  name + '_extracted'# Create a directory for the contents of the pyzif not os.path.exists(dirName):os.mkdir(dirName)with open(name, 'rb') as f:pyzMagic = f.read(4)assert pyzMagic == b'PYZ\0' # Sanity CheckpyzPycMagic = f.read(4) # Python magic valueif self.pycMagic == b'\0' * 4:self.pycMagic = pyzPycMagicelif self.pycMagic != pyzPycMagic:self.pycMagic = pyzPycMagicprint('[!] Warning: pyc magic of files inside PYZ archive are different from those in CArchive')# Skip PYZ extraction if not running under the same python versionif self.pymaj != sys.version_info.major or self.pymin != sys.version_info.minor:print('[!] Warning: This script is running in a different Python version than the one used to build the executable.')print('[!] Please run this script in Python {0}.{1} to prevent extraction errors during unmarshalling'.format(self.pymaj, self.pymin))print('[!] Skipping pyz extraction')return(tocPosition, ) = struct.unpack('!i', f.read(4))f.seek(tocPosition, os.SEEK_SET)try:toc = marshal.load(f)except:print('[!] Unmarshalling FAILED. Cannot extract {0}. Extracting remaining files.'.format(name))returnprint('[+] Found {0} files in PYZ archive'.format(len(toc)))# From pyinstaller 3.1+ toc is a list of tuplesif type(toc) == list:toc = dict(toc)for key in toc.keys():(ispkg, pos, length) = toc[key]f.seek(pos, os.SEEK_SET)fileName = keytry:# for Python > 3.3 some keys are bytes object some are str objectfileName = fileName.decode('utf-8')except:pass# Prevent writing outside dirNamefileName = fileName.replace('..', '__').replace('.', os.path.sep)if ispkg == 1:filePath = os.path.join(dirName, fileName, '__init__.pyc')else:filePath = os.path.join(dirName, fileName + '.pyc')fileDir = os.path.dirname(filePath)if not os.path.exists(fileDir):os.makedirs(fileDir)try:data = f.read(length)data = zlib.decompress(data)except:print('[!] Error: Failed to decompress {0}, probably encrypted. Extracting as is.'.format(filePath))open(filePath + '.encrypted', 'wb').write(data)else:self._writePyc(filePath, data)def main():if len(sys.argv) < 2:print('[+] Usage: pyinstxtractor.py <filename>')else:arch = PyInstArchive(sys.argv[1])if arch.open():if arch.checkFile():if arch.getCArchiveInfo():arch.parseTOC()arch.extractFiles()arch.close()print('[+] Successfully extracted pyinstaller archive: {0}'.format(sys.argv[1]))print('')print('You can now use a python decompiler on the pyc files within the extracted directory')returnarch.close()if __name__ == '__main__':main()

反编译的结果为一个添加后缀_extracted的文件夹

参考文献

GitHub - horsicq/Detect-It-Easy:用于确定 Windows、Linux 和 MacOS 文件类型的程序。

GitHub - extremecoders-re/pyinstxtractor:PyInstaller 提取器

超详细Pyinstaller打包exe+反编译Pyinstaller打包的exe教程+防止反编译教程 - 知乎 (zhihu.com)

相关文章:

【Python】反编译PyInstaller打包的exe

查看exe基本信息 需要反编译的exe 查看exe文件的打包工具&#xff0c;查看exe信息的软件叫Detect It Easy(查壳工具) 由图我们可以看出当前选中的exe文件是由名叫PyInstaller的打包工具打包好的exe 反编译 exe反编译工具&#xff1a;pyinstxtractor.py 使用方法 python py…...

【数据结构】哈希表与哈希桶

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.概念 2.哈希冲突…...

幼儿教育管理系统|基于jsp 技术+ Mysql+Java的幼儿教育管理系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…...

【赠书第21期】游戏力:竞技游戏设计实战教程

文章目录 前言 1 竞技游戏设计的核心要素 1.1 游戏机制 1.2 角色与技能 1.3 地图与环境 2 竞技游戏设计的策略与方法 2.1 以玩家为中心 2.2 不断迭代与优化 2.3 营造竞技氛围与社区文化 3 实战案例分析 4 结语 5 推荐图书 6 粉丝福利 前言 在数字化时代的浪潮中&…...

基于VMware虚拟机安装MacOS BigSur系统

这周用VMWare搞了个MacOS虚拟机&#xff0c;也算是完成初中高中时候的梦想了吧~~&#xff08;那时候我的电脑配置还很拉跨&#xff0c;带不动虚拟机&#xff09;~~ 写一篇博客记录一下&#xff0c;当然这也是yonagi04.github.io建站的第一篇新博客 准备工作&#xff08;VMWare…...

C++特性三:多态的基本语法及原理剖析

一、多态的基本语法 多态分为两类 静态多态: 函数重载 和 运算符重载属于静态多态&#xff0c;复用函数名 动态多态: 派生类和虚函数实现运行时多态 静态多态和动态多态区别&#xff1a; 静态多态的函数地址早绑定 - 编译阶段确定函数地址 动态多态的函数地址晚绑定 - 运…...

Windows下的TCP/IP实例

1.注意事项 windows下winsock.h/winsock2.h linux下sys/socket.h 不同平台头文件不一样 #include <winsock.h> 或者 #include <winsock2.h> 2. 安装minGW 目标是在 Windows 环境下提供类似于 Unix/Linux 环境下的开发工具&#xff0c;使开发者能够轻松地在 Wind…...

硬件学习件Cadence day15 allegro 查看state 后发现有网络未连接怎么办, shape 有问题怎么办,

1. 当我们查看 state 有问题怎么解决 1. 有问题的图片 2.解决办法&#xff1a; A.网络和节点有问题 如下图所示&#xff0c;点开下面这个窗口进行下面操作&#xff0c;能简单的网络未连接问题。 如下图所示&#xff0c;能进一步解决更难得网络节点未连接问题 如下图所示&#x…...

nginx 中 user 配置的作用

在 Nginx 配置文件中&#xff0c;user 指令用于指定 Nginx 运行时所使用的用户和用户组。默认情况下&#xff0c;Nginx 会以 nobody 用户的身份运行(即使使用 root 用户运行nginx进程, nginx运行过程中线程的用户还是用的nobody)&#xff0c;这是一个低权限用户&#xff0c;专门…...

愚人节礼物(C++)

这不愚人节 快到了吗&#xff1f;身为顶级程序员&#xff0c;不用c编写愚人节礼物那心里是很不舒服的&#xff0c;所以&#xff0c;趁着愚人节到来之际&#xff0c;下面分享一种坑朋友的c代码&#xff1a; 内容包含一些敏感词&#xff0c;如果对你产生了影响或伤害&#xff0c;…...

Lua 学习

参照 注释 -- 这是单行注释--[[这是多行注释--]]if语句 if true thenprint(true) endif else语句 nil是false if nil thenprint("nil被当作true处理") elseprint("nil被当作false处理") end运算符 % 取余 ^ 乘幂 A10,A^2100 // 整除运算符&#xff0…...

YOLOv7 | 添加GSConv,VoVGSCSP等多种卷积,有效提升目标检测效果,代码改进(超详细)

⭐欢迎大家订阅我的专栏一起学习⭐ &#x1f680;&#x1f680;&#x1f680;订阅专栏&#xff0c;更新及时查看不迷路&#x1f680;&#x1f680;&#x1f680; YOLOv5涨点专栏&#xff1a;http://t.csdnimg.cn/QdCj6 YOLOv7专栏&#xff1a; http://t.csdnimg.cn/dy…...

『运维心得』BPC-EPM-AddIn专家看过来

目录 系统版本问题 安装顺序问题 framework问题 vstor_redis问题 dll问题 一个小彩蛋 总结 最近在搞BPC&#xff0c;安装Office所需的EPM-AddIn的过程中&#xff0c;碰到了一些奇怪的问题。 查了BPC专家提供的安装说明文档&#xff0c;文档里要么没有提到我们碰到的问题…...

论文浅尝 | GPT-RE:基于大语言模型针对关系抽取的上下文学习

笔记整理&#xff1a;张廉臣&#xff0c;东南大学硕士&#xff0c;研究方向为自然语言处理、信息抽取 链接&#xff1a;https://arxiv.org/pdf/2305.02105.pdf 1、动机 在很多自然语言处理任务中&#xff0c;上下文学习的性能已经媲美甚至超过了全资源微调的方法。但是&#xf…...

Rust语言:告诉编译器允许存在未使用的代码(Rust保留未使用的实现)

Rust告诉编译器允许存在未使用的代码(Rust保留未使用的实现) Rust的Lint工具clippy clippy是一个Rust的Lint工具&#xff0c;旨在帮助开发者发现并改进代码中的潜在问题。它提供了许多静态代码分析的规则和建议&#xff0c;以提高代码质量和可读性。其中就包括检查未使用的代…...

Winform数据绑定

简介# 在C#中提起控件绑定数据&#xff0c;大部分人首先想到的是WPF&#xff0c;其实Winform也支持控件和数据的绑定。 Winform中的数据绑定按控件类型可以分为以下几种&#xff1a; 简单控件绑定列表控件绑定表格控件绑定 绑定基类# 绑定数据类必须实现INotifyPropertyChanged…...

DeprecationWarning: currentThread() is deprecated, use current_thread() instead

解决方案&#xff1a; # auto_commit not getattr(threading.currentThread(), testing, False) #阙辉注释 auto_commit not getattr(threading.current_thread(), testing, False) #阙辉新增...

2024届 C++ 刷题 笔试强训 Day 03

选择题 01 以下程序的输出结果是&#xff08;&#xff09; #include <stdio.h> void main() {char a[10] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, *p;int i;i 8;p a i;printf("%s\n", p - 3); }A 6 B 6789 C ‘6’ D 789 题目解析&#xff1a; 题目中定义了一个…...

linux用git拉取我云端以及git处理冲突

拉取后切换一个跟云端分支(dev)一样的 git branch --set-upstream-toorigin/dev dev 之后就同步了 A在dev分支写了iii,提交 B在dev分支写了hhh,提交,冲突 怎么修改,B把云端的拉下来,随便改改就行...

Learn OpenGL 17 立方体贴图

立方体贴图 我们已经使用2D纹理很长时间了&#xff0c;但除此之外仍有更多的纹理类型等着我们探索。在本节中&#xff0c;我们将讨论的是将多个纹理组合起来映射到一张纹理上的一种纹理类型&#xff1a;立方体贴图(Cube Map)。 简单来说&#xff0c;立方体贴图就是一个包含了…...

从考研到面试:线性代数高频术语中英对照速查手册(含易混点解析)

从考研到面试&#xff1a;线性代数高频术语中英对照速查手册&#xff08;含易混点解析&#xff09; 线性代数是理工科学生绕不开的核心课程&#xff0c;无论是研究生入学考试还是技术岗位面试&#xff0c;扎实的线性代数基础往往是区分优秀候选人的关键指标。尤其在涉及英文文献…...

PCIe设备初始化避坑指南:手把手教你正确配置Command寄存器(Type 0/1 Header详解)

PCIe设备初始化避坑指南&#xff1a;手把手教你正确配置Command寄存器&#xff08;Type 0/1 Header详解&#xff09; 当你第一次将PCIe设备插入主板&#xff0c;系统识别到硬件却无法正常工作时&#xff0c;80%的问题可能源于Command寄存器的错误配置。作为连接CPU与高速外设的…...

如何找回遗忘的压缩包密码?开源工具ArchivePasswordTestTool帮你轻松解决

如何找回遗忘的压缩包密码&#xff1f;开源工具ArchivePasswordTestTool帮你轻松解决 【免费下载链接】ArchivePasswordTestTool 利用7zip测试压缩包的功能 对加密压缩包进行自动化测试密码 项目地址: https://gitcode.com/gh_mirrors/ar/ArchivePasswordTestTool 你是否…...

基于蓄电池进行调峰和频率调节研究【超线性增益的联合优化】附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和…...

你以为毕业论文写作是“盖房子”?好写作AI告诉你,它是一次“极限拆墙”

每当我走进论文写作科普课的教室&#xff0c;都会在开场白问一个同样的问题&#xff1a; “用一句话形容你的毕业论文写作过程&#xff0c;你会说什么&#xff1f;” 答案永远出奇地一致——“像一个人对着空白文档发呆。”“像在一片黑暗的森林里迷路。”“像明知道前面有墙…...

国际阿里云实名账号云文件存储 NAS 怎么用?别把它当成“高级网盘”就完了!!!

很多人第一次看到 NAS&#xff0c;脑子里都会自动翻译成一句话&#xff1a; “哦&#xff0c;云上的共享文件夹。”这个理解不能说错&#xff0c;但如果你真把它当成一个“高级网盘”&#xff0c;后面大概率会一边挂载一边怀疑人生。因为阿里云国际站的 NAS&#xff0c;本质上不…...

高效视频修复方案:Untrunc工具深度解析与实战指南

高效视频修复方案&#xff1a;Untrunc工具深度解析与实战指南 【免费下载链接】untrunc Restore a truncated mp4/mov. Improved version of ponchio/untrunc 项目地址: https://gitcode.com/gh_mirrors/un/untrunc 在数字媒体时代&#xff0c;视频文件意外损坏是每个内…...

BGP邻居建不起来?从Open报文到Keepalive,一份完整的排错检查清单

BGP邻居建立故障排查实战指南&#xff1a;从报文解析到命令集 凌晨三点&#xff0c;数据中心告警面板突然亮起——"BGP邻居状态异常"。作为网络运维工程师&#xff0c;这种场景再熟悉不过。BGP作为互联网的"邮政系统"&#xff0c;其邻居关系的稳定性直接决…...

告别卡顿与内存泄漏:Dalsa线扫相机QT开发中的SapBufferWithTrash与回调函数优化实践

工业视觉开发实战&#xff1a;Dalsa线扫相机QT应用中的高性能采集架构设计 在工业自动化检测领域&#xff0c;线扫相机的稳定高效运行直接关系到整个系统的可靠性。当采样率达到每秒数万行时&#xff0c;传统的内存管理方式往往会导致图像卡顿、程序崩溃等棘手问题。本文将深入…...

Arduino新手避坑指南:面包板电路搭建最常见的5个错误(附解决方案)

Arduino面包板实战避坑手册&#xff1a;从5个经典错误中掌握电路搭建精髓 当你第一次把Arduino和面包板从包装盒里拿出来时&#xff0c;那种兴奋感就像拿到新玩具的孩子。但很快&#xff0c;当LED死活不亮、电路毫无反应时&#xff0c;这种兴奋可能就会变成沮丧。别担心&#x…...