pyobfuscate
これが必要な理由は、このツールを使用して Python コードを難読化したいからです。ただしpyobfuscate
、難読化できるファイルは 1 つだけです。
4 に答える
モジュールのツリーを単一のモジュールに変換する方法は間違いなくあります。しかし、それは些細なことではありません。私が考えることができる最も簡単なことはこれです:
まず、モジュールのリストが必要です。これは、find
コマンドまたはos.walk
.
次に、grep
または Pythonre
を使用して各ファイル内のすべてのインポート ステートメントを取得し、それを使用してモジュールをトポロジ的に並べ替える必要があります。import foo
トップレベルで絶対フラットステートメントのみを実行する場合、これは自明な正規表現です。絶対パッケージのインポート、またはfrom foo import bar
(またはfrom foo import *
)、または他のレベルでのインポートも行う場合、それほどトリッキーではありません。相対的なパッケージのインポートは少し難しいですが、それほど大したことではありません。もちろん、動的インポートを行う場合、imp
モジュールを使用する場合、インポート フックをインストールする場合などは、ここでは運が悪いですが、そうならないことを願っています。
次に、実際の import ステートメントを置き換える必要があります。上記と同じ仮定で、これは単純なsed
or re.sub
、 with のようなものimport\s+(\w+)
で行うことができます\1 = sys.modules['\1']
。
ここで、難しい部分として、各モジュールを、同等のモジュール オブジェクトを動的に作成するものに変換する必要があります。これは難しい部分です。あなたがしたいことは、モジュールコード全体をエスケープして、トリプルクォートで囲まれた文字列に入れることができるようにしてから、これを行うことだと思います:
import types
mod_globals = {}
exec('''
# escaped version of original module source goes here
''', mod_globals)
mod = types.ModuleType(module_name)
mod.__dict__.update(mod_globals)
sys.modules[module_name] = mod
これらの変換されたモジュールをすべて連結するだけです。結果は元のコードとほぼ同じになりますがimport foo; del foo
、開始時にすべてのモジュールに対して (依存関係の順序で) 同等の処理を行うため、起動時間が少し遅くなる可能性があります。
私はあなたの直接の質問に個別に答えましたが、あなたが実際にやろうとしていると思われることとは別の解決策を提供させてください:
難読化されたソースを出荷する代わりに、バイトコード ファイルだけを出荷します。これらは自動的に作成、キャッシュ、使用されるファイルですが、標準ライブラリのモジュール.pyc
を使用するだけで手動で作成することもできます。compileall
.pyc
ファイルが見つから.py
ないファイルは問題なくインポートできます。そのままでは人間が読めるものではありません。もちろん、Python ソースに逆コンパイルすることもできますが、結果は… 基本的に、元のソースで難読化ツールを実行した場合と同じ結果になります。つまり、あなたがやろうとしていることよりもわずかに優れており、はるかに簡単です。
この方法でトップレベルのスクリプトをコンパイルすることはできませんが、回避するのは簡単です。import
実際のトップレベル スクリプト以外は何もしないワンライナー ラッパー スクリプトを作成するだけです。そこにコードがある場合if __name__ == '__main__':
は、それも関数に移動する必要があります。ラッパーは、モジュールをインポートして関数を呼び出す 2 つのライナーになります...しかし、それは非常に困難です。)または、実行することもできます。トップレベルのスクリプトだけでpyobfuscatorを実行しますが、実際にはそうする理由はありません。
実際、簡単なトップレベル ラッパーを作成することを除いて、パッケージャー ツールの多くは、必要に応じて、このすべての作業を自動的に行うことができます。たとえば、デフォルトpy2app
ビルドは、独自のモジュールのコンパイル済みバージョンを、依存する stdlib およびサイト パッケージ モジュールと共にpythonXY.zip
アプリ バンドル内のファイルに貼り付け、その zip ファイルを stdlib として使用するように組み込みインタープリターをセットアップします。