
و Virtualizer Code X86-64 للاشتعال القائم على VM.
*دعم PE تم اختباره فقط على الثنائيات التي تم تجميعها عبر Mingw-W64
سيحضر CMake كل هذه التبعيات ، لذا فإن تثبيتها بنفسك ليس ضروريًا.
| اسم | إصدار |
|---|---|
| cmake | 3.25+ |
| زيديس | 4.1.0+ |
| Zasm | أحدث |
| lief | 0.15.1+ |
مطلوب برنامج مترجم C++23 من أجل البناء.
git clone https://github.com/dmaivel/covirt.git
cd covirt
mkdir build
cd build
cmake ..
cmake --build . --config Release إذا كنت تقوم بتجميع Windows عبر Visual Studio ، فيجب عليك استخدام clang-cl : cmake .. -T ClangCL -A x64 .
Usage: covirt [--help] [--version] [--output OUTPUT_PATH] [--vm_code_size MAX] [--vm_stack_size SIZE] [--no_self_modifying_code] [--no_mixed_boolean_arith] [--show_dump_table] INPUT_PATH
Code virtualizer for x86-64 ELF & PE binaries
Positional arguments:
INPUT_PATH path to input binary to virtualize
Optional arguments:
-h, --help shows help message and exits
-v, --version prints version information and exits
-o, --output OUTPUT_PATH specify the output file [default: INPUT_PATH.covirt]
-vcode, --vm_code_size MAX specify the maximum allowed total lifted bytes [default: 2048]
-vstack, --vm_stack_size SIZE specify the size of the virtual stack [default: 2048]
-no_smc, --no_self_modifying_code disable smc pass
-no_mba, --no_mixed_boolean_arith disable mba pass
-d, --show_dump_table show disassembly of the vm instructions لكي تعرف covirt أي وظائف يجب أن تكون افتراضية ، يجب عليك إضافة علامات البدء والنهاية إلى رمز المصدر الخاص بك ، مثل ذلك:
#include "covirt_stub.h"
int my_function (...)
{
int result = 0 ;
__covirt_vm_start ();
// ...
__covirt_vm_end ();
return result ;
}مهم
__covirt_vm_end في مواقع لا يمكن الوصول إليها (أي بعد العودة) ، لأنها ستمنع كعب النهاية من الانبعاث__covirt_vm_...(); لن تعمل كعباء باستخدام MSVC لأنها تستخدم التجميع المضمّنSSE4 مطلوب 
#include <covirt_stub.h>
#include <stdio.h>
int calculate ( int a , int b )
{
int result = 0 ;
__covirt_vm_start ();
for ( int i = 0 ; i < 10 ; i ++ )
if ( i > 5 )
result += result + a ;
else
result += ( result >> 1 ) + b ;
printf ( "result = %dn" , result );
__covirt_vm_end ();
return result ;
}
int main ()
{
calculate ( 5 , 12 );
} كان تطبيق المثال أعلاه افتراضيًا باستخدام covirt a.out -d ، والذي يخرج تفريغًا من تعليمات VM بعد التغلب والمحاكاة الافتراضية. يدفع تطبيق VM الحالي معظم المعاملات إلى المكدس لمعالجتها ، مما يقلل من تعقيد ترميز تعليمات VM. للحصول على التعليمات التي لا تحتوي على معالج VM محدد ، سيتم تنفيذها أصليًا ( vm_exit -> native instruction -> vm_enter ). تتبع وظائف الاتصال نفس خط الأنابيب ، الذي نخرج فيه ، ودعا الوظيفة ، وإعادة إدخال VM. جميعًا معًا ، تجعل التحولات الثنائيات تنمو بشكل كبير في الحجم:
a.out as ELF : 15.5 kb -> 1.0 mba.out كـ PE : 259.3 كيلو بايت -> 1.3 ميغابايت | وصف | IDA |
|---|---|
إيدا فك تشفير vm_entry ، الذي تم التغلب عليه عبر ممر ماجستير إدارة الأعمال فقط. تم إنشاء أكثر من 27K LOC بواسطة Decompiler. | ![]() |
تفكيك IDA من vm_entry ، والذي تم التغلب عليه عبر ممرات ماجستير إدارة الأعمال و SMC. إلغاء الإلغاء لا يعمل. | ![]() |