Windows Loader on KVM Guest

สืบเนื่องจากมีลูกค้าดันอยากได้ Windows VPS ไอ่เราก็โอเค server ตูมี KVM เฟร้ย
เลยจัดการสร้าง VM แล้วลง OS ตามปกติ พอลงเสร็จก็ update และ windows loader ตามสูตร
จากนั้น reboot ทีนึงหวังว่าจะส่งมอบให้ลูกค้าได้ละแต่ทว่า…

ชิบหาย boot ไม่ขึ้น
เราก็นึกในใจตายห่าละเป็นไรวะ นั่งงมอากู๋อยู่ตั้งนานได้ความมาว่า
ไอ่ KVM เนี่ย มันใช้ seabios ซึ่งไม่สนับสนุน Windows Loader ที่ crack ผ่่านการหลอก SLIC
ทำให้ Windows Activate เป็น OEM ได้ เพราะ seabios มันไม่ support… เออ ง่ายเนอะ

ทีนี้จะทำยังไงดีล่ะ ค้นอากู๋ต่อไปก็ไปเจอกับ hacker ผู้น่ารักบอกว่า
ให้ dump SLIC จากบอร์ดของเครื่องที่มี license oem มา
แล้วเอาไป patch ใส่ seabios compile ใหม่… แล้วตูจะไปเอา SLIC มาจากไหน(ฟระ)

แท่นแท๊นนนน จากนี่ไง

static char SLIC[] = {
0x53, 0x4c, 0x49, 0x43, 0x76, 0x01, 0x00, 0x00, 0x01, 0x2f, 0x47, 0x42,
0x54, 0x20, 0x20, 0x20, 0x47, 0x42, 0x54, 0x55, 0x41, 0x43, 0x50, 0x49,
0x01, 0x00, 0x00, 0x00, 0x4d, 0x53, 0x46, 0x54, 0x40, 0x42, 0x0f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00,
0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x01, 0x00, 0xbf, 0x89, 0x52, 0xfd, 0x37, 0x4b, 0xc9, 0x81,
0x97, 0xa1, 0xc3, 0xb7, 0x35, 0xb5, 0xe2, 0x55, 0x96, 0xf6, 0x8c, 0xef,
0x6f, 0xe8, 0xb0, 0xf8, 0x15, 0x7b, 0x8d, 0xa0, 0x65, 0xc4, 0x61, 0xb3,
0x18, 0x39, 0x32, 0xb9, 0x9c, 0x74, 0xe3, 0xc5, 0xe1, 0x4f, 0xcc, 0xd6,
0x1e, 0x67, 0x21, 0x36, 0x95, 0x27, 0xb6, 0x6a, 0x3b, 0x9e, 0x78, 0x08,
0x64, 0xa3, 0x26, 0x81, 0x91, 0x49, 0x64, 0x9b, 0x1c, 0xec, 0xd0, 0x29,
0x8c, 0x68, 0xa9, 0x2e, 0x29, 0xe8, 0x7f, 0xbd, 0xff, 0xe1, 0x22, 0xd3,
0x73, 0x8e, 0x21, 0x2b, 0xe1, 0x16, 0xe8, 0x19, 0x1f, 0x18, 0xa3, 0xb4,
0x6f, 0x66, 0x0e, 0x78, 0xf1, 0xe3, 0x1f, 0x73, 0x90, 0xaf, 0xa8, 0xb7,
0xc3, 0x57, 0x5a, 0x34, 0x2e, 0xf9, 0x66, 0x1e, 0x3c, 0xbf, 0x10, 0x63,
0x57, 0x50, 0x88, 0x6b, 0xc9, 0xf6, 0xac, 0x21, 0xbe, 0x8d, 0x97, 0xc2,
0x01, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
0x47, 0x42, 0x54, 0x20, 0x20, 0x20, 0x47, 0x42, 0x54, 0x55, 0x41, 0x43,
0x50, 0x49, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x20, 0x01, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x17, 0xc8, 0xe2, 0x08, 0x86,
0xa2, 0x97, 0xa0, 0x7b, 0x2f, 0xf2, 0x27, 0x46, 0xfe, 0x8e, 0x59, 0x3f,
0x83, 0xdb, 0x87, 0x79, 0x3a, 0x39, 0xc9, 0x2c, 0x9a, 0x40, 0xb0, 0xce,
0xa8, 0xdb, 0xfe, 0xcf, 0xe7, 0x03, 0x3c, 0xe0, 0x0e, 0x6d, 0x7d, 0x0b,
0x25, 0x74, 0x0f, 0xe1, 0x1e, 0x7c, 0x45, 0x47, 0x33, 0xd7, 0xab, 0x28,
0x9f, 0x05, 0x40, 0x31, 0x2d, 0x71, 0x30, 0x19, 0xac, 0x7a, 0x10, 0xaf,
0xb8, 0xa9, 0x3a, 0x05, 0x49, 0xbe, 0x73, 0x03, 0x48, 0xf0, 0x0a, 0xd1,
0x21, 0x02, 0xb8, 0x05, 0x83, 0x4e, 0xbb, 0x58, 0xfa, 0xc9, 0xa3, 0x82,
0xb5, 0xe0, 0x2a, 0x77, 0x8e, 0x10, 0x04, 0x02, 0x4b, 0x73, 0xf5, 0x11,
0xc7, 0xbb, 0xc5, 0x34, 0x9b, 0xe0, 0xc0, 0xc2, 0xbe, 0x0f, 0xbf, 0x23,
0x40, 0x53, 0x20, 0x85, 0x42, 0x41, 0xcc, 0x8c, 0x2a, 0xef, 0xda, 0x58,
0x5c, 0xdb
};

แล้วก็ seabios patch

diff –git a/src/acpi.c b/src/acpi.c
index 6428d9c..10ce5e8 100644
— a/src/acpi.c
+++ b/src/acpi.c
@@ -198,6 +198,11 @@ struct srat_memory_affinity
#include “acpi-dsdt.hex”
+#define CONFIG_OEM_SLIC
+#ifdef CONFIG_OEM_SLIC
+#include “acpi-slic.hex”
+#endif
+
static void
build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
{
@@ -210,6 +215,10 @@ build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
memcpy(h->oem_table_id + 4, (void*)&sig, 4);
h->oem_revision = cpu_to_le32(1);
h->asl_compiler_revision = cpu_to_le32(1);
+#ifdef CONFIG_OEM_SLIC
+ if (sig == RSDT_SIGNATURE) // only RSDT is checked by win7 & vista
+ memcpy(h->oem_id, ((struct acpi_table_header*)SLIC)->oem_id, 14);
+#endif
h->checksum -= checksum(h, len);
}
@@ -626,6 +635,17 @@ acpi_bios_init(void)
ACPI_INIT_TABLE(build_hpet());
ACPI_INIT_TABLE(build_srat());
+#ifdef CONFIG_OEM_SLIC
+ { void *buf = malloc_high(sizeof(SLIC));
+ if (!buf)
+ warn_noalloc();
+ else {
+ memcpy(buf, SLIC, sizeof(SLIC));
+ ACPI_INIT_TABLE(buf);
+ }
+ }
+#endif
+
u16 i, external_tables = qemu_cfg_acpi_additional_tables();
for(i = 0; i < external_tables; i++) {
diff –git a/src/ahci.c b/src/ahci.c
index b820e28..9c4315f 100644
— a/src/ahci.c
+++ b/src/ahci.c
@@ -408,7 +408,6 @@ static void
ahci_detect(void *data)
{
struct ahci_ctrl_s *ctrl = data;
– struct ahci_port_s *port;
u32 pnr, max;
int rc;
@@ -422,7 +421,7 @@ ahci_detect(void *data)
dprintf(1, “AHCI/%d: link %sn”, pnr, rc == 0 ? “up” : “down”);
if (rc != 0)
continue;
– port = ahci_port_init(ctrl, pnr);
+ ahci_port_init(ctrl, pnr);
}
}
diff –git a/src/bregs.h b/src/bregs.h
index 9a381d0..f026fa8 100644
— a/src/bregs.h
+++ b/src/bregs.h
@@ -37,9 +37,9 @@
struct bregs {
u16 ds;
u16 es;
– UREG(edi, di, di_hi, di_lo);
– UREG(esi, si, si_hi, si_lo);
– UREG(ebp, bp, bp_hi, bp_lo);
+ UREG(edi, di, di8u, di8l);
+ UREG(esi, si, si8u, si8l);
+ UREG(ebp, bp, bp8u, bp8l);
UREG(ebx, bx, bh, bl);
UREG(edx, dx, dh, dl);
UREG(ecx, cx, ch, cl);

จากนั้น make ตามปกติก็จะได้ bios.bin อันใหม่มา เอาไปไว้ใน /usr/share/kvm
แล้วก็กดโลด รอบนี้ activate ได้แถมไม่ต้อง reboot อีกตะหาก เยี่ยม = =b

Leave a Reply

Your email address will not be published. Required fields are marked *