Created
September 13, 2015 16:02
-
-
Save Cr4sh/fcad66c809b9dfec0825 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| #!/usr/bin/env python | |
| import sys, os | |
| from subprocess import Popen, PIPE | |
| from struct import pack, unpack | |
| from portio import * | |
| def hexdump(data, width = 16, addr = 0): | |
| ret = '' | |
| def quoted(data): | |
| # replace non-alphanumeric characters | |
| return ''.join(map(lambda b: b if b.isalnum() else '.', data)) | |
| while data: | |
| line = data[: width] | |
| data = data[width :] | |
| # put hex values | |
| s = map(lambda b: '%.2x' % ord(b), line) | |
| s += [ ' ' ] * (width - len(line)) | |
| # put ASCII values | |
| s = '%s | %s' % (' '.join(s), quoted(line)) | |
| if addr is not None: | |
| # put address | |
| s = '%.8x: %s' % (addr, s) | |
| addr += len(line) | |
| ret += s + '\n' | |
| return ret | |
| def proc_run(command, in_data = None): | |
| p = Popen(command, stdin = PIPE, stdout = PIPE) | |
| ret, _ = p.communicate(input = in_data) | |
| return ret | |
| def _pci_read(bus, dev, func, addr, domain = 0, size = 'b'): | |
| ret = proc_run([ 'setpci', '-s', | |
| '%x:%x:%x.%x' % (domain, bus, dev, func), # PCI device address | |
| '%x.%s' % (addr, size) ]) | |
| return long(ret.strip(), 16) | |
| def pci_read_8(*args): return _pci_read(*args) | |
| def pci_read_16(*args): return _pci_read(*args, size = 'w') | |
| def pci_read_32(*args): return _pci_read(*args, size = 'l') | |
| bitval = lambda val, b: 0L if val & (1L << b) == 0 else 1L | |
| PCI_HOST = (0, 0, 0) | |
| pci_host = lambda addr: PCI_HOST + (addr, ) | |
| PCI_LPC = (0, 0x1f, 0) | |
| pci_lpc = lambda addr: PCI_LPC + (addr, ) | |
| BIOS_CNTL = 0xdc | |
| bios_cntl = lambda: pci_read_8(*pci_lpc(BIOS_CNTL)) | |
| RCBA = 0xf0 | |
| rcba = lambda: pci_read_32(*pci_lpc(RCBA)) | |
| rcrb = lambda: rcba() & 0xffffc000 | |
| SMM_BWP = 5 | |
| smm_bwp = lambda: bitval(bios_cntl(), SMM_BWP) | |
| BLE = 1 | |
| ble = lambda: bitval(bios_cntl(), BLE) | |
| BIOSWE = 0 | |
| bioswe = lambda: bitval(bios_cntl(), BIOSWE) | |
| SMRAMC = 0x88 | |
| smramc = lambda: pci_read_32(*pci_host(SMRAMC)) | |
| G_SMRAME = 3 | |
| g_smrame = lambda: bitval(smramc(), G_SMRAME) | |
| D_LCK = 4 | |
| d_lck = lambda: bitval(smramc(), D_LCK) | |
| D_CLS = 5 | |
| d_cls = lambda: bitval(smramc(), D_CLS) | |
| D_OPEN = 6 | |
| d_open = lambda: bitval(smramc(), D_OPEN) | |
| TSEGMB = 0xb8 | |
| tsegmb = lambda: pci_read_32(*pci_host(TSEGMB)) | |
| tsegmb_base = lambda: tsegmb() & 0xfff00000 | |
| tsegmb_lock = lambda: tsegmb() & 1 | |
| PMBASE = 0x40 | |
| pmbase = lambda: pci_read_32(*pci_lpc(PMBASE)) | |
| GEN_PMCON_1 = 0xa0 | |
| gen_pmcon_1 = lambda: pci_read_16(*pci_lpc(GEN_PMCON_1)) | |
| SMI_LOCK = 4 | |
| smi_lock = lambda: bitval(gen_pmcon_1(), SMI_LOCK) | |
| def pmbase_addr(): | |
| lo = pci_read_8(*pci_lpc(PMBASE + 0)) | |
| hi = pci_read_8(*pci_lpc(PMBASE + 1)) | |
| return ((hi << 1) | (lo >> 7)) << 7 | |
| def _port_read(port, size = 1): | |
| ioperm(port, size, 1) | |
| return { 1: inb, 2: inw, 4: inl }[size](port) | |
| def port_read_8(port): return _port_read(port) | |
| def port_read_16(port): return _port_read(port, 2) | |
| def port_read_32(port): return _port_read(port, 4) | |
| SMI_EN = 0x30 | |
| smi_en = lambda: port_read_32(pmbase_addr() + SMI_EN) | |
| GBL_SMI_EN = 0 | |
| gbl_smi_en = lambda: bitval(smi_en(), GBL_SMI_EN) | |
| def efi_var_get(name): | |
| with open('/sys/firmware/efi/vars/%s/data' % name, 'rb') as fd: | |
| return fd.read() | |
| def efi_var_get_32(name): return unpack('I', efi_var_get(name))[0] | |
| def efi_var_get_64(name): return unpack('Q', efi_var_get(name))[0] | |
| def _mem_read(dev_name, addr, size): | |
| with open(dev_name, 'rb') as fd: | |
| fd.seek(addr) | |
| return fd.read(size) | |
| def mem_read(addr, size): return _mem_read('/dev/mem', addr, size) | |
| def mem_read_8(addr): return unpack('B', mem_read(addr, 1))[0] | |
| def mem_read_16(addr): return unpack('H', mem_read(addr, 2))[0] | |
| def mem_read_32(addr): return unpack('I', mem_read(addr, 4))[0] | |
| def mem_read_64(addr): return unpack('Q', mem_read(addr, 8))[0] | |
| def kmem_read(addr, size): return _mem_read('/dev/kmem', addr, size) | |
| def kmem_read_8(addr): return unpack('B', kmem_read(addr, 1))[0] | |
| def kmem_read_16(addr): return unpack('H', kmem_read(addr, 2))[0] | |
| def kmem_read_32(addr): return unpack('I', kmem_read(addr, 4))[0] | |
| def kmem_read_64(addr): return unpack('Q', kmem_read(addr, 8))[0] | |
| def _mem_write(dev_name, addr, data): | |
| with open(dev_name, 'wb') as fd: | |
| fd.seek(addr) | |
| fd.write(data) | |
| def mem_write(addr, data): return _mem_write('/dev/mem', addr, data) | |
| def mem_write_8(addr, data): return mem_write(addr, pack('B', data)) | |
| def mem_write_16(addr, data): return mem_write(addr, pack('H', data)) | |
| def mem_write_32(addr, data): return mem_write(addr, pack('I', data)) | |
| def mem_write_64(addr, data): return mem_write(addr, pack('Q', data)) | |
| def kmem_write(addr, data): return _mem_write('/dev/kmem', addr, data) | |
| def kmem_write_8(addr, data): return kmem_write(addr, pack('B', data)) | |
| def kmem_write_16(addr, data): return kmem_write(addr, pack('H', data)) | |
| def kmem_write_32(addr, data): return kmem_write(addr, pack('I', data)) | |
| def kmem_write_64(addr, data): return kmem_write(addr, pack('Q', data)) | |
| def _at(data, off, size, fmt): return unpack(fmt, data[off : off + size])[0] | |
| def byte_at(data, off): return _at(data, off, 1, 'B') | |
| def word_at(data, off): return _at(data, off, 2, 'H') | |
| def dword_at(data, off): return _at(data, off, 4, 'I') | |
| def qword_at(data, off): return _at(data, off, 8, 'Q') | |
| NASM = 'nasm' | |
| def assembly(prog): | |
| ret = '' | |
| src = '.prog.asm' | |
| dst = '.prog.bin' | |
| # create source file | |
| with open(src, 'wb') as fd: fd.write(prog) | |
| # compile | |
| code = os.system('"%s" "%s" -o "%s"' % (NASM, src, dst)) | |
| os.unlink(src) | |
| if code != 0: | |
| raise Exception('nasm error %d' % code) | |
| # read binary contents | |
| with open(dst, 'rb') as fd: ret = fd.read() | |
| os.unlink(dst) | |
| return ret | |
| def test(): | |
| print 'BIOS_CNTL = %.2x' % bios_cntl() | |
| print '- BIOSWE = %d' % bioswe() | |
| print '- BLE = %d' % ble() | |
| print '- SMM_BWP = %d' % smm_bwp() | |
| print 'SMRAMC = %.8x' % smramc() | |
| print '- G_SMRAME = %d' % g_smrame() | |
| print '- D_LCK = %d' % d_lck() | |
| print '- D_CLS = %d' % d_cls() | |
| print '- D_OPEN = %d' % d_open() | |
| print 'TSEGMB = %.8x' % tsegmb() | |
| print '- TSEGMB = %.8x' % tsegmb_base() | |
| print '- LOCK = %d' % tsegmb_lock() | |
| print 'SMI_EN = %.8x' % smi_en() | |
| print '- GBL_SMI_EN = %d' % gbl_smi_en() | |
| print 'GEN_PMCON_1 = %.4x' % gen_pmcon_1() | |
| print '- SMI_LOCK = %d' % smi_lock() | |
| if __name__ == '__main__': | |
| exit(test()) | |
| # | |
| # EoF | |
| # |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment