#!/usr/bin/env ruby # This file is part of Metasm, the Ruby assembly manipulation suite # Copyright (C) 2007 Yoann GUILLOT # # Licence is LGPL, see LICENCE in the top-level directory # # this sample shows the compilation of a slightly more complex program # it displays in a messagebox the result of CPUID # require 'metasm' pe = Metasm::PE.assemble Metasm::Ia32.new, < #include static char *featureinfo[32] = { "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", "unk10", "sep", "mtrr", "pge", "mca", "cmov", "pat", "pse36", "psn", "clfsh", "unk20", "ds", "acpi", "mmx", "fxsr", "sse", "sse2", "ss", "htt", "tm", "unk30", "pbe" }, *extendinfo[32] = { "sse3", "unk1", "unk2", "monitor", "ds-cpl", "unk5-vt", "unk6", "est", "tm2", "unk9", "cnxt-id", "unk12", "cmpxchg16b", "unk14", "unk15", "unk16", "unk17", "unk18", "unk19", "unk20", "unk21", "unk22", "unk23", "unk24", "unk25", "unk26", "unk27", "unk28", "unk29", "unk30", "unk31" }; #define cpuid(id) __asm__( "cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(id), "b"(0), "c"(0), "d"(0)) #define b(val, base, end) ((val << (31-end)) >> (31-end+base)) int main(void) { unsigned long eax, ebx, ecx, edx; unsigned long i, max; int support_extended; printf("%8s - %8s %8s %8s %8s\n", "query", "eax", "ebx", "ecx", "edx"); max = 0; for (i=0 ; i<=max ; i++) { cpuid(i); if (!i) max = eax; printf("%.8lX - %.8lX %.8lX %.8lX %.8lX\n", i, eax, ebx, ecx, edx); } printf("\n"); max = 0x80000000; for (i=0x80000000 ; i<=max ; i++) { cpuid(i); if (!(i << 1)) { max = eax; support_extended = eax >> 31; } printf("%.8lX - %.8lX %.8lX %.8lX %.8lX\n", i, eax, ebx, ecx, edx); } printf("\n"); cpuid(0); printf("identification: \"%.4s%.4s%.4s\"\n", (char *)&ebx, (char *)&edx, (char *)&ecx); printf("cpu information:\n"); cpuid(1); printf(" family %ld model %ld stepping %ld efamily %ld emodel %ld\n", b(eax, 8, 11), b(eax, 4, 7), b(eax, 0, 3), b(eax, 20, 27), b(eax, 16, 19)); printf(" brand %ld cflush sz %ld*8 nproc %ld apicid %ld\n", b(ebx, 0, 7), b(ebx, 8, 15), b(ebx, 16, 23), b(ebx, 24, 31)); printf(" feature information:"); for (i=0 ; i<32 ; i++) if (edx & (1 << i)) printf(" %s", featureinfo[i]); printf("\n extended information:"); for (i=0 ; i<32 ; i++) if (ecx & (1 << i)) printf(" %s", extendinfo[i]); printf("\n"); if (!support_extended) return 0; printf("extended cpuid:\n", eax); cpuid(0x80000001); printf(" %.8lX %.8lX %.8lX %.8lX + ", eax, ebx, ecx & ~1, edx & ~0x00800102); if (ecx & 1) printf(" lahf64"); if (edx & (1 << 11)) printf(" syscall64"); if (edx & (1 << 20)) printf(" nx"); if (edx & (1 << 29)) printf(" em64t"); char brandstring[48]; unsigned long *p = (unsigned long*)brandstring; cpuid(0x80000002); *p++ = eax; *p++ = ebx; *p++ = ecx; *p++ = edx; cpuid(0x80000003); *p++ = eax; *p++ = ebx; *p++ = ecx; *p++ = edx; cpuid(0x80000004); *p++ = eax; *p++ = ebx; *p++ = ecx; *p++ = edx; printf("\n brandstring: \"%.48s\"\n", brandstring); return 0; }