BitVisor
BitVisorDay 10

BitVisorでCPUID命令の挙動を変える

More than 1 year has passed since last update.

BitVisorを書き換えて、仮想マシン上のCPUID命令の挙動を変える方法を紹介します。


コードの場所

CPUID命令が仮想マシン上で実行されると、いろんなところを通って、core/cpuid_pass.cのdo_cpuid_pass()関数というのが呼び出されます。この関数は、CPUID命令を実行して、その結果を一部改竄して返しています。改竄の内容は、主に、未実装の機能を隠蔽するものです。


core/cpuid_pass.c

static void

do_cpuid_pass (u32 ia, u32 ic, u32 *oa, u32 *ob, u32 *oc, u32 *od)

この関数を書き換えることで、CPUID命令の挙動を変えることができます。この関数のiaとicにそれぞれ%eax, %ecxレジスターの値が渡され、この関数はCPUID命令の実行結果の%eax, %ebx, %ecx, %edxレジスターの値をそれぞれoa, ob, oc, odポインターが指す領域に格納します。


書き換え例


実装例

ここでは、"GenuineIntel"を"AuthenticAMD"に書き換えるだけの簡単な例を示します。(タブがスペースになっていますので試す時にはご注意ください。)

diff --git a/core/cpuid_pass.c b/core/cpuid_pass.c

--- a/core/cpuid_pass.c
+++ b/core/cpuid_pass.c
@@ -42,6 +42,11 @@ do_cpuid_pass (u32 ia, u32 ic, u32 *oa,
else
asm_cpuid (CPUID_EXT_0, 0, &tmpa, &tmpb, &tmpc, &tmpd);
asm_cpuid (ia, ic, oa, ob, oc, od);
+ if (!ia) {
+ *ob += -217706502;
+ *oc += -672674571;
+ *od += 537853948;
+ }
if (tmpa >= 1 && ia == 1) {
/* *ob &= ~CPUID_1_EBX_NUMOFLP_MASK; */
/* *ob |= ~CPUID_1_EBX_NUMOFLP_1; */


実行例

iMac Mid-2014での実行例を示します。Ubuntu 16.04で確認しています。

$ head -5 /proc/cpuinfo 

processor : 0
vendor_id : AuthenticAMD
cpu family : 6
model : 69
model name : Intel(R) Core(TM) i5-4260U CPU @ 1.40GHz

AMD! AMD! (model nameはそのままですが...)