Bytecode Simplifier هو أداة لإزالة البرامج النصية Python المحمية Pjorion المحمية. هذه إعادة كتابة كاملة لأدواتي القديمة Pjorion deobfuscator
تحتاج إلى الحصول على الحزم التالية مثبتة مسبقًا:
كل من الحزم قابلة للتثبيت pip . بالإضافة إلى ذلك ، تأكد من أن GraphViz executive هو في طريقك ل pydotplus للعمل. pydotplus مطلوب فقط لرسم الرسوم البيانية ، وإذا كنت لا تريد هذه الميزة ، يمكنك التعليق على مكالمات render_graph في وظيفة deobfuscate في ملف deobfuscator.py
Pjorion يعشق الملف الأصلي ويقدم العديد من طبقات التفاف فوقه. الغرض من هذه الطبقات هو ببساطة (نوع من) فك تشفير الطبقة الداخلية التالية وتنفيذها عبر تعليمات EXEC_STMT . وبالتالي ، لا يمكنك استخدام هذه الأداة كما هي على ملف محشور. أولاً ، ستحتاج إلى إزالة طبقات الغلاف والاحتفاظ بكائن الكود الفعلي. بعد ذلك ، يمكنك تنشئة الكود المتفوق على القرص وتشغيل هذه الأداة عليها والتي نأمل أن يعيدك رمز deobfusced.
الرجوع إلى منشور المدونة هذا للحصول على التفاصيل.
Bytecode Simplifier يحلل الكود المفرط باستخدام نهج تفكيك التوقيت المتكرر. يتم تفكيك التعليمات ودمجها في الكتل الأساسية. الكتلة الأساسية هي سلسلة من التعليمات مع إدخال واحد وخروج واحد.
قد تنتهي الكتلة الأساسية بتعليمات تدفق التحكم مثل عبارة if . بيان if له فرعين - صحيح وكاذب. المقابلة للفروع الكتل الأساسية لها حواف بينهما. ويمثل هذا الهيكل بأكمله برسم بياني موجه. نستخدم networkx.DiGraph لهذا الغرض.
تمثل العقد في الرسم البياني الكتل الأساسية في حين تمثل الحواف بين العقد تدفق التحكم بين الكتل الأساسية.
تعليمات نقل التحكم المشروطة مثل if كان له فرعين - الفرع الحقيقي الذي يتم تنفيذه عند استمرار الشرط. نقوم بتمييز هذا الفرع باعتباره الحافة الصريحة حيث يتم تحديد هذا الفرع بشكل صريح من خلال العبارة if . الفرع الآخر بمعنى. يتم وضع علامة على واحدة خاطئة على أنها حافة ضمنية ، حيث يتم استخلاصها منطقياً.
تعليمات نقل التحكم غير المشروطة مثل jump لها حافة صريحة فقط.
بمجرد أن يكون لدينا الرمز في نموذج الرسم البياني ، يكون من الأسهل التفكير في الكود. وبالتالي يتم تبسيط الكود المتفوق على هذا الرسم البياني.
يتم استخدام استراتيجيتين للتبسيط بشكل أساسي:
المهاجم عبارة عن كتلة أساسية تتكون من تعليمات تدفق تحكم واحدة غير مشروطة. يقوم المهاجم بنقل التنفيذ إلى كتلة أساسية أخرى دون القيام بأي عمل مفيد.
قبل التوجيه

الحظر الأساسي المبرز باللون الأصفر هو كتلة توجيه. يمكن القضاء عليها لإعطاء الهيكل التالي أدناه.
بعد التوجيه

ومع ذلك ، لا يمكن دائمًا التخلص من الشحن على وجه التحديد في الحالات التي يكون فيها الشحن في الحواف ضمنية. الرجوع إلى simplifier.py للحصول على التفاصيل
يمكن دمج كتلة أساسية على سابقتها إذا وفقط إذا كان هناك سلف واحد بالضبط ، يكون للسلف هذه الكتلة الأساسية كخليفة وحيد.
قبل الدمج

تم دمج التعليمات المميزة للكتل الأساسية لتشكيل كتلة أساسية أكبر موضحة أدناه. تمت إزالة تعليمات نقل التحكم حيث لم تعد هناك حاجة إليها.
بعد الاندماج

بمجرد تبسيط الرسم البياني ، نحتاج إلى تجميع الكتل الأساسية مرة أخرى في الرمز المسطح. يتم تنفيذ هذا في ملفات الملفات.
تتكون عملية التجميع في حد ذاتها من المراحل الفرعية:
JUMP_FORWARD إلى JUMP_ABSOLUTE : إذا كانت الكتلة الأساسية A لها تعليمات تدفق تحكم نسبية إلى الحظر B ، فيجب أن تكون الكتلة B موجودة بعد الكتلة A في التصميم الذي تم إنشاؤه. وذلك لأن تعليمات تدفق التحكم النسبية تستخدم عادة للإشارة إلى العناوين الموجودة بعد ذلك. إذا كانت تعليمات CF النسبية هي JUMP_FORWARD فيمكننا التغيير إلى JUMP_ABSOLUTE .SETUP_LOOP, SETUP_EXCEPT ، نحتاج إلى إنشاء كتلة توجيهية جديدة تتكون من تعليمات القفز المطلقة للكتلة 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