记录一下python常用的源码
邮件服务
用来每次部署博客以后给订阅的人自动发邮件
<!-- 邮件服务 --> |
自动更新更新时间
每次部署的时候自动将post的
update:
后面的时间改成文件的修改时间
<!-- 自动更新更新时间和文件名 --> |
自己写了一个文件名字批处理的软件
网上找的都怪怪的,用起来不舒服,就自己写了一个,自由度更高,使用的是tkinter。
未来打算更新的几个功能
- 增加前缀后缀(已实现)
- 修改字符的半匹配(逻辑重复已pass)
- 支持正则替换
- 支持修改范围(例如:前十个)
- 支持批量word转pdf
- 支持批量pdf转word
另外附上:>>最新版本下载地址<<
import tkinter as tk
import time
import os
import re
from tkinter import scrolledtext
import webbrowser
import tkinter.messagebox
class MY_GUI():
#窗口初始化
def __init__(self,window_name):
self.window = window_name
self.is_all_change = 0
self.is_all_change = tk.IntVar()
self.can_change = 0
self.theme_CN=self.mode_CN='默认'
# 设置窗口
#窗口设置
def set_window(self):
self.window.title('文件名称批量修改器_v1.2.0')
self.window.geometry('800x600+500+100')
self.window.maxsize(800,600)
self.window.minsize(800,600)
self.window.attributes('-alpha',1) # 1为不虚化
# self.to_be_changed_label_name=tk.StringVar()
self.to_change_label_name=tk.StringVar()
self.change_button_name=tk.StringVar()
# 标签
self.address_label = tk.Label(self.window,text='原文件夹的地址',font=('microsoft yahei', 10),relief='groove')
self.state_label = tk.Label(self.window,font=('microsoft yahei', 9),anchor='w',relief='groove')
self.to_be_changed_label = tk.Label(self.window,text='',font=('microsoft yahei', 10),relief='groove')
self.to_change_label = tk.Label(self.window,text = '',font=('microsoft yahei', 10),relief='groove')
self.change_button = tk.Button(self.window,text = '',bg='#CCCCCC',command=self.callChange)
self.original_fileList_label = tk.Label(self.window,text='原始文件目录',relief='groove')
self.latest_fileList_label = tk.Label(self.window,text='修改后文件目录',relief='groove')
self.log_data_label = tk.Label(self.window,text='工 作 日 志',font=('microsoft yahei', 10,'bold'))
# 单行输入框
self.address_Entry = tk.Entry(self.window) # 文件夹地址收集框
self.to_be_changed_Entry = tk.Entry(self.window) # 要被改变的字符串
self.to_change_Entry = tk.Entry(self.window) # 要改变成的字符串
# 按钮
self.is_all_change_button = tk.Checkbutton(self.window,text = "是否遍历整个文件夹(默认为否)",variable=self.is_all_change,onvalue=1,offvalue=0)
self.look_files_button = tk.Button(self.window,text='查看当前目录',command=self.look_files)
self.clear_button = tk.Button(self.window,text='重置',command=self.clearAll)
self.clearLog_button = tk.Button(self.window,text='清除工作日志',command=self.clearLog)
# 多行文本框
self.original_fileList_text = tk.Text(self.window) # 原始文件目录
self.latest_fileList_text = tk.Text(self.window) # 修改后的文件目录
self.log_data_text = scrolledtext.ScrolledText(self.window,font=('microsoft yahei', 10),fg='#fff',bg='#455') # 工作日志
# 菜单栏
self.menubar = tk.Menu(self.window)
self.func_menu = tk.Menu(self.menubar, tearoff=0)
self.menubar.add_cascade(label='功能', menu=self.func_menu)
self.func_menu.add_command(label='查看当前目录',command=self.look_files)
self.func_menu.add_command(label='执行',command=self.change_name)
self.func_menu.add_command(label='退出',command=self.window.quit)
self.func_menu.add_command(label='重置',command=self.clearAll)
self.change_mode_menu = tk.Menu(self.menubar,tearoff=0)
self.menubar.add_cascade(label='模式',menu=self.change_mode_menu)
self.change_mode_menu.add_command(label='替换模式',command= lambda: self.change_mode('replace_mode'))
self.change_mode_menu.add_command(label='加缀模式',command=lambda: self.change_mode('clues_mode'))
self.more_menu = tk.Menu(self.menubar,tearoff=0)
self.color_menu = tk.Menu(self.menubar,tearoff=0)
self.menubar.add_cascade(label='主题',menu = self.color_menu)
self.color_menu.add_command(label='默认',command=lambda: self.change_color('默认','#eee','#eee','#eee','#000'))
self.color_menu.add_command(label='灰蓝',command=lambda: self.change_color('灰蓝','#758a99','#50616d','#41555d','#eee'))
self.color_menu.add_command(label='苍水',command=lambda: self.change_color('苍水','#75878a','#88ada6','#808080','#eee'))
self.color_menu.add_command(label='茶白',command=lambda: self.change_color('茶白','#f3f9f1','#e0eee8','#fffbf0','#000'))
self.color_menu.add_command(label='豆青',command=lambda: self.change_color('豆青','#bce672','#96ce54','#0eb83a','#000'))
self.color_menu.add_command(label='黛紫',command=lambda: self.change_color('豆青','#815463','#8c4356','#8c4356','#fff'))
self.color_menu.add_command(label='深黑',command=lambda: self.change_color('深黑','#000','#000','#000','#fff'))
self.color_menu.add_command(label='砺茶',command=lambda: self.change_color('砺茶','#9f6f55','#8c6450','#a16d5d','#fff'))
self.menubar.add_cascade(label='更多', menu=self.more_menu)
self.more_menu.add_command(label='bug反馈',command=self.bug_return)
self.more_menu.add_command(label='赞赏',command=self.reward)
self.menubar.add_command(label='关于',command=self.about_window)
self.menubar.add_command(label='更新',command=self.update_link)
# 菜单栏的关联
self.window.config(menu=self.menubar)
# 滚动条
self.original_fileList_text_scroll = tk.Scrollbar()
self.latest_fileList_text_scroll = tk.Scrollbar()
# 放到窗口的右侧, 填充Y竖直方向
# 两个控件关联
self.original_fileList_text_scroll.config(command=self.original_fileList_text.yview)
self.original_fileList_text.config(yscrollcommand=self.original_fileList_text_scroll.set)
self.latest_fileList_text_scroll.config(command=self.latest_fileList_text.yview)
self.latest_fileList_text.config(yscrollcommand=self.latest_fileList_text_scroll.set)
self.change_mode('replace_mode')# 初始化标签名字
#布局
label_x = 10
extry_x = 140
fileList_text_x = 380
log_text_width = 360-label_x
self.address_label.place(x=label_x,y=0,width=log_text_width/3,height=30)
self.to_be_changed_label.place(x=label_x,y=30,width=log_text_width/3,height=30)
self.to_change_label.place(x=label_x,y=60,width=log_text_width/3,height=30)
self.address_Entry.place(x=extry_x,y=0,width=220,height=30)
self.to_be_changed_Entry.place(x=extry_x,y=30,width=220,height=30)
self.to_change_Entry.place(x=extry_x,y=60,width=220,height=30)
self.change_button.place(x=2*(log_text_width)/3+label_x,y=120,width=log_text_width/3,height=30)
self.is_all_change_button.place(x=100,y=90,width=280,height=30)
self.log_data_text.place(x=label_x,y=175,width=log_text_width+18,height=430-25)
self.original_fileList_label.place(x=fileList_text_x,y=0,width=100,height=30)
self.original_fileList_text.place(x=fileList_text_x,y=30,width=400,height=250)
self.latest_fileList_label.place(x=fileList_text_x,y=300,width=100,height=30)
self.latest_fileList_text.place(x=fileList_text_x,y=330,width=400,height=250)
self.look_files_button.place(x=label_x,y=90,width=log_text_width/3,height=30)
self.clear_button.place(x=label_x,y=120,width=log_text_width/3,height=30)
self.original_fileList_text_scroll.place(x=780,y=0,width=15,height=300)
self.latest_fileList_text_scroll.place(x=780,y=330,width=15,height=300)
self.clearLog_button.place(x=log_text_width/3+label_x,y=120,width=log_text_width/3,height=30)
self.log_data_label.place(x=label_x,y=150,width=log_text_width,height=25)
self.state_label.place(x=label_x,y=580,width=log_text_width,height=20)
def change_color(self,theme_CN,color1,color2,color3,fontcolor):
self.address_label.config(bg=color1,fg=fontcolor)
self.to_be_changed_label.config(bg=color2,fg=fontcolor)
self.to_change_label.config(bg=color3,fg=fontcolor)
self.original_fileList_label.config(bg = color1,fg=fontcolor)
self.latest_fileList_label.config(bg=color1,fg=fontcolor)
self.log_data_label.config(bg=color2,fg=fontcolor)
self.theme_CN=theme_CN
self.state_label.config(text='当前模式:'+self.mode_CN+' 当前主题:'+self.theme_CN)
def change_mode(self,mode):
if mode == 'replace_mode':
self.mode='replace_mode'
self.to_be_changed_label.config(text = '被替换的字符串')
self.to_change_label.config(text = '来替换的字符串')
self.change_button.config(text = '替换')
self.mode_CN='替换模式'
else:
self.mode='clues_mode'
self.to_be_changed_label.config(text='要添加的前缀')
self.to_change_label.config(text = '要添加的后缀')
self.change_button.config(text = '添加')
self.mode_CN='加缀模式'
self.state_label.config(text='当前模式:'+self.mode_CN+' 当前主题:'+self.theme_CN)
def update_link(self):
webbrowser.open('http://asea.ys168.com/',new=0)
def reward(self):
webbrowser.open("https://img.imgdb.cn/item/605ff1f08322e6675cb51721.jpg", new=0)
def about_window(self):
tk.messagebox.askyesno('关于','本软件为我闲暇之余开发的小应用,目的是解决一下自己常遇到的批量替换文件名的问题,由于我还是个新手,软件可能还有bug,你可以点击菜单栏的更多——bug反馈来进行反馈,希望本工具能够帮助到你。')
def bug_return(self):
webbrowser.open("tencent://message/?uin=569389750&Site=admin5.com&Menu=yes", new=0)
#清除工作日志
def clearLog(self):
self.log_data_text.delete(1.0,tk.END)
current_time = str(self.get_current_time())
self.log_data_text.insert(1.0, current_time+' '+'WARNING:已清除\n')
# self.log_data_text.mark_set('insert', tk.END)
#遍历文件夹返回生成器
def findAllFile(self,path): # 获取文件夹下所有文件
for root, ds, fs in os.walk(path):
for f in fs:
fullname = [os.path.join(root, f),os.path.join(root),os.path.join(f)]
yield fullname
#重置
def clearAll(self):
current_time = str(self.get_current_time())
# self.address_Entry.delete(0,tk.END)
# self.to_be_changed_Entry.delete(0,tk.END)
# self.to_change_Entry.delete(0,tk.END,)
# self.log_data_text.delete(1.0,tk.END)
self.set_window()
self.log_data_text.insert(1.0,current_time+' '+'WARNING:已重置\n')
# self.original_fileList_text.delete(1.0,tk.END)
# self.latest_fileList_text.delete(1.0,tk.END)
#获取当前时间
def get_current_time(self):
current_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
return current_time
#判断是否输入文件夹地址
def callChange(self):
if self.address_Entry.get() != '':
self.change_name()
#查看当前文件夹目录
def look_files(self):
self.original_fileList_text.delete(1.0,tk.END)
address_str = self.address_Entry.get()
try:
if self.is_all_change.get():
fileList = self.findAllFile(address_str)
for filelist in fileList:
self.original_fileList_text.insert(tk.END,filelist[2]+'\n')
else:
fileList = os.listdir(address_str)
for fileName in fileList:
self.original_fileList_text.insert(tk.END,fileName+'\n')
except:
current_time = self.get_current_time()
self.log_data_text.insert(tk.END,current_time+' '+'ERROR:请确认路径存在\n')
#主函数
def change_name(self):
address_str = self.address_Entry.get()
if self.is_all_change.get():#判断是否遍历
current_time = self.get_current_time()
try:
fileList = self.findAllFile(address_str)
except:
self.log_data_text.insert(tk.END,current_time+' '+'ERROR:请确认路径存在\n')
self.original_fileList_text.delete(1.0,tk.END)
self.latest_fileList_text.delete(1.0,tk.END)
to_be_changed_str = self.to_be_changed_Entry.get()
to_change_str = self.to_change_Entry.get()
num = 0
for filelist in (fileList):
fileName = filelist[0]#绝对路径
fileRoot = filelist[1]+'\\'
fileShortName = filelist[2]
self.original_fileList_text.insert(tk.END,fileShortName+'\n')
if self.mode == 'replace_mode':
try:
os.rename(fileName, fileRoot + fileShortName.replace(to_be_changed_str,to_change_str)) # 文件重新命名
if fileShortName != fileShortName.replace(to_be_changed_str,to_change_str):
num += 1
self.log_data_text.insert(tk.END, '已将\n'+fileShortName+'\n'+'修改为\n'+fileShortName.replace(to_be_changed_str,to_change_str)+'\n'+'-'*20+'\n')
except:
self.log_data_text.insert(tk.END,current_time+' '+'ERROR:无法同时存在两个相同名字的文件\n')
else:
try:
os.rename(fileName, fileRoot + to_be_changed_str + os.path.splitext(fileShortName)[0] + to_change_str + os.path.splitext(fileShortName)[1])
num += 1
self.log_data_text.insert(tk.END, '已将\n'+fileName+'\n'+'修改为\n'+fileRoot + fileShortName.replace(to_be_changed_str,to_change_str)+'\n'+'-'*20+'\n')
except:
self.log_data_text.insert(tk.END,current_time+' '+'ERROR:添加错误,请点击菜单栏反馈bug\n')
self.log_data_text.insert(tk.END,current_time+' '+'共修改'+str(num)+'个文件'+'\n'+'{:■^26}'.format('本次修改结束')+'\n')
fileList = self.findAllFile(address_str)
for filelist in fileList:
self.latest_fileList_text.insert(tk.END,filelist[2]+'\n')
self.log_data_text.see(tk.END) # 自动将光标移到末尾
else:
current_time = self.get_current_time()
try:
fileList = os.listdir(address_str)
except:
self.log_data_text.insert(tk.END,current_time+' '+'ERROR:请确认路径存在\n')
# os.chdir(address_str) # 将当前工作目录修改为待修改文件夹的位置
self.original_fileList_text.delete(1.0,tk.END)
self.latest_fileList_text.delete(1.0,tk.END)
to_be_changed_str = self.to_be_changed_Entry.get()
to_change_str = self.to_change_Entry.get()
num = 0
for fileName in fileList:
self.original_fileList_text.insert(tk.END,fileName+'\n')
if self.mode == 'replace_mode':
try:
os.rename(address_str+'\\'+fileName, address_str+'\\'+fileName.replace(to_be_changed_str,to_change_str)) # 3. 文件重新命名 规则根据需求自己定
if fileName != fileName.replace(to_be_changed_str,to_change_str):
num += 1
self.log_data_text.insert(tk.END, '已将\n'+fileName+'\n'+'修改为\n'+fileName.replace(to_be_changed_str,to_change_str)+'\n'+'-'*20+'\n')
except:
self.log_data_text.insert(tk.END,current_time+' '+'ERROR:无法同时存在两个相同名字的文件\n')
else:
try:
os.rename(address_str+'\\'+fileName, address_str+'\\'+to_be_changed_str+os.path.splitext(fileName)[0]+to_change_str+os.path.splitext(fileName)[1]) # 3. 文件重新命名 规则根据需求自己定
num += 1
self.log_data_text.insert(tk.END, '已将\n'+fileName+'\n'+'修改为\n'+fileName.replace(to_be_changed_str,to_change_str)+'\n'+'-'*20+'\n')
except:
self.log_data_text.insert(tk.END,current_time+' '+'ERROR:添加错误,请点击菜单栏反馈bug\n')
fileList = os.listdir(address_str)
self.latest_fileList_text.insert(tk.END,'\n'.join(fileList))
self.log_data_text.insert(tk.END,current_time+' '+'共修改'+str(num)+'个文件'+'\n'+'{:■^26}'.format('本次修改结束')+'\n')
self.log_data_text.see(tk.END)
def gui_start():
window = tk.Tk()
MY_PORTAL = MY_GUI(window)
MY_PORTAL.set_window()
window.mainloop()
gui_start()#启动pyinstaller反编译代码《pyinstxtractor.py》
具体使用可以自行百度pyinstxtractor.py
"""
PyInstaller Extractor v1.9 (Supports pyinstaller 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 : 29-November-2017
Url : https://sourceforge.net/projects/pyinstallerextractor/
For 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 resides
and run the script with the exe file name as a parameter
C:\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.0
Version 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)
"""
from __future__ import print_function
import os
import struct
import marshal
import zlib
import sys
import imp
import types
from uuid import uuid4 as uniquename
class CTOCEntry:
def __init__(self, position, cmprsdDataSize, uncmprsdDataSize, cmprsFlag, typeCmprsData, name):
self.position = position
self.cmprsdDataSize = cmprsdDataSize
self.uncmprsdDataSize = uncmprsdDataSize
self.cmprsFlag = cmprsFlag
self.typeCmprsData = typeCmprsData
self.name = name
class PyInstArchive:
PYINST20_COOKIE_SIZE = 24 # For pyinstaller 2.0
PYINST21_COOKIE_SIZE = 24 + 64 # For pyinstaller 2.1+
MAGIC = b'MEI\014\013\012\013\016' # Magic number which identifies pyinstaller
def __init__(self, path):
self.filePath = path
def open(self):
try:
self.fPtr = open(self.filePath, 'rb')
self.fileSize = os.stat(self.filePath).st_size
except:
print('[*] Error: Could not open {0}'.format(self.filePath))
return False
return True
def close(self):
try:
self.fPtr.close()
except:
pass
def checkFile(self):
print('[*] Processing {0}'.format(self.filePath))
# Check if it is a 2.0 archive
self.fPtr.seek(self.fileSize - self.PYINST20_COOKIE_SIZE, os.SEEK_SET)
magicFromFile = self.fPtr.read(len(self.MAGIC))
if magicFromFile == self.MAGIC:
self.pyinstVer = 20 # pyinstaller 2.0
print('[*] Pyinstaller version: 2.0')
return True
# Check for pyinstaller 2.1+ before bailing out
self.fPtr.seek(self.fileSize - self.PYINST21_COOKIE_SIZE, os.SEEK_SET)
magicFromFile = self.fPtr.read(len(self.MAGIC))
if magicFromFile == self.MAGIC:
print('[*] Pyinstaller version: 2.1+')
self.pyinstVer = 21 # pyinstaller 2.1+
return True
print('[*] Error : Unsupported pyinstaller version or not a pyinstaller archive')
return False
def getCArchiveInfo(self):
try:
if self.pyinstVer == 20:
self.fPtr.seek(self.fileSize - self.PYINST20_COOKIE_SIZE, os.SEEK_SET)
# Read CArchive cookie
(magic, lengthofPackage, toc, tocLen, self.pyver) = \
struct.unpack('!8siiii', self.fPtr.read(self.PYINST20_COOKIE_SIZE))
elif self.pyinstVer == 21:
self.fPtr.seek(self.fileSize - self.PYINST21_COOKIE_SIZE, os.SEEK_SET)
# Read CArchive cookie
(magic, lengthofPackage, toc, tocLen, self.pyver, pylibname) = \
struct.unpack('!8siiii64s', self.fPtr.read(self.PYINST21_COOKIE_SIZE))
except:
print('[*] Error : The file is not a pyinstaller archive')
return False
print('[*] Python version: {0}'.format(self.pyver))
# Overlay is the data appended at the end of the PE
self.overlaySize = lengthofPackage
self.overlayPos = self.fileSize - self.overlaySize
self.tableOfContentsPos = self.overlayPos + toc
self.tableOfContentsSize = tocLen
print('[*] Length of package: {0} bytes'.format(self.overlaySize))
return True
def parseTOC(self):
# Go to the table of contents
self.fPtr.seek(self.tableOfContentsPos, os.SEEK_SET)
self.tocList = []
parsedLen = 0
# Parse table of contents
while 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))
name = name.decode('utf-8').rstrip('\0')
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 += entrySize
print('[*] Found {0} files in CArchive'.format(len(self.tocList)))
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:
basePath = os.path.dirname(entry.name)
if basePath != '':
# Check if path exists, create if not
if not os.path.exists(basePath):
os.makedirs(basePath)
self.fPtr.seek(entry.position, os.SEEK_SET)
data = self.fPtr.read(entry.cmprsdDataSize)
if entry.cmprsFlag == 1:
data = zlib.decompress(data)
# Malware may tamper with the uncompressed size
# Comment out the assertion in such a case
assert len(data) == entry.uncmprsdDataSize # Sanity Check
with open(entry.name, 'wb') as f:
f.write(data)
if entry.typeCmprsData == b's':
print('[+] Possible entry point: {0}'.format(entry.name))
elif entry.typeCmprsData == b'z' or entry.typeCmprsData == b'Z':
self._extractPyz(entry.name)
def _extractPyz(self, name):
dirName = name + '_extracted'
# Create a directory for the contents of the pyz
if not os.path.exists(dirName):
os.mkdir(dirName)
with open(name, 'rb') as f:
pyzMagic = f.read(4)
assert pyzMagic == b'PYZ\0' # Sanity Check
pycHeader = f.read(4) # Python magic value
if imp.get_magic() != pycHeader:
print('[!] Warning: The script is running in a different python version than the one used to build the executable')
print(' Run this script in Python{0} to prevent extraction errors(if any) during unmarshalling'.format(self.pyver))
(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))
return
print('[*] Found {0} files in PYZ archive'.format(len(toc)))
# From pyinstaller 3.1+ toc is a list of tuples
if type(toc) == list:
toc = dict(toc)
for key in toc.keys():
(ispkg, pos, length) = toc[key]
f.seek(pos, os.SEEK_SET)
fileName = key
try:
# for Python > 3.3 some keys are bytes object some are str object
fileName = key.decode('utf-8')
except:
pass
# Make sure destination directory exists, ensuring we keep inside dirName
destName = os.path.join(dirName, fileName.replace("..", "__"))
destDirName = os.path.dirname(destName)
if not os.path.exists(destDirName):
os.makedirs(destDirName)
try:
data = f.read(length)
data = zlib.decompress(data)
except:
print('[!] Error: Failed to decompress {0}, probably encrypted. Extracting as is.'.format(fileName))
open(destName + '.pyc.encrypted', 'wb').write(data)
continue
with open(destName + '.pyc', 'wb') as pycFile:
pycFile.write(pycHeader) # Write pyc magic
pycFile.write(b'\0' * 4) # Write timestamp
if self.pyver >= 33:
pycFile.write(b'\0' * 4) # Size parameter added in Python 3.3
pycFile.write(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')
return
arch.close()
if __name__ == '__main__':
main()预支项目
opencv
可视化
pdf-word
mysql+python搭建后端接口