日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Python中如何安全地進(jìn)行編譯和反編譯?

用Python寫腳本,小程序可謂非常方便,但它需要有特定的python環(huán)境才能運(yùn)行,因此如果你想在別的電腦上運(yùn)行時(shí)就會(huì)出現(xiàn)許多問(wèn)題,就算已經(jīng)安裝了Python,但版本可能相差較大,且相關(guān)的依賴庫(kù)沒(méi)有安裝,同樣不能正常運(yùn)行。那有沒(méi)有一種工具能把我們寫的代碼和依賴庫(kù)以及編譯環(huán)境打包到一起呢?答案是肯定的,Pyinstaller就是一款不錯(cuò)的工具,可以一鍵把你的代碼打包成exe文件。下面就先來(lái)聊一聊pyinstaller的使用方法。

創(chuàng)新互聯(lián)是一家專業(yè)從事成都做網(wǎng)站、成都網(wǎng)站制作的網(wǎng)絡(luò)公司。作為專業(yè)網(wǎng)站制作公司,創(chuàng)新互聯(lián)依托的技術(shù)實(shí)力、以及多年的網(wǎng)站運(yùn)營(yíng)經(jīng)驗(yàn),為您提供專業(yè)的成都網(wǎng)站建設(shè)、全網(wǎng)整合營(yíng)銷推廣及網(wǎng)站設(shè)計(jì)開(kāi)發(fā)服務(wù)!

一、用Pyinstaller打包python代碼

1. 安裝Pyinstaller

安裝過(guò)程非常簡(jiǎn)單,在命令行中運(yùn)行: 

 
 
 
 
  1. pip install pyinstaller 

即可完成安裝。

2. 打包代碼

我寫了一段簡(jiǎn)單的代碼作為例子,為了更清晰地演示打包過(guò)程,我將main()函數(shù)寫在了單獨(dú)的文件中,并將mylib.py作為一個(gè)庫(kù)引入。 

 
 
 
 
  1. #   mylib.py  
  2. #  
  3. import time  
  4. def myfunc():  
  5.     now = time.time()  
  6.     timetime_str = time.strftime("%Y-%m-%d %H:%M", time.localtime(now))  
  7.     print('現(xiàn)在是' + time_str)  
  8.     print("Have a nice day!")  
  9. #   main.py  
  10. #  
  11. import mylib  
  12. import os  
  13. if __name__ == "__main__":  
  14.     mylib.myfunc()  
  15.     os.system('pause') 

這時(shí)只需要在命令行中運(yùn)行: 

 
 
 
 
  1. pyinstaller.exe -F yourcode.py 

即可。會(huì)看到一下輸出: 

 
 
 
 
  1. PS D:\文檔\tmp\test> pyinstaller.exe -F main.py  
  2. 580 INFO: PyInstaller: 3.6  
  3. 582 INFO: Python: 3.7.3  
  4. 585 INFO: Platform: Windows-10-10.0.18362-SP0  
  5. 592 INFO: wrote D:\文檔\tmp\test\main.spec  
  6. 596 INFO: UPX is not available.  
  7. 611 INFO: Extending PYTHONPATH with paths  
  8. ['D:\\文檔\\tmp\\test', 'D:\\文檔\\tmp\\test']  
  9. 612 INFO: checking Analysis  
  10. 614 INFO: Building Analysis because Analysis-00.toc is non existent  
  11. 614 INFO: Initializing module dependency graph...  
  12. 620 INFO: Caching module graph hooks...  
  13. 657 INFO: Analyzing base_library.zip ...  
  14. 13893 INFO: Caching module dependency graph...  
  15. 14161 INFO: running Analysis Analysis-00.toc  
  16. 14233 INFO: Adding Microsoft.Windows.Common-Controls to dependent assemblies of final executable  
  17.   required by d:\programfiles\python\python.exe  
  18. 15748 INFO: Analyzing D:\文檔\tmp\test\main.py  
  19. 15751 INFO: Processing module hooks...  
  20. 15752 INFO: Loading module hook "hook-encodings.py"...  
  21. 16003 INFO: Loading module hook "hook-pydoc.py"...  
  22. 16011 INFO: Loading module hook "hook-xml.py"...  
  23. 16916 INFO: Looking for ctypes DLLs  
  24. 16917 INFO: Analyzing run-time hooks ...  
  25. 16925 INFO: Looking for dynamic libraries  
  26. 17373 INFO: Looking for eggs 
  27.  17374 INFO: Using Python library d:\programfiles\python\python37.dll  
  28. 17374 INFO: Found binding redirects:  
  29. []  
  30. 17377 INFO: Warnings written to D:\文檔\tmp\test\build\main\warn-main.txt  
  31. 17447 INFO: Graph cross-reference written to D:\文檔\tmp\test\build\main\xref-main.html  
  32. 17506 INFO: checking PYZ  
  33. 17507 INFO: Building PYZ because PYZ-00.toc is non existent  
  34. 17508 INFO: Building PYZ (ZlibArchive) D:\文檔\tmp\test\build\main\PYZ-00.pyz  
  35. 18600 INFO: Building PYZ (ZlibArchive) D:\文檔\tmp\test\build\main\PYZ-00.pyz completed successfully.  
  36. 18637 INFO: checking PKG  
  37. 18639 INFO: Building PKG because PKG-00.toc is non existent  
  38. 18640 INFO: Building PKG (CArchive) PKG-00.pkg  
  39. 22329 INFO: Building PKG (CArchive) PKG-00.pkg completed successfully.  
  40. 22332 INFO: Bootloader d:\programfiles\python\lib\site-packages\PyInstaller\bootloader\Windows-64bit\run.exe  
  41. 22334 INFO: checking EXE  
  42. 22335 INFO: Building EXE because EXE-00.toc is non existent  
  43. 22336 INFO: Building EXE from EXE-00.toc  
  44. 22416 INFO: Appending archive to EXE D:\文檔\tmp\test\dist\main.exe  
  45. 22641 INFO: Building EXE from EXE-00.toc completed successfully. 

你將在當(dāng)前文件夾下看到如下文件: 

 
 
 
 
  1. D:.  
  2. │  main.py  
  3. │  main.spec  
  4. │  mylib.py  
  5. ├─build  
  6. │  └─main  
  7. │          Analysis-00.toc  
  8. │          base_library.zip  
  9. │          EXE-00.toc  
  10. │          main.exe.manifest  
  11. │          PKG-00.pkg  
  12. │          PKG-00.toc  
  13. │          PYZ-00.pyz  
  14. │          PYZ-00.toc  
  15. │          warn-main.txt  
  16. │          xref-main.html  
  17. └─dist  
  18.        main.exe 

其中dist文件夾中就是生成的exe文件。

直接雙擊exe文件就能正常運(yùn)行了。

但這篇文章的重點(diǎn)并不是介紹如何使用pyinstaller。此時(shí),我又在思考,如此簡(jiǎn)單的打包過(guò)程究竟安全嗎?打包成的exe文件會(huì)不會(huì)輕而易舉地被反編譯?

查閱了相關(guān)資料后發(fā)現(xiàn),確實(shí)可能。

二、pyinstaller 的反編譯過(guò)程

1. 下載并使用pyinstxtractor解包

我們第一步采用的工具是pyinstxtractor.py,可以將pyinstaller 生成的exe文件解包成pyc文件。

項(xiàng)目地址:

https://sourceforge.net/projects/pyinstallerextractor/

之后把這個(gè)文件復(fù)制到待解包exe同級(jí)目錄下,運(yùn)行如下命令: 

 
 
 
 
  1. python pyinstxtractor.py xx.exe 

運(yùn)行后生成xx.exe_extracted文件夾 ,里面有一堆dll ,pyd等文件,我們需要注意的是里面有一個(gè)xxx.exe.manifest文件,xxx可能與你的exe文件名不同,但這才是它的真實(shí)名字。然后找到一個(gè)叫xxx的沒(méi)有后綴名的文件,它其實(shí)就是你之前打包的那個(gè).py文件對(duì)應(yīng)的pyc文件。

找到一個(gè)叫xxx的沒(méi)有后綴名的文件 

我們還注意到此目錄下還有一個(gè)PYZ-00.pyz_extracted文件夾,里面都是引入的依賴庫(kù),當(dāng)然,我們自己寫的mylib.py也在其中,它也是我們反編譯的對(duì)象。

2. 反編譯pyc文件

找到了pyc文件,下面自然就是對(duì)它進(jìn)行解密了。pyc其實(shí)是python程序執(zhí)行過(guò)程中產(chǎn)生的緩存文件,我們直接運(yùn)行python代碼時(shí)也會(huì)看到。對(duì)于這種格式的反編譯是比較簡(jiǎn)單的,網(wǎng)上有許多工具,甚至還有很多在線工具。這里為了方便,我就采用了一款在線工具。附上鏈接:http://tools.bugscaner.com/decompyle/

但直接將我們找到的pyc文件上傳會(huì)發(fā)現(xiàn)無(wú)法反編譯。原因是什么呢?我們用十六進(jìn)制編輯器(大家網(wǎng)上搜就行,我這里用的是wxMEdit)打開(kāi)這個(gè)文件,與之前直接運(yùn)行py文件生成的pyc文件比較。

我先來(lái)看一下main.pyc的區(qū)別,左邊是我們解包出來(lái)的,右邊是運(yùn)行生成的。

左邊是我們解包出來(lái)的,右邊是運(yùn)行生成的

發(fā)現(xiàn)唯一的差別就是少了第一行16個(gè)字節(jié)(叫做 magic number 表示python的版本和編譯時(shí)間),那我們把它加上是不是就能正常解析了呢?確實(shí)是這樣,但沒(méi)有原始pyc文件怎么辦?我們?cè)俚絰x.exe_extracted文件夾里找一找。會(huì)發(fā)現(xiàn)有一個(gè)叫struct的文件,我們給他加上后綴.pyc反編譯試試。發(fā)現(xiàn)成功反編譯出如下內(nèi)容:

struct反編譯結(jié)果

這就說(shuō)明它的 magic number 是正確的,那我們只要把它的前16個(gè)字節(jié)復(fù)制過(guò)去不就行了?我們?cè)賮?lái)試試,成了!main.py中的內(nèi)容被成功反編譯出來(lái)了。

main.pyc反編譯結(jié)果 

下面同理也能反編譯出mylib.py等依賴庫(kù)中的內(nèi)容,不過(guò)值得注意的是,網(wǎng)上很多教程都沒(méi)有提到依賴庫(kù)的pyc文件缺少的字節(jié)數(shù)與主程序的不同!

左:struct文件 | 中:解包出的mylib.pyc | 右:正確的pyc文件

我們發(fā)現(xiàn)它不是缺少了16個(gè)字節(jié),而是中間少了4個(gè)字節(jié)!那么,我們只需要把struct頭部的16個(gè)字節(jié)覆蓋掉mylib.pyc的前12個(gè)字節(jié)。

改好之后再進(jìn)行反編譯。

mylib.pyc反編譯內(nèi)容 

反編譯成功!不過(guò)中文字符被解析成了Unicode編碼,可以再使用相應(yīng)工具轉(zhuǎn)換。

可以看到,通過(guò)pyinstaller打包的exe,還是能被較為容易地反編譯的。那么有加密打包的方法嗎?其實(shí)pyinstaller本身就是支持加密的,下面就來(lái)說(shuō)一說(shuō)如何加密打包。

三、使用pyinstaller加密打包exe

其實(shí)只要在打包時(shí)加個(gè)key參數(shù)就能加密 

 
 
 
 
  1. pyinstaller.exe -F --key 123456 xxx.py 

不過(guò)需要依賴pycrypto包,而python一般是不自帶這個(gè)包的。因此需要我們手動(dòng)安裝。

1. 安裝pycrypto包

原本安裝過(guò)程應(yīng)該很簡(jiǎn)單,通過(guò)pip就能安裝。 

 
 
 
 
  1. pip install pycrypto 

不過(guò)安裝過(guò)程好像要調(diào)用VS編譯器編譯,這就造成了莫名其妙的問(wèn)題,如果你在安裝過(guò)程中沒(méi)有報(bào)錯(cuò),那么恭喜你,你可以跳過(guò)這部分了。

