ByteCode Simplifierは、PJORION保護されたPythonスクリプトを除去するためのツールです。これは私の古いツールpjorion deobfuscatorの完全な書き直しです
次のパッケージを事前にインストールする必要があります。
両方のパッケージは、 pipインストール可能です。さらに、GraphViz実行可能ファイルがpydotplus機能するためのパスにあることを確認してください。 pydotplusグラフを描画するためにのみ必要です。この機能が必要な場合は、ファイルdeobfuscator.pyのdeobfuscate関数のrender_graph呼び出しにコメントすることができます。
PJORIONは元のファイルを難読化し、その上にいくつかのラッパー層を導入します。これらのレイヤーの目的は、単に次の内側のレイヤーを(ある種の)解読し、 EXEC_STMT命令を介して実行することです。したがって、このツールは難読化されたファイルでAS-ISを使用することはできません。まず、ラッパー層を削除し、実際の難読化コードオブジェクトを保持する必要があります。次に、難読化されたコードをディスクに登録して、このツールを実行することができます。
詳細については、このブログ投稿を参照してください。
ByteCode Simplifierは、再帰的トラバーサル分解アプローチを使用して、難読化されたコードを分析します。命令は分解され、基本的なブロックに結合されます。基本ブロックは、単一のエントリと単一の出口を備えた一連の命令です。
基本的なブロックは、 ifステートメントなどの制御フロー命令で終了する場合があります。 ifステートメントには2つのブランチがあります - 真とfalse。ブランチに対応する基本ブロックには、それらの間にエッジがあります。この構造全体は、指示されたグラフで表されます。この目的のためにnetworkx.DiGraphを使用します。
グラフのノードは基本ブロックを表しますが、ノード間のエッジは基本ブロック間の制御フローを表します。
ifような条件付き制御転送命令2つのブランチがあります - 条件が保持されたときに実行される真のブランチ。このブランチはifステートメントで明示的に指定されているため、このブランチに明示的なエッジとしてタグ付けします。もう一方のブランチ。偽のものは、論理的に推定されているため、暗黙のエッジとしてタグ付けされます。
jumpのような無条件の制御転送命令には、明示的なエッジしかありません。
グラフ形式にコードを作成したら、コードについて推論する方が簡単です。したがって、このグラフでは、難読化されたコードの簡素化が行われます。
主に2つの単純化戦略が使用されています。
フォワーダーは、単一の無条件の制御フロー命令で構成される基本的なブロックです。フォワーダーは、有用な作業を行わずに実行を他の基本ブロックに転送します。
フォワーダーの排除の前

黄色で強調表示されている基本的なブロックされたブロックは、フォワーダーブロックです。以下に次の構造を与えるために排除できます。
フォワーダーの除去後

ただし、フォワーダーが暗黙のエッジを持っている場合、フォワーダーを具体的に常に排除することはできません。詳細については、simplifier.pyを参照してください
正確に1つの前身があり、前身がその唯一の後継者としてこの基本的なブロックを持っている場合にのみ、基本的なブロックを前身に統合できます。
マージする前に

基本的なブロックの強調表示された指示は、以下に示すより大きな基本ブロックを形成するためにマージされています。コントロール転送命令は、もう必要ないため削除されました。
マージした後

グラフが簡素化されたら、基本ブロックをフラットコードに戻す必要があります。これは、ファイルassembler.pyに実装されています。
アセンブリプロセス自体は、サブステージで構成されています。
JUMP_FORWARD JUMP_ABSOLUTEに変更する:Basic Block AがBブロックBに相対的な制御フロー命令を持っている場合、生成されたレイアウトのブロックAの後にブロックBを配置する必要があります。これは、相対的な制御フロー命令が通常、その後にあるアドレスを参照するために使用されるためです。相対的なCF命令がJUMP_FORWARDの場合、 JUMP_ABSOLUTEに変更できます。SETUP_LOOP, SETUP_EXCEPTなどの他の相対的なCF命令については、ブロックBの絶対ジャンプ命令で構成される新しいフォワーダーブロックを作成し、ブロックAの相対的な制御フロー命令を転送ブロックに向けて作成する必要があります。フォワーダーブロックは自然に生成されたレイアウトのブロックAの後に行われるため、これは機能します。相対命令は常に使用されて、その後のブロックを指すことができます。つまり、より高いアドレスがあります。JUMP_FORWARD & SETUP_LOOPのような命令は、オペランドを使用して他の命令を参照します。この参照は、ターゲットのオフセット/絶対アドレスを示す整数です。 $ python main.py --ifile=obfuscated.pyc --ofile=deobfuscated.pyc
INFO:__main__:Opening file obfuscated.pyc
INFO:__main__:Input pyc file header matched
DEBUG:__main__:Unmarshalling file
INFO:__main__:Processing code object x0bx08x0cx19x0bx0ex03
DEBUG:deobfuscator:Code entrypoint matched PjOrion signature v1
INFO:deobfuscator:Original code entrypoint at 124
INFO:deobfuscator:Starting control flow analysis...
DEBUG:disassembler:Finding leaders...
DEBUG:disassembler:Start leader at 124
DEBUG:disassembler:End leader at 127
.
<snip>
.
DEBUG:disassembler:Found 904 leaders
DEBUG:disassembler:Constructing basic blocks...
DEBUG:disassembler:Creating basic block 0x27dc5a8 spanning from 13 to 13, both inclusive
DEBUG:disassembler:Creating basic block 0x2837800 spanning from 5369 to 5370, end exclusive
.
<snip>
.
DEBUG:disassembler:461 basic blocks created
DEBUG:disassembler:Constructing edges between basic blocks...
DEBUG:disassembler:Adding explicit edge from block 0x2a98080 to 0x2aa88a0
DEBUG:disassembler:Adding explicit edge from block 0x2aa80f8 to 0x2a9ab70
DEBUG:disassembler:Basic block 0x2aa8dc8 has xreference
.
<snip>
.
INFO:deobfuscator:Control flow analysis completed.
INFO:deobfuscator:Starting simplication of basic blocks...
DEBUG:simplifier:Eliminating forwarders...
INFO:simplifier:Adding implicit edge from block 0x2aa8058 to 0x2a9ab70
INFO:simplifier:Adding explicit edge from block 0x2b07ee0 to 0x2a9ab70
DEBUG:simplifier:Forwarder basic block 0x2aa80f8 eliminated
.
<snip>
.
INFO:
INFO:simplifier:307 basic blocks merged.
INFO:deobfuscator:Simplication of basic blocks completed.
INFO:deobfuscator:Beginning verification of simplified basic block graph...
INFO:deobfuscator:Verification succeeded.
INFO:deobfuscator:Assembling basic blocks...
DEBUG:assembler:Performing a DFS on the graph to generate the layout of the blocks.
DEBUG:assembler:Morphing some JUMP_ABSOLUTE instructions to make file decompilable.
DEBUG:assembler:Verifying generated layout...
INFO:assembler:Basic block 0x2b0e940 uses a relative control transfer instruction to access block 0x2abb3a0 located before it.
INFO:assembler:Basic block 0x2ab5300 uses a relative control transfer instruction to access block 0x2ada918 located before it.
DEBUG:assembler:Successfully verified layout.
DEBUG:assembler:Calculating addresses of basic blocks.
DEBUG:assembler:Calculating instruction operands.
DEBUG:assembler:Generating code...
INFO:deobfuscator:Successfully assembled.
INFO:__main__:Successfully deobfuscated code object main
INFO:__main__:Collecting constants for code object main
INFO:__main__:Generating new code object for main
INFO:__main__:Generating new code object for x0bx08x0cx19x0bx0ex03
INFO:__main__:Writing deobfuscated code object to disk
INFO:__main__:Success