
Virtualisasi kode X86-64 untuk Kebingungan Berbasis VM.
*Dukungan PE hanya diuji pada binari yang dikompilasi melalui Mingw-W64
CMake akan mengambil semua dependensi ini, jadi memasangnya sendiri tidak perlu.
| Nama | Versi |
|---|---|
| Cmake | 3.25+ |
| Zydis | 4.1.0+ |
| ZASM | Terbaru |
| LEBIH SUKA | 0.15.1+ |
Kompiler kompatibel C++23 diperlukan untuk membangun.
git clone https://github.com/dmaivel/covirt.git
cd covirt
mkdir build
cd build
cmake ..
cmake --build . --config Release Jika Anda menyusun pada jendela melalui Visual Studio, Anda harus menggunakan 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 Agar covirt mengetahui fungsi mana yang perlu divirtualisasi, Anda harus menambahkan penanda awal dan akhir ke dalam kode sumber Anda, seperti itu:
#include "covirt_stub.h"
int my_function (...)
{
int result = 0 ;
__covirt_vm_start ();
// ...
__covirt_vm_end ();
return result ;
}Penting
__covirt_vm_end di lokasi yang tidak dapat dijangkau (yaitu setelah kembali), karena akan mencegah stub akhir memancarkan__covirt_vm_...(); Stubs tidak akan berfungsi menggunakan MSVC karena mereka menggunakan perakitan inlineSSE4 diperlukan 
#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 );
} Contoh aplikasi di atas divirtualisasi menggunakan covirt a.out -d , yang menghasilkan dump instruksi VM setelah kebingungan dan virtualisasi. Implementasi VM saat ini mendorong sebagian besar operan ke tumpukan untuk memprosesnya, mengurangi kompleksitas pengkodean instruksi VM. Untuk instruksi yang tidak memiliki penangan VM yang ditentukan, mereka akan dieksekusi secara asli ( vm_exit -> native instruction -> vm_enter ). Fungsi panggilan mengikuti pipa yang sama, di mana kami keluar, memanggil fungsi, dan masuk kembali ke VM. Secara keseluruhan, transformasi membuat binari tumbuh secara signifikan dalam ukuran:
a.out sebagai ELF : 15,5 kb -> 1.0 MBa.out sebagai PE : 259,3 kb -> 1,3 MB | Keterangan | Ida |
|---|---|
Dekompilasi IDA vm_entry , yang telah dikaburkan melalui MBA Pass saja. Lebih dari 27k LOC dihasilkan oleh dekompiler. | ![]() |
Ida Disassembly of vm_entry , yang telah dikaburkan melalui MBA & SMC pass. Dekompilasi tidak berhasil. | ![]() |