๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿฆพ ๋ณด์•ˆ ๐Ÿฆพ/๋žœ์„ฌ์›จ์–ด

[๋žœ์„ฌ์›จ์–ด] CPU ๋ฒค๋”๋ฅผ ํ†ตํ•œ ๊ฐ€์ƒ๋จธ์‹  ์‹คํ–‰ ์—ฌ๋ถ€ ํ™•์ธ

๋ฐ˜์‘ํ˜•

๊ฐ€์ƒ๋จธ์‹ (Virtual Machine)์ด๋ž€?

๊ฐ€์ƒ ๋จธ์‹ ์€ ํ•˜๋‚˜์˜ ๋ฌผ๋ฆฌ์  ์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ ์•ˆ์—์„œ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋…๋ฆฝ์ ์ธ ๊ฐ€์ƒ ์ปดํ“จํ„ฐ ํ™˜๊ฒฝ์„ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ์ด ๊ฐ€์ƒ ๋จธ์‹ ๋“ค์€ ๊ฐ๊ฐ ๋…๋ฆฝ์ ์ธ ์šด์˜์ฒด์ œ ๋ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์ƒ ๋จธ์‹ ์€ ํ•˜์ดํผ๋ฐ”์ด์ €(Hypervisor)๋ผ๋Š” ์†Œํ”„ํŠธ์›จ์–ด ๊ณ„์ธต์„ ํ†ตํ•ด ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์˜ ํ•˜๋“œ์›จ์–ด ์ž์›์„ ๋ถ„ํ• ํ•˜๊ณ  ๊ฐ ๊ฐ€์ƒ ๋จธ์‹ ์— ํ• ๋‹นํ•˜์—ฌ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

CPU ๋ฒค๋”๋ž€?

CPU ๋ฒค๋”๋Š” CPU(์ค‘์•™ ์ฒ˜๋ฆฌ ์žฅ์น˜)๋ฅผ ์ œ์กฐํ•˜๋Š” ํšŒ์‚ฌ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ๋ฒค๋”๋Š” ๊ณ ์œ ์˜ ๋ฒค๋” ID๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด CPU๊ฐ€ ์–ด๋ŠํšŒ์‚ฌ์—์„œ ์ œ์กฐ๋˜์—ˆ๋Š”์ง€๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€์ƒ ํ™˜๊ฒฝ์—์„œ๋Š” ๊ฐ€์ƒ ๋จธ์‹ ์˜ ํ•˜์ดํผ๋ฐ”์ด์ €(ex: VMware, VirtualBox ๋“ฑ)๊ฐ€ ์‹ค์ œ ๋ฌผ๋ฆฌ์  CPU๋ฅผ ์—๋ฎฌ๋ ˆ์ดํŠธํ•˜๊ฑฐ๋‚˜ pass-through ํ˜•ํƒœ๋กœ ์ œ๊ณตํ•˜์ง€๋งŒ, ์ด๋ฅผ ํ†ตํ•ด CPU ๋ฒค๋” ID๋ฅผ ํฌํ•จํ•œ ๋‹ค์–‘ํ•œ ํ•˜๋“œ์›จ์–ด ์ •๋ณด๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐ€์ƒ ํ™˜๊ฒฝ์—์„œ๋„ ํŠน์ • ๋ฒค๋” ID๊ฐ€ ์กด์žฌํ•˜๋ฉฐ, ํ•˜์ดํผ๋ฐ”์ด์ €์— ๋”ฐ๋ผ ์ด๋Ÿฌํ•œ ์ •๋ณด๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CPU ๋ฒค๋” ๋ฒค๋” ID
Intel GenuineIntel
AMD AuthenticAMD
VIA Technologies CentaurHauls
Transmeta GenuineTMx86
VMware VMwareVMware
VirtualBox VirtualBox
Microsoft Hyper-V Microsoft Hv

 

๊ฐ€์ƒ ๋จธ์‹  ์‹คํ–‰ ์—ฌ๋ถ€ ํ™•์ธ

์•ž์„œ ์ •๋ฆฌํ•œ CPU ๋ฒค๋” ID๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ์Šคํ…œ์ด ๊ฐ€์ƒ ๋จธ์‹ ์—์„œ ์‹คํ–‰ ์ค‘์ธ์ง€ cpp ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. intrin.h ํ—ค๋” ํŒŒ์ผ์— ์ •์˜๋œ __cpuid ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • __cpuid(info, function_id): intrin.h ํ—ค๋” ํŒŒ์ผ์— ์ •์˜๋œ ํ•จ์ˆ˜๋กœ, function_id ๊ฐ’์— ๋”ฐ๋ผ cpuid ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ info ๋ฐฐ์—ด์— EAX, EBX, ECX, EDX ๋ ˆ์ง€์Šคํ„ฐ์˜ ๊ฐ’์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์ด ๋™์ž‘ํ•˜๊ณ  ์žˆ๋Š” ์‹œ์Šคํ…œ์˜ ๋ฒค๋” ID๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

#include <iostream>
#include <array>
#include <intrin.h>

void cpuid(int info[4], int function_id) {
    __cpuid(info, function_id);
}

int main() {
    std::array<int, 4> cpui;
    cpuid(cpui.data(), 0);
    std::cout << "Vendor ID: "
              << std::string(reinterpret_cast<const char*>(&cpui[1]), 12) << std::endl;
    return 0;
}

 

์ฝ”๋“œ๋ฅผ ํ™•์žฅํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์ด ๊ฐ€์ƒ๋จธ์‹ ์—์„œ ์‹คํ–‰์ค‘์ธ์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

#include <iostream>
#include <array>
#include <intrin.h>

bool checkCpuVendor(const char* vendor) {
    std::array<int, 4> cpui;
    __cpuid(cpui.data(), 0);
    char vendor_id[13];
    memcpy(vendor_id, &cpui[1], 4);  // EBX
    memcpy(vendor_id + 4, &cpui[3], 4);  // EDX
    memcpy(vendor_id + 8, &cpui[2], 4);  // ECX
    vendor_id[12] = '\\0';
    return strcmp(vendor_id, vendor) == 0;
}

bool checkVirtualEnvironment() {
    // Check common CPU vendors used by virtual environments
    if (checkCpuVendor("KVMKVMKVM") || checkCpuVendor("Microsoft Hv") || checkCpuVendor("VMwareVMware")) {
        return true;
    }

    // Check for hypervisor bit
    std::array<int, 4> cpui;
    __cpuid(cpui.data(), 1);
    bool isHypervisor = cpui[2] & (1 << 31);
    if (isHypervisor) {
        return true;
    }

    return false;
}

int main() {
    if (checkVirtualEnvironment()) {
        std::cout << "This system is running in a virtual environment." << std::endl;
    } else {
        std::cout << "This system is not running in a virtual environment." << std::endl;
    }
    return 0;
}

๊ฒฐ๋ก 

์ตœ์‹  ๋žœ์„ฌ์›จ์–ด๋Š” ๊ฐ€์ƒ๋จธ์‹ ์—์„œ์˜ ๋ถ„์„์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ํ˜„์žฌ ์‹œ์Šคํ…œ CPU ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜์—ฌ ์‹คํ–‰์„ ๊ฒฐ์ •ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๊ฐ€์ƒ๋จธ์‹ ์—์„œ์˜ ํƒ์ง€๋ฅผ ํ”ผํ•˜๊ณ  ๋ณด์•ˆ ์—ฐ๊ตฌ์ž๋“ค์ด ๋ถ„์„ํ•˜๊ณ  ๋Œ€์‘ํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•