
x86-64用コード仮想化ツール(VMベースの難読化)
| 名前 | バージョン |
|---|
| CMake | 3.25+ |
| Zydis | 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 仮想化する入力バイナリへのパス
Optional arguments:
-h, --help ヘルプメッセージを表示して終了
-v, --version バージョン情報を表示して終了
-o, --output OUTPUT_PATH 出力ファイルを指定 [デフォルト: INPUT_PATH.covirt]
-vcode, --vm_code_size MAX リフトされたバイトの最大許容合計を指定 [デフォルト: 2048]
-vstack, --vm_stack_size SIZE 仮想スタックのサイズを指定 [デフォルト: 2048]
-no_smc, --no_self_modifying_code SMCパスを無効化
-no_mba, --no_mixed_boolean_arith MBAパスを無効化
-d, --show_dump_table VM命令の逆アセンブルを表示
covirt がどの関数を仮想化する必要があるかを認識するためには、以下のようにソースコードに開始マーカーと終了マーカーを追加する必要があります:
#include "covirt_stub.h"
int my_function(...)
{
int result = 0;
__covirt_vm_start();
// ...
__covirt_vm_end();
return result;
}
[!IMPORTANT]
__covirt_vm_endを到達不可能な場所(return の後など)に配置しないでください。エンドスタブが生成されなくなります。__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 = %d\n", 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を抜けて関数を呼び出し、VMに再入します。これらの変換により、バイナリのサイズが大幅に増加します。
a.out as an ELF: 15.5 kB -> 1.0 MBa.out as a PE: 259.3 kB -> 1.3 MB| 説明 | IDA |
|---|---|
MBAパスのみで難読化された vm_entry のIDA逆コンパイル。デコンパイラによって27,000行以上のコードが生成されました。 | ![]() |
MBAおよびSMCパスで難読化された vm_entry のIDA逆アセンブル。逆コンパイルは機能しません。 | ![]() |