用Python做一个安全攻防工具:端口嗅探器(9)
傳送門
本系列原創博文傳送門:
用Python做一個安全攻防工具:端口嗅探器(1)
用Python做一個安全攻防工具:端口嗅探器(2)
用Python做一個安全攻防工具:端口嗅探器(3)
用Python做一個安全攻防工具:端口嗅探器(4)
用Python做一個安全攻防工具:端口嗅探器(5)
用Python做一個安全攻防工具:端口嗅探器(6)
用Python做一個安全攻防工具:端口嗅探器(7)
用Python做一個安全攻防工具:端口嗅探器(8)
用Python做一個安全攻防工具:端口嗅探器(9)
?
本章目標
本章目標是將工具打包成可執行文件。
暫時選擇py2exe模塊。
步驟實施
找了一篇示范性的文章,《使用 py2exe 打包 Python 程序》。
第一步是安裝py2exe模塊:
pip install py2exe --user這里需要加上 “--user” ,否則會出現權限問題。
第二步,在文件夾下,新建python文件 setup.py :
from distutils.core import setupsetup(console=["PortSearchGUI.py"]) # 入口文件第三步,將命令行切換到python文件目錄下:
C:\Users\admin\PycharmProjects\PortSearch>python setup.py py2exe出現報錯:
error: invalid command 'py2exe'修改代碼:
from distutils.core import setup import py2exesetup(console=["PortSearchGUI.py"]) # 入口文件第二行的代碼 “import py2exe”,一開始提示沒有被調用,實際上在命令行運行時,會使用到,加上之后,前面的報錯沒有了。
出現了新的報錯:
running py2exe9 missing Modules------------------ ? AppKit imported from pyperclip ? Foundation imported from pyperclip ? PyQt4 imported from pyperclip ? _posixshmem imported from multiprocessing.resource_tracker, multiprocessing.shared_memory ? _testinternalcapi imported from test.support ? gtk imported from pyperclip ? qtpy imported from pyperclip ? readline imported from cmd, code, pdb ? resource imported from test.support Building 'dist\PortSearchGUI.exe'. error: [Errno 2] No such file or directory: 'C:\\Users\\admin\\AppData\\Roaming\\Python\\Python39\\site-packages\\py2exe\\run-py3.9-win-amd64.exe'先找找缺少?run-py3.9-win-amd64.exe 的原因,據說py2exe只支持 python 3.4及以下。
查了下,有人建議先從缺失的模塊開始入手,這些missing Modules理論上講在代碼里是不會調到的,試著修改代碼試試:
from distutils.core import setup import py2exesetup(console=["PortSearchGUI.py"], # 入口文件options={'py2exe': {'excludes': ['AppKit', 'Foundation', 'PyQt4', '_posixshmem', '_testinternalcapi', 'gtk','qtpy', 'readline', 'resource']}},) # 入口文件再次運行下看看,報錯,提示少了,只剩下一個問題:
running py2exe Building 'dist\PortSearchGUI.exe'. error: [Errno 2] No such file or directory: 'C:\\Users\\admin\\AppData\\Roaming\\Python\\Python39\\site-packages\\py2exe\\run-py3.9-win-amd64.exe'到?C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\py2exe 目錄下看一看,發現有個?
run_w-py3.9-win-amd64.exe 文件:
復制一個文件出來,將其命名為:?run-py3.9-win-amd64.exe
再次運行:
C:\Users\admin\PycharmProjects\PortSearch>python setup.py py2exe運行成功:
running py2exe Building 'dist\PortSearchGUI.exe'. Building shared code archive 'dist\library.zip'. Copy c:\python39\python39.dll to dist Copy C:\Python39\DLLs\unicodedata.pyd to dist\unicodedata.pyd Copy C:\Python39\DLLs\select.pyd to dist\select.pyd Copy C:\Python39\DLLs\_bz2.pyd to dist\_bz2.pyd Copy C:\Python39\DLLs\_lzma.pyd to dist\_lzma.pyd Copy C:\Python39\DLLs\pyexpat.pyd to dist\pyexpat.pyd Copy C:\Python39\DLLs\_socket.pyd to dist\_socket.pyd Copy C:\Python39\DLLs\_hashlib.pyd to dist\_hashlib.pyd Copy C:\Python39\DLLs\_decimal.pyd to dist\_decimal.pyd Copy C:\Python39\DLLs\_ssl.pyd to dist\_ssl.pyd Copy C:\Python39\DLLs\_queue.pyd to dist\_queue.pyd Copy C:\Python39\DLLs\_elementtree.pyd to dist\_elementtree.pyd Copy C:\Python39\DLLs\_ctypes.pyd to dist\_ctypes.pyd Copy C:\Python39\DLLs\_tkinter.pyd to dist\_tkinter.pyd Copy C:\Python39\DLLs\_testcapi.pyd to dist\_testcapi.pyd Copy C:\Python39\DLLs\_asyncio.pyd to dist\_asyncio.pyd Copy C:\Python39\DLLs\_multiprocessing.pyd to dist\_multiprocessing.pyd Copy C:\Python39\DLLs\_overlapped.pyd to dist\_overlapped.pyd Copy C:\Python39\lib\site-packages\shiboken2\shiboken2.pyd to dist\shiboken2.shiboken2.pyd Copy C:\Python39\lib\site-packages\PySide2\QtNetwork.pyd to dist\PySide2.QtNetwork.pyd Copy C:\Python39\lib\site-packages\PySide2\QtWidgets.pyd to dist\PySide2.QtWidgets.pyd Copy C:\Python39\lib\site-packages\PySide2\QtCore.pyd to dist\PySide2.QtCore.pyd Copy C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\PyQt5\QtWidgets.pyd to dist\PyQt5.QtWidgets.pyd Copy DLL C:\Python39\lib\site-packages\PySide2\Qt5Qml.dll to dist\ Copy DLL C:\Python39\DLLs\tcl86t.dll to dist\ Copy DLL C:\Python39\DLLs\libssl-1_1.dll to dist\ Copy DLL C:\Python39\DLLs\libcrypto-1_1.dll to dist\ Copy DLL C:\Python39\lib\site-packages\PySide2\Qt5Core.dll to dist\ Copy DLL C:\Python39\lib\site-packages\PySide2\pyside2.abi3.dll to dist\ Copy DLL C:\Python39\DLLs\tk86t.dll to dist\ Copy DLL C:\Python39\lib\site-packages\PySide2\Qt5Widgets.dll to dist\ Copy DLL C:\Python39\lib\site-packages\PySide2\Qt5Gui.dll to dist\ Copy DLL C:\Python39\DLLs\libffi-7.dll to dist\ Copy DLL C:\Python39\lib\site-packages\PySide2\Qt5Network.dll to dist\ Copy DLL C:\Python39\lib\site-packages\shiboken2\shiboken2.abi3.dll to dist\ Copy ExtensionDLL C:\Python39\python3.dll to dist\在項目目錄下看到新增一個文件夾:
找到入口文件 PortSearchGUI.exe
到項目目錄下看一下,雙擊運行入口文件,出現報錯:
打開log文件,發現報錯:
Traceback (most recent call last):File "PortSearchGUI.py", line 3, in <module>File "<frozen zipimport>", line 259, in load_moduleFile "<loader>", line 10, in <module>File "<loader>", line 8, in __load ImportError: (could not import module 'PySide2.QtGui') 'C:\\Users\\admin\\PycharmProjects\\PortSearch\\dist\\PySide2.QtWidgets.pyd'在命令行里輸入:python
輸入:import?PySide2.QtGui
C:\Users\admin\PycharmProjects\PortSearch>python Python 3.9.0 (tags/v3.9.0:9cf6752, Oct 5 2020, 15:34:40) [MSC v.1927 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import PySide2.QtGui發現不報錯,試著在 PortSearchGUI.py 中加入一行引入?import?PySide2.QtGui,刪除dist目錄,再試著打包一次。
報錯:
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
查一下問題,根據 信息?,先進入 C:\Python39\Lib\site-packages\PySide2 ,將 plugins 文件夾下的 platforms 文件夾復制到 PySide2目錄下,與 designer.exe 同目錄。
再次打包,還是報一樣的錯誤,再將 PySide2文件夾復制到??C:\Users\admin\AppData\Roaming\Python\Python39\site-packages 目錄下,再次打包,再次試圖運行,報了另外一個錯:
查看日志文件,看到報錯:
Traceback (most recent call last):File "PortSearchGUI.py", line 3, in <module> ModuleNotFoundError: No module named 'PySide2.QtWidgets'在PortSearchGUI.py中加入引用?
import PySide2.QtWidgets再次打包并運行,在日志里又看到:
Traceback (most recent call last):File "PortSearchGUI.py", line 3, in <module> ModuleNotFoundError: No module named 'PySide2.QtWidgets'修改:
from PySide2 import *再次打包并運行,在日志里又看到:
Traceback (most recent call last):File "PortSearchGUI.py", line 3, in <module> AttributeError: module 'PySide2' has no attribute 'QtCore'找不到問題,試著運行了下 PortSearchGUI.py,發現報錯:
Traceback (most recent call last):File "C:\Users\admin\PycharmProjects\PortSearch\PortSearchGUI.py", line 3, in <module>from PySide2.QtWidgets import QApplication, QLineEdit, QLabel, QPlainTextEdit, QPushButton, QWidget # 引入模塊File "C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\PySide2\__init__.py", line 107, in <module>_setupQtDirectories()File "C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\PySide2\__init__.py", line 54, in _setupQtDirectoriesfor dir in _additional_dll_directories(pyside_package_dir):File "C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\PySide2\__init__.py", line 26, in _additional_dll_directoriesraise ImportError(shiboken2 + ' does not exist') ImportError: C:\Users\admin\AppData\Roaming\Python\Python39\shiboken2\libshiboken does not exist安裝 shiboken2,發現安裝在c盤根目錄下,跟之前的操作一樣,復制一份到?C:\Users\admin\AppData\Roaming\Python\Python39\site-packages?
再運行試試,能跑起來了,再打包試試,又報這個錯:
在個人環境變量里新建:
QT_PLUGINS_PATH? ??C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\PySide2\plugins
QT_PLATFORMS_PATH? ??C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\PySide2\plugins\platforms
再次打包,運行,終于出來了:
淚流滿面……
精簡不必要的代碼,最后PortSearchGUI.py代碼如下:
?
# coding=utf-8from PySide2 import QtGui from PySide2.QtWidgets import QApplication, QLineEdit, QLabel, QPlainTextEdit, QPushButton, QWidget # 引入模塊 from PySide2.QtWidgets import QMessageBox from PySide2.QtWidgets import QGroupBox, QVBoxLayout, QHBoxLayout # 布局容器 from PySide2.QtCore import Slot # 插槽模塊 from PortSearch import PortSearch import PortText import threading import pyperclip import time import sysclass PortSearchGUI(QWidget):def __init__(self):QWidget.__init__(self)self.resize(600, 480) # 主窗體尺寸self.setWindowTitle('端口嗅探器 v1.0') # 窗體名稱self.ip_line_edit = QLineEdit() # 修改父類self.ip_line_edit.setPlaceholderText('輸入ip或者網址')self.ip_line_edit.setMinimumSize(180, 22)self.thread_label = QLabel('并發數:')self.thread_line_edit = QLineEdit() # 修改父類self.thread_line_edit.setText('300')self.thread_line_edit.setMinimumSize(40, 22)self.port_label = QLabel('端口范圍:')self.port_line_edit1 = QLineEdit() # 修改父類self.port_line_edit1.setText('0')self.port_label2 = QLabel('~')self.port_line_edit2 = QLineEdit() # 修改父類self.port_line_edit2.setText('65535')self.report_box_edit = QPlainTextEdit() # 修改父類self.report_box_edit.setReadOnly(True)self.start_btn = QPushButton() # 修改父類self.start_btn.setText('啟動')self.start_btn.clicked.connect(self.collect_data) # 建立連接self.copy_all_btn = QPushButton() # 修改父類self.copy_all_btn.setText('復制全文')self.copy_all_btn.clicked.connect(self.copy_all) # 建立連接self.copy_ori_btn = QPushButton() # 修改父類self.copy_ori_btn.setText('復制原文')self.copy_ori_btn.clicked.connect(self.copy) # 建立連接self.clear_btn = QPushButton() # 修改父類self.clear_btn.setText('清空')self.clear_btn.clicked.connect(self.clear) # 建立連接self.first_group_box = QGroupBox() # 第一個分組框組控件self.first_group_box.setTitle('參數設置')self.second_group_box = QGroupBox() # 第二個分組框組控件self.second_group_box.setTitle('端口開放情況')self.first_h_layout = QHBoxLayout() # 第一個橫向布局容器,屬于第一個分組框控件self.second_h_layout = QHBoxLayout() # 第二個橫向布局容器,屬于第一個分組框控件self.third_h_layout = QHBoxLayout() # 第三個橫向布局容器,屬于第一個分組框控件self.first_v_layout = QVBoxLayout() # 第一個縱向布局容器,屬于第二個橫向布局容器self.second_v_layout = QVBoxLayout() # 第二個縱向布局容器,屬于第二個橫向布局容器self.first_h_layout.addWidget(self.ip_line_edit)self.first_h_layout.addWidget(self.thread_label)self.first_h_layout.addWidget(self.thread_line_edit)self.first_h_layout.addWidget(self.port_label)self.first_h_layout.addWidget(self.port_line_edit1)self.first_h_layout.addWidget(self.port_label2)self.first_h_layout.addWidget(self.port_line_edit2)self.first_h_layout.addWidget(self.start_btn)self.first_group_box.setLayout(self.first_h_layout)self.first_v_layout.addWidget(self.report_box_edit)self.second_v_layout.addWidget(self.copy_all_btn)self.second_v_layout.addWidget(self.copy_ori_btn)self.second_v_layout.addWidget(self.clear_btn)self.second_h_layout.addItem(self.first_v_layout)self.second_h_layout.addItem(self.second_v_layout)self.second_group_box.setLayout(self.second_h_layout)self.layout = QVBoxLayout()self.layout.addWidget(self.first_group_box)self.layout.addWidget(self.second_group_box)self.setLayout(self.layout)self.MESSAGE = ('ip或者網址不得為空','并發數不得小于1','開始端口號不得小于0','結束端口號需要大于開始端口號','原文復制成功','全文復制成功')self.G_LIST = ['', '']self.ip = ''self.thread_line = 0self.port_start = 0self.port_end = 0def show_tip(self, message): # 遇到問題,則丟到這里,拋到界面上tip = QMessageBox(self)tip.setWindowTitle('提示')tip.setText(message)tip.show()# 函數B 負責調用邏輯def logic(self):search = PortSearch(ip=self.ip, thread_line=self.thread_line, port_start=self.port_start, port_end=self.port_end)result = search.run()string = ''string1 = ''str_len = len(result)self.report_box_edit.setPlainText('')if str_len > 0: # 處理返回數據,輸出到編輯框內for ele in result:string = string + '端口:' + str(ele[1]) + ' ,狀態:開啟, 輸出信息:' + str(ele[3]) + "\n"time.sleep(1)if ele[3] == b'': # 如果沒有端口說明,則輸出參考端口服務說明string1 = string1 + '端口:' + str(ele[1]) + ',狀態:開啟,輸出信息:無' + ',參考端口服務說明:' + \PortText.port_text(ele[1]) + "\n"else:string1 = string1 + '端口:' + str(ele[1]) + ',狀態:開啟,輸出信息:' + str(ele[3]) + "\n"else:string1 = '所有端口均未開啟'self.G_LIST[0] = string # 保存原文結果self.G_LIST[1] = string1 # 保存全文結果self.report_box_edit.setPlainText(string1)self.start_btn.setEnabled(True)self.setWindowTitle('端口嗅探器 v1.0')@Slot()def collect_data(self):self.ip = self.ip_line_edit.text()self.thread_line = int(self.thread_line_edit.text())self.port_start = int(self.port_line_edit1.text())self.port_end = int(self.port_line_edit2.text())if not self.ip:self.show_tip(self.MESSAGE[0])returnif self.thread_line < 1:self.show_tip(self.MESSAGE[1])returnif self.port_start < 0:self.show_tip(self.MESSAGE[2])returnif self.port_end <= self.port_start:self.show_tip(self.MESSAGE[3])returnthread = threading.Thread(target=self.logic)thread.start() # 異步調用,避免工具卡死self.start_btn.setEnabled(False) # 限制按鈕,避免重復調用self.setWindowTitle('端口嗅探器 v1.0 ---- 執行中')@Slot()def copy(self):pyperclip.copy(self.G_LIST[0])self.show_tip(self.MESSAGE[4])@Slot()def copy_all(self):pyperclip.copy(self.G_LIST[1])self.show_tip(self.MESSAGE[5])@Slot()def clear(self):self.report_box_edit.setPlainText('')app = QApplication(sys.argv) # 創建appwindow = PortSearchGUI() # 創建主窗體 window.show() # 顯示窗體app.exec_() # 啟動app sys.exit()結語
這個系列就寫到這里了。
ps: 20210220 今天在其他同事的電腦上試了下,報 計算機中丟失 api-ms-win-core-path-l1-1-0.dll?的報錯,查了下原因,需要在該電腦上安裝?Visual C++ Redistributable for Visual Studio 2015。
?
?
總結
以上是生活随笔為你收集整理的用Python做一个安全攻防工具:端口嗅探器(9)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 地行、地貌
- 下一篇: 使用Elastic Stack做应用的3