covirt
1.0.0

VMベースの難読化のためのX86-64コード仮想イザー。
*MINGW-W64を介してコンパイルされたバイナリでのみテストされたPEサポート
CMakeこれらすべての依存関係を取得するため、自分でインストールする必要はありません。
| 名前 | バージョン |
|---|---|
| cmake | 3.25+ |
| Zydis | 4.1.0+ |
| ZASM | 最新 |
| リーフ | 0.15.1+ |
構築するには、 C++23互換性のあるコンパイラが必要です。
git clone https://github.com/dmaivel/covirt.git
cd covirt
mkdir build
cd build
cmake ..
cmake --build . --config Release Visual Studioを介してWindowsでコンパイルしている場合は、 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 instructionscovirt仮想化する必要がある関数を知るには、SOURESコードにスタートマーカーとエンドマーカーを追加する必要があります。
#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に再入力します。すべて一緒に、変換により、バイナリのサイズが大幅に増加します。
ELFとしてのa.out :15.5 kb-> 1.0 mbPEとしてのa.out :259.3 kb-> 1.3 Mb | 説明 | アイダ |
|---|---|
MBAパスのみを介して難読化されているvm_entryのIDAの逆コンパイル。 27k以上のlocが分解者によって生成されました。 | ![]() |
MBA&SMCパスを介して難読化されているvm_entryのIDA分解。逆コンパイルが機能しません。 | ![]() |