Source code for windows.native_exec.cpuid

import ctypes
import struct

import native_function
import simple_x86 as x86
import simple_x64 as x64
from windows.generated_def.winstructs import *


def _bitness():
    """Returns 32 or 64"""
    import platform
    bits = platform.architecture()[0]
    return int(bits[:2])


[docs]class X86CpuidResult(ctypes.Structure): """Raw result of the CPUID instruction""" _fields_ = [("EAX", DWORD), ("EBX", DWORD), ("ECX", DWORD), ("EDX", DWORD)] fields = [f[0] for f in _fields_] """Fields of the Structure"""
[docs]class X64CpuidResult(ctypes.Structure): _fields_ = [("RAX", ULONG64), ("RBX", ULONG64), ("RCX", ULONG64), ("RDX", ULONG64)]
[docs]class X86IntelCpuidFamilly(ctypes.Structure): _fields_ = [("SteppingID", DWORD, 4), ("ModelID", DWORD, 4), ("FamilyID", DWORD, 4), ("ProcessorType", DWORD, 2), ("Reserved2", DWORD, 2), ("ExtendedModel", DWORD, 4), ("ExtendedFamily", DWORD, 8), ("Reserved", DWORD, 2)] fields = [f[0] for f in _fields_] """Fields of the Structure"""
[docs]class X86AmdCpuidFamilly(ctypes.Structure): _fields_ = [("SteppingID", DWORD, 4), ("ModelID", DWORD, 4), ("FamilyID", DWORD, 4), ("Reserved2", DWORD, 4), ("ExtendedModel", DWORD, 4), ("ExtendedFamily", DWORD, 8), ("Reserved", DWORD, 2)] fields = [f[0] for f in _fields_] """Fields of the Structure"""
cpuid32_code = x86.MultipleInstr() cpuid32_code += x86.Push('EDI') cpuid32_code += x86.Mov('EAX', x86.mem('[ESP + 0x8]')) cpuid32_code += x86.Mov('EDI', x86.mem('[ESP + 0xc]')) cpuid32_code += x86.Cpuid() cpuid32_code += x86.Mov(x86.mem('[EDI + 0x0]'), 'EAX') cpuid32_code += x86.Mov(x86.mem('[EDI + 0x4]'), 'EBX') cpuid32_code += x86.Mov(x86.mem('[EDI + 0x8]'), 'ECX') cpuid32_code += x86.Mov(x86.mem('[EDI + 0xc]'), 'EDX') cpuid32_code += x86.Pop('EDI') cpuid32_code += x86.Ret() do_cpuid32 = native_function.create_function(cpuid32_code.get_code(), [DWORD, DWORD, PVOID]) cpuid64_code = x64.MultipleInstr() cpuid64_code += x64.Mov('RAX', 'RCX') cpuid64_code += x64.Mov('R10', 'RDX') cpuid64_code += x64.Cpuid() # For now assembler cannot do 32bits register in x64 cpuid64_code += x64.Mov(x64.mem('[R10 + 0x00]'), 'RAX') cpuid64_code += x64.Mov(x64.mem('[R10 + 0x08]'), 'RBX') cpuid64_code += x64.Mov(x64.mem('[R10 + 0x10]'), 'RCX') cpuid64_code += x64.Mov(x64.mem('[R10 + 0x18]'), 'RDX') cpuid64_code += x64.Ret() do_cpuid64 = native_function.create_function(cpuid64_code.get_code(), [DWORD, DWORD, PVOID])
[docs]def x86_cpuid(req): """Performs a CPUID in 32bits mode :rtype: :class:`X86CpuidResult` """ cpuid_res = X86CpuidResult() do_cpuid32(req, ctypes.addressof(cpuid_res)) return cpuid_res
[docs]def x64_cpuid(req): """Performs a CPUID in 64bits mode :rtype: :class:`X86CpuidResult` """ cpuid_res = X64CpuidResult() do_cpuid64(req, ctypes.addressof(cpuid_res)) # For now assembler cannot do 32bits register in x64 return X86CpuidResult(cpuid_res.RAX, cpuid_res.RBX, cpuid_res.RCX, cpuid_res.RDX)
if _bitness() == 32: _do_cpuid = x86_cpuid else: _do_cpuid = x64_cpuid
[docs]def do_cpuid(req): """Performs a CPUID for the current process bitness :rtype: :class:`X86CpuidResult` """ return _do_cpuid(req)
[docs]def get_vendor_id(): """Extracts the VendorId string from CPUID :rtype: :class:`str` """ cpuid_res = do_cpuid(0) return struct.pack("<III", cpuid_res.EBX, cpuid_res.EDX, cpuid_res.ECX)
# platform.processor() could do the trick
[docs]def is_intel_proc(): """get_vendor_id() == 'GenuineIntel'""" return get_vendor_id() == "GenuineIntel"
[docs]def is_amd_proc(): """get_vendor_id() == 'AuthenticAMD'""" return get_vendor_id() == "AuthenticAMD"
[docs]def get_proc_family_model(): """Extracts the family and model based on vendorId :rtype: (ComputedFamily, ComputedModel) """ cpuid_res = do_cpuid(1) if is_intel_proc(): format = X86IntelCpuidFamilly elif is_amd_proc(): format = X86AmdCpuidFamilly else: raise NotImplementedError("Cannot get familly information of proc <{0}>".format(get_vendor_id())) infos = format.from_buffer_copy(struct.pack("<I", cpuid_res.EAX)) if infos.FamilyID == 0x6 or infos.FamilyID == 0x0F: ComputedModel = infos.ModelID + (infos.ExtendedModel << 4) else: ComputedModel = infos.ModelID if infos.FamilyID == 0x0F: ComputedFamily = infos.FamilyID + infos.ExtendedFamily else: ComputedFamily = infos.FamilyID return ComputedFamily, ComputedModel