Created
April 1, 2015 06:54
-
-
Save amtal/eb4ef8b231cbf4c18843 to your computer and use it in GitHub Desktop.
Poke CPUID from Python via AmihaiN's GetThreadContext wrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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) | |
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 | |
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