forked from naksyn/PythonMemoryModule
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcpuid.py
More file actions
159 lines (126 loc) · 4.7 KB
/
cpuid.py
File metadata and controls
159 lines (126 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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])
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"""
class X64CpuidResult(ctypes.Structure):
_fields_ = [("RAX", ULONG64),
("RBX", ULONG64),
("RCX", ULONG64),
("RDX", ULONG64)]
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"""
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])
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
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
def do_cpuid(req):
"""Performs a CPUID for the current process bitness
:rtype: :class:`X86CpuidResult`
"""
return _do_cpuid(req)
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
def is_intel_proc():
"""get_vendor_id() == 'GenuineIntel'"""
return get_vendor_id() == "GenuineIntel"
def is_amd_proc():
"""get_vendor_id() == 'AuthenticAMD'"""
return get_vendor_id() == "AuthenticAMD"
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