Skip to content

Instantly share code, notes, and snippets.

@amtal
Created April 1, 2015 06:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amtal/eb4ef8b231cbf4c18843 to your computer and use it in GitHub Desktop.
Save amtal/eb4ef8b231cbf4c18843 to your computer and use it in GitHub Desktop.
Poke CPUID from Python via AmihaiN's GetThreadContext wrapper
"""Poke interesting instructions from Python.
Uses the nifty trick in https://github.com/AmihaiN/pyAsm to run snippets then
inspect registers. (Use at own risk, nasm.exe source not verified, etc.)
"""
from pyAsm import pyAsm, A_32BIT
def regs(reg, sep='\n', txt=''):
txt = txt.strip()
acc = []
bit = 0
for line in txt.split(sep):
if line.strip():
acc.append
acc.append((line, reg, bit))
bit += 1
return acc
# From:
# Intel(R) Advanced Vector Extensions
# Programming Reference
_feat_table = []
# Table 2-26 ECX
_feat_table += regs(2, txt="""
SSE3
PCLMULDQ
DTES64
MONITOR
DSCPL
VMX Virtual Machine Extensions
SMX Safer Mode Extensions
EST
TM2
SSE3
CNXTID IA32_MISC_ENABLE_MSR bit 24, L1 cache Context ID
reserved
FMA extensions using YMM state
CX16 CMPXCHG16B
XTPR
PDCM
reserved
PCID proc context identifiers, CR4.PCIDE
DCA (prefetch data from mmaped device)
SSE4_1
SSE4_2
X2APIC
MOVBE instruction
POPCNT instruction!
reserved (this is set - why?)
AES
XSAVE
OSXSAVE
AVX instructions on YMM state, 3-op 256/128 SIMD isns
F16C
RDRAND
unused
""")
# Table 2-27 EDX
_feat_table += regs(3, txt='''
FPU
VME
DE
PSE
TSC
MSR
PAE
MCE
CX8
APIC
Reserved
SEP
MTRR
PGE
MCA
CMOV
PAT
PSE_36
PSN proc serial number (96 bit)
CLFSH CLFLUSH isn
reserved
DS debug store (branch trace store, PEBS precise event-based sampling)
ACPI
MMX
FXSR FXSAVE/FXRSTOR
SSE
SSE2
SS self snoop
HTT multi-threading
TM thermal monitor
reserved
PBE FERR#/PBE# pin
''')
from pprint import pprint as pp
def cpuid(val):
p = pyAsm(A_32BIT)
for line in '''
mov eax, {0}
cpuid
'''.format(hex(val)).strip().split('\n'):
if line: p.update(line)
r = p.run()
return (r.Eax, r.Ebx, r.Ecx, r.Edx)
def features():
(eax,ebx,ecx,edx) = info = cpuid(1)
print '\tfeature regs:'
for n in info:
print hex(n)
print '\t flags:'
for key, reg, bit in _feat_table:
has_feat = (info[reg] & (1 << bit)) != 0
print(('[x] ' if has_feat else '[ ] ') + key)
print 'brand index:', hex(ebx & 0xff)
print 'CLFLUSH cache line size:', hex((ebx >> 8) & 0xff)
print 'Local APIC ID:', hex((ebx >> 16) & 0xff)
print 'eax:', hex(eax)
print
def ext_vendor_info():
acc = ''
p = pyAsm(A_32BIT)
for line in '''
mov eax, 0x80000002
cpuid
'''.strip().split('\n'):
if line: p.update(line)
r = p.run()
acc += (hex(r.Eax)[2:-1].decode('hex')[::-1]+
hex(r.Ebx)[2:-1].decode('hex')[::-1]+
hex(r.Edx)[2:-1].decode('hex')[::-1]+
hex(r.Ecx)[2:-1].decode('hex')[::-1])
p = pyAsm(A_32BIT)
for line in '''
mov eax, 0x80000003
cpuid
'''.strip().split('\n'):
if line: p.update(line)
r = p.run()
acc += (hex(r.Eax)[2:-1].decode('hex')[::-1]+
hex(r.Ebx)[2:-1].decode('hex')[::-1]+
hex(r.Edx)[2:-1].decode('hex')[::-1]+
hex(r.Ecx)[2:-1].decode('hex')[::-1])
p = pyAsm(A_32BIT)
for line in '''
mov eax, 0x80000004
cpuid
'''.strip().split('\n'):
if line: p.update(line)
r = p.run()
acc += (hex(r.Eax)[2:-1].decode('hex')[::-1]+
hex(r.Ebx)[2:-1].decode('hex')[::-1]+
hex(r.Edx)[2:-1].decode('hex')[::-1]+
hex(r.Ecx)[2:-1].decode('hex')[::-1])
return acc
if __name__=='__main__':
features()
print '\tvendor ID', repr(ext_vendor_info())
print '\tMode 7'
p = pyAsm(A_32BIT) #We can alse use A_64BIT and A_16BIT!
for line in '''
mov eax, 7
cpuid
'''.strip().split('\n'):
if line: p.update(line)
r = p.run()
print(('[x] ' if r.Ebx&0x08 else '[ ] ') + 'BMI1 bit manip isns 1')
print(('[x] ' if r.Ebx&0x20 else '[ ] ') + 'AVX2')
print(('[x] ' if r.Ebx&0x100 else '[ ] ') + 'BMI2 bit manip isns 2 (Haswell)')
print(('[x] ' if r.Ebx&0x200 else '[ ] ') + 'ERMS')
print(('[x] ' if r.Ebx&0x400 else '[ ] ') + 'INVPCID')
# 4=cache info, 5=monitor?
# 0x80000000 max extended cpuid info
# 8-1 ext sig/feature bits
# 8-2..4 ext brand string
# 8-6 cache associativity
print
print
p = pyAsm(A_32BIT)
for line in '''
mov eax, 0x3100
mov ebx, 0x0000ffff
mov ecx, 0xffff0000
pcmpistri xmm0, xmm1, 5
rdrand eax
rdrand ebx
rdrand ecx
rdrand edx
'''.strip().split('\n'):
if line: p.update(line)
r = p.run()
print map(hex, (r.Eax, r.Ebx, r.Ecx, r.Edx))
print '^^^^^^ test'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment