Pyarmor:混淆 Python 腳本,保護你的程式

Pyarmor
Github - Pyarmor
Homepage - Pyarmor
Pyarmor 是一個由 Dashingsoft 公司 (德新软件科技有限公司) 推出用來混淆 Python Script 的一個工具,透過混淆,可以防止有心人士查看裡面的程式碼,保護你的程式。有分為免費版本和付費版本,對付費版本有興趣的可以自己去看官方的頁面。
甚至還有 web 介面供用戶使用
安裝方式很簡單,直接用 pip 安裝即可:
pip install -U pyarmorSingle Script
如果只有一個單獨的 Python Script 需要加密,則直接使用以下指令就可以了
pyarmor gen <path/to/script>
# Example
pyarmor gen test.py我們用簡單的 Hello World 腳本來測試一下:
def hello_world():
print("Hello World")
if __name__ == "__main__":
hello_world()跑完指令後,接著你會看到產生出一個 dist 的資料夾,裡面有這個這樣的結構:
.
└── dist/
├── test.py
└── pyarmor_runtime_000000/
├── __init__.py
└── pyarmor_runtime.pyd我們直接執行 dist 資料夾內的 test.py,你會發現跟直接執行 test.py 是一樣的
如果你要直接 Release 給別人的話,可以直接將 dist 連同裡面所有檔案傳給別人就好了,對方不需要安裝 Pyarmor,只要用安裝相同版本的 Python 執行即可,作業系統也是需要是一樣的
Private
>>> import test
>>> dir(test)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__pyarmor__', '__spec__', 'hello_world']有時候為了防止其他人透過 dir 偷看裡面的資訊,我們可以加上 --private 來防止透露一些 function 和 attribute 的資訊
pyarmor gen --private <path/to/script>
# Example
pyarmor gen --private test.py這時候我們跑看看 dir,就會出現 RuntimeError
>>> import test
>>> dir(test)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: unauthorized use of script (1:5174)Assert Call
>>> import test
>>> test.hello_world()
Hello World
>>> test.hello_world = lambda: print("Hacked")
>>> test.hello_world()
Hacked透過上面的方法,我們可以偷換裡面的 function,甚至繞過某些檢查機制,但我們可以加上 --assert-call 來防止這件事情
pyarmor gen --assert-call <path/to/script>
# Example
pyarmor gen --assert-call test.py接著再試一次,就出現 RuntimeError 了
>>> import test
>>> test.hello_world()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: unauthorized use of script (1:5174)
>>> dir(test)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: unauthorized use of script (1:5174)Package
如果是 package 需要加密,也是直接使用以下指令就可以了
pyarmor gen <path/to/package>
# Example
pyarmor gen test執行完後,你會看到產生出一個 dist 的資料夾,裡面有這個這樣的結構:
.
└── dist/
├── test/
│ ├── __init__.py
│ └── func.py
└── pyarmor_runtime_000000/
├── __init__.py
└── pyarmor_runtime.pyd如果你要直接 Release 給別人的話,可以直接將 dist 連同裡面所有檔案傳給別人就好了,對方不需要安裝 Pyarmor,只要用安裝相同版本的 Python 執行即可,作業系統也是需要是一樣的,但你會發現 test 和 pyarmor_runtime_000000 是分開的,這樣其實不太方便,也很容易放錯位置,所以可以在 obfuscating 的時候加上 -i,這樣 pyarmor_runtime_000000 就會被放到 test 裡面,這樣只要給別人 test 資料夾就可以了~
.
└── dist/
└── test/
├── __init__.py
├── func.py
└── pyarmor_runtime_000000/
├── __init__.py
└── pyarmor_runtime.pydRestrict
假設資料夾結構如下:
.
└── test/
├── __init__.py
├── func.py
└── utils.py然後 __init__.py 的檔案裡面有 import func,但沒有 import utils
from .func import hello_world我們直接執行,還是能透過 test 匯入 utils 並執行裡面的 function
>>> import test
>>> test.hello_world()
hello_world
>>> from test import utils
>>> utils.hello_world()
hello_world我們可以透過 --restrict 避免這種狀況
pyarmor gen -i --restrict <path/to/package>
# Example
pyarmor gen -i --restrict test這樣只有 __init__.py 不受限制,其餘 modules 對外面來說都是不可見的
>>> import test
>>> test.hello_world()
hello_world
>>> from test import utils
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<frozen test.utils>", line 3, in <module>
RuntimeError: unauthorized use of script (1:1125)Expire
Pyarmor 有提供設定有效期限的功能,可以設定有效天數或是指定的日期
pyarmor gen -e <days>/<date> <path/to/script>
# Example
pyarmor gen -e 2025-10-26 test.py
pyarmor gen -e 15 test.py 如果過期的話,會顯示以下的錯誤:
>>> import test
RuntimeError: this license key is expired (1:11086)Binding
Pyarmor 也還可以綁定裝置,透過讀取裝置的硬體資訊,可以綁定腳本到特定的機器上,防止使用者使用不合法的機器運行。我們可以透過下面的指令顯示當前機器的資訊,用於後續綁定
python -m pyarmor.cli.hdinfoMachine ID: 'xxxxxxxxxxxxxx'
Default Harddisk Serial Number: 'xxxxxxxxxxxxxx'
Multiple Mac addresses: xxxxxxxxxxxxxx
Domain: 'xxxxxxxxxxxxxx'我們可以透過以下指令綁定:
pyarmor gen -b <binding info> <path/to/script>
# Example
pyarmor gen -b 00:00:00:00:00:00 test.py 如果不是綁定的裝置的話,會顯示以下的錯誤:
>>> import test
RuntimeError: this license key is not for this machine (1:10166)Read-Only
>>> import test
>>> test.print_value()
Value = 10
>>> test.value = 1
>>> test.print_value()
Value = 1如果要防止有心人士偷改 attribute,最簡單的方式就是設定成 READ-ONLY 的模式,可以透過以下指令:
pyarmor cfg readonly_module=1重新混淆一次後,現在會出現 RunteimError 了
>>> import test
>>> test.print_value()
Value = 10
>>> test.value = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: protection exception (16782406)PyInstaller
我們一樣可以打包混淆過的 Python Script,記得先安裝 PyInstaller
pip install pyinstaller打包成 Single File
pyarmor gen --pack onefile <path/to/script>
# Example
pyarmor gen --pack onefile test.py打包成一個 Folder
pyarmor gen --pack onedir <path/to/script>
# Example
pyarmor gen --pack onedir test.pyReference
- https://github.com/dashingsoft/pyarmor
- https://pyarmor.dashingsoft.com/index-zh.html
- https://github.com/dashingsoft/pyarmor-webui
如果你覺得這篇文章有用 可以考慮贊助飲料給大貓咪