我在網(wǎng)上找了很多解決方法都沒(méi)效,最后終于在StackOverflow上找到了一篇回答,完美解決了這個(gè)問(wèn)題。原答案地址:https://stackoverflow.com/a/46921479/12954728

解決方法如下,前提是你電腦上安裝了Visual studio

以我的vs2015為例

(1)在開(kāi)始菜單中找到VS文件夾,用管理員身份運(yùn)行這個(gè)”兼容工具命令提示符“

(2)在你的VS安裝目錄下找到stdint.h這個(gè)文件,最好用everything搜索一下

(3)輸入set CL=-FI"你的路徑\stdint.h"設(shè)置環(huán)境變量

(4)然后再執(zhí)行pip install pycrypto就能成功安裝了

2. 使用pyinstaller加密打包

現(xiàn)在執(zhí)行如下命令就能加密打包了。key后面為密鑰可以隨便輸。 

 
 
 
 
  1. pyinstaller.exe -F --key 123456 xxx.py 

3. 反編譯測(cè)試

那么我們?cè)賮?lái)測(cè)試一下加密打包的exe還能不能被反編譯。

再次執(zhí)行pyinstxtractor.py 

 
 
 
 
  1. PS > python pyinstxtractor.py .\main-encrypt.exe  
  2.   import imp  
  3. [*] Processing .\main-encrypt.exe  
  4. [*] Pyinstaller version: 2.1+  
  5. [*] Python version: 37  
  6. [*] Length of package: 5787283 bytes  
  7. [*] Found 63 files in CArchive  
  8. [*] Beginning extraction...please standby  
  9. [+] Possible entry point: pyiboot01_bootstrap  
  10. [+] Possible entry point: main  
  11. [*] Found 136 files in PYZ archive  
  12. [!] Error: Failed to decompress Crypto, probably encrypted. Extracting as is.  
  13. [!] Error: Failed to decompress Crypto.Cipher, probably encrypted. Extracting as is.  
  14. [!] Error: Failed to decompress __future__, probably encrypted. Extracting as is.  
  15. [!] Error: Failed to decompress _compat_pickle, probably encrypted. Extracting as is.  
  16. [!] Error: Failed to decompress argparse, probably encrypted. Extracting as is.  
  17. [!] Error: Failed to decompress ast, probably encrypted. Extracting as is.  
  18. [!] Error: Failed to decompress base64, probably encrypted. Extracting as is.  
  19. [!] Error: Failed to decompress bdb, probably encrypted. Extracting as is.  
  20. [!] Error: Failed to decompress bisect, probably encrypted. Extracting as is.  
  21. [!] Error: Failed to decompress bz2, probably encrypted. Extracting as is.  
  22. [!] Error: Failed to decompress calendar, probably encrypted. Extracting as is.  
  23. [!] Error: Failed to decompress cmd, probably encrypted. Extracting as is.  
  24. [!] Error: Failed to decompress code, probably encrypted. Extracting as is.  
  25. [!] Error: Failed to decompress codeop, probably encrypted. Extracting as is. 

這次下面輸出了一長(zhǎng)串Error,看來(lái)確實(shí)是被加密了。

我們?cè)賮?lái)看一看文件夾。

main-encrypt.exe_extracted文件夾里似乎沒(méi)什么變化,但PYZ-00.pyz_extracted文件夾里全是加密文件,應(yīng)該是無(wú)法反編譯了。

不過(guò)對(duì)外層文件夾中的main文件進(jìn)行同樣操作后依然是可以反編譯出源碼的。

看來(lái)這個(gè)加密只針對(duì)依賴庫(kù)。

四、總結(jié)

如果你不希望別人得到你的源碼,建議將你程序的入口函數(shù)寫在一個(gè)單獨(dú)的文件里,并采用加密方式打包exe。這樣的話,就算別人嘗試反編譯也只能得到你的入口函數(shù)。


當(dāng)前標(biāo)題:Python中如何安全地進(jìn)行編譯和反編譯?
文章URL:http://www.5511xx.com/article/cocdidj.html