メモめもメモ

環境構築やプログラミングに関するメモ

rdtsc命令とcpuid命令を使ったVM検知

cpuid命令をVM(Virtual Machine, 仮想マシン)環境で実行すると制御が一時的にVMM(Virtual Machine Monitor, 仮想マシンモニター)へ移るので、 物理マシン環境と比べて実行速度が遅くなります。 そのため、cpuid命令の実行速度をrdtsc命令などで計測することでVM検知を行うことができます。

コード(Visual C++用)

#include <stdio.h>

// VMならば1, そうでないならば0を返す
int cpuid_tsc_check()
{
    unsigned __int64 threshold = 750;

    unsigned __int64 i, loop = 10;
    unsigned __int64 avg, sum = 0;
    unsigned __int64 start, end;
    unsigned __int32 eax1, eax2, edx1, edx2;

    for (i = 0; i < loop; i++)
    {
        __asm {
            rdtsc;
            mov eax1, eax;
            mov edx1, edx;
        }
        start = ((unsigned __int64)edx1 << 32) | eax1;

        __asm {
            xor eax, eax;
            cpuid;
            rdtsc;
            mov eax2, eax;
            mov edx2, edx;
        }
        end = ((unsigned __int64)edx2 << 32) | eax2;

        sum += end - start;
    }
    
    avg = sum / loop;
    return avg > threshold ? 1 : 0;
}

// 使用例
int main(void)
{
    if (cpuid_tsc_check())
    {
        printf("このマシンはVMです。\n");
    }
    else
    {
        printf("このマシンはVMではありません。\n");
    }
    
    return 0;
}