mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 11:43:23 +08:00
211 lines
9.8 KiB
Python
211 lines
9.8 KiB
Python
![]() |
#
|
||
|
#
|
||
|
#
|
||
|
|
||
|
|
||
|
from pykd import *
|
||
|
import sys
|
||
|
|
||
|
|
||
|
VMCB_CONTROL_CR0 = 0x000
|
||
|
VMCB_CONTROL_DR0 = 0x004
|
||
|
VMCB_CONTROL_00C = 0x00C
|
||
|
VMCB_CONTROL_010 = 0x010
|
||
|
VMCB_CONTROL_PAUSE_COUNT = 0x03E
|
||
|
VMCB_CONTROL_IOPM_BASE_PA = 0x040
|
||
|
VMCB_CONTROL_MSRPM_BASE_PA = 0x048
|
||
|
VMCB_CONTROL_GUEST_ASID = 0x058
|
||
|
VMCB_CONTROL_TLB_CONTROL = 0x05C
|
||
|
VMCB_CONTROL_VINTERRUPT = 0x060
|
||
|
VMCB_CONTROL_INRT_SHADOW = 0x068
|
||
|
VMCB_CONTROL_EXITCODE = 0x070
|
||
|
VMCB_CONTROL_EXITINFO1 = 0x078
|
||
|
VMCB_CONTROL_EXITINFO2 = 0x080
|
||
|
VMCB_CONTROL_EXITINTINFO = 0x088
|
||
|
VMCB_CONTROL_NESTED_PAGING = 0x090
|
||
|
VMCB_CONTROL_EVENTINJ = 0x0A8
|
||
|
VMCB_CONTROL_N_CR3 = 0x0B0
|
||
|
VMCB_CONTROL_LBR_VIRT = 0x0B8
|
||
|
VMCB_CONTROL_CLEAN_BITS = 0x0C0
|
||
|
VMCB_CONTROL_NRIP = 0x0C8
|
||
|
|
||
|
|
||
|
|
||
|
VMCB_GUEST_STATE_OFFSET = 0x400
|
||
|
VMCB_GUEST_ES_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x000
|
||
|
VMCB_GUEST_CS_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x010
|
||
|
VMCB_GUEST_SS_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x020
|
||
|
VMCB_GUEST_DS_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x030
|
||
|
VMCB_GUEST_FS_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x040
|
||
|
VMCB_GUEST_GS_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x050
|
||
|
VMCB_GUEST_GDTR_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x060
|
||
|
VMCB_GUEST_LDTR_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x070
|
||
|
VMCB_GUEST_IDTR_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x080
|
||
|
VMCB_GUEST_TR_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x090
|
||
|
VMCB_GUEST_EFER_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x0D0
|
||
|
VMCB_GUEST_CR4_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x148
|
||
|
VMCB_GUEST_CR3_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x150
|
||
|
VMCB_GUEST_CR0_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x158
|
||
|
VMCB_GUEST_DR7_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x160
|
||
|
VMCB_GUEST_DR6_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x168
|
||
|
VMCB_GUEST_RFLAGS_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x170
|
||
|
VMCB_GUEST_RIP_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x178
|
||
|
VMCB_GUEST_RSP_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x1D8
|
||
|
VMCB_GUEST_RAX_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x1F8
|
||
|
VMCB_GUEST_STAR_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x200
|
||
|
VMCB_GUEST_LSTAR_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x208
|
||
|
VMCB_GUEST_CSTAR_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x210
|
||
|
VMCB_GUEST_SFMASK_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x218
|
||
|
VMCB_GUEST_KERNELGS_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x220
|
||
|
VMCB_GUEST_SYSENTER_CS_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x228
|
||
|
VMCB_GUEST_SYSENTER_ESP_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x230
|
||
|
VMCB_GUEST_SYSENTER_EIP_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x238
|
||
|
VMCB_GUEST_CR2_OFFSET = VMCB_GUEST_STATE_OFFSET + 0x240
|
||
|
|
||
|
|
||
|
|
||
|
def bin32( dw ):
|
||
|
return "0b" + "".join( [ ((dw & ( 0x80000000 >> i ) ) == 0) and "0" or "1" for i in xrange(32) ] )
|
||
|
|
||
|
def bin16( dw ):
|
||
|
return "0b" + "".join( [ ((dw & ( 0x8000 >> i ) ) == 0) and "0" or "1" for i in xrange(16) ] )
|
||
|
|
||
|
def sysselectstr( val ):
|
||
|
return "selector=%x attr=%x base=%x limit=%x" % ( val[0] & 0xFFFF, (val[0]>>16)&0xFFFF, val[1]&0xFFFFFFFF, (val[0]>>32)&0xFFFFFFFF )
|
||
|
|
||
|
|
||
|
def sysselectload( addr ):
|
||
|
return (ptrQWord(addr), ptrQWord(addr+8) )
|
||
|
|
||
|
|
||
|
class VmcbEntry:
|
||
|
|
||
|
def __init__( self, desc, offset, loader, formatter ):
|
||
|
self.desc = desc
|
||
|
self.offset = offset
|
||
|
self.loader = loader
|
||
|
self.formatter = formatter
|
||
|
self.value = "invalid"
|
||
|
|
||
|
def load( self, address ):
|
||
|
self.value = self.loader( address + self.offset )
|
||
|
|
||
|
|
||
|
def __str__( self ):
|
||
|
return self.formatter( self.value )
|
||
|
|
||
|
|
||
|
|
||
|
class Vmcb:
|
||
|
|
||
|
|
||
|
def __init__( self, addr ):
|
||
|
|
||
|
self.addr = addr
|
||
|
|
||
|
self.controlArea = [
|
||
|
VmcbEntry( "CR0 Reads/Writes", VMCB_CONTROL_CR0, ptrDWord, bin32 ),
|
||
|
VmcbEntry( "DR0 Reads/Writes", VMCB_CONTROL_DR0, ptrDWord, bin32 ),
|
||
|
VmcbEntry( "Interceptors", VMCB_CONTROL_00C, ptrDWord, bin32 ),
|
||
|
VmcbEntry( "Interceptors", VMCB_CONTROL_010, ptrDWord, bin32 ),
|
||
|
VmcbEntry( "PAUSE Filter Count",VMCB_CONTROL_PAUSE_COUNT, ptrWord, hex ),
|
||
|
VmcbEntry( "IOPM_BASE_PA", VMCB_CONTROL_IOPM_BASE_PA, ptrQWord, hex ),
|
||
|
VmcbEntry( "MSRPM_BASE_PA", VMCB_CONTROL_MSRPM_BASE_PA, ptrQWord, hex ),
|
||
|
VmcbEntry( "Guest ASID", VMCB_CONTROL_GUEST_ASID, ptrDWord, hex ),
|
||
|
VmcbEntry( "TLB_CONTROL", VMCB_CONTROL_TLB_CONTROL, ptrDWord, hex ),
|
||
|
VmcbEntry( "Virtual interrupt",VMCB_CONTROL_VINTERRUPT, ptrQWord, hex ),
|
||
|
VmcbEntry( "Interrupt Shadow", VMCB_CONTROL_INRT_SHADOW, ptrQWord, hex ),
|
||
|
VmcbEntry( "EXITCODE", VMCB_CONTROL_EXITCODE, ptrQWord, hex ),
|
||
|
VmcbEntry( "EXITINFO1", VMCB_CONTROL_EXITINFO1, ptrQWord, hex ),
|
||
|
VmcbEntry( "EXITINFO2", VMCB_CONTROL_EXITINFO2, ptrQWord, hex ),
|
||
|
VmcbEntry( "EXITINTINFO", VMCB_CONTROL_EXITINTINFO, ptrQWord, hex ),
|
||
|
VmcbEntry( "Nested Paging", VMCB_CONTROL_NESTED_PAGING, ptrQWord, hex ),
|
||
|
VmcbEntry( "EVENTINJ", VMCB_CONTROL_EVENTINJ, ptrQWord, hex ),
|
||
|
VmcbEntry( "N_CR3", VMCB_CONTROL_N_CR3, ptrQWord, hex ),
|
||
|
VmcbEntry( "LBR_VIRTUALIZATION_ENABLE", VMCB_CONTROL_LBR_VIRT, ptrQWord, hex ),
|
||
|
VmcbEntry( "Clean Bits", VMCB_CONTROL_CLEAN_BITS, ptrDWord, hex ),
|
||
|
VmcbEntry( "nRIP", VMCB_CONTROL_NRIP, ptrQWord, hex ),
|
||
|
]
|
||
|
|
||
|
self.guestArea = [
|
||
|
VmcbEntry( "ES", VMCB_GUEST_ES_OFFSET, sysselectload, sysselectstr ),
|
||
|
VmcbEntry( "CS", VMCB_GUEST_CS_OFFSET, sysselectload, sysselectstr ),
|
||
|
VmcbEntry( "SS", VMCB_GUEST_SS_OFFSET, sysselectload, sysselectstr ),
|
||
|
VmcbEntry( "DS", VMCB_GUEST_DS_OFFSET, sysselectload, sysselectstr ),
|
||
|
VmcbEntry( "FS", VMCB_GUEST_FS_OFFSET, sysselectload, sysselectstr ),
|
||
|
VmcbEntry( "GS", VMCB_GUEST_GS_OFFSET, sysselectload, sysselectstr ),
|
||
|
VmcbEntry( "GDTR", VMCB_GUEST_GDTR_OFFSET, sysselectload, sysselectstr ),
|
||
|
VmcbEntry( "LDTR", VMCB_GUEST_LDTR_OFFSET, sysselectload, sysselectstr ),
|
||
|
VmcbEntry( "IDTR", VMCB_GUEST_IDTR_OFFSET, sysselectload, sysselectstr ),
|
||
|
VmcbEntry( "TR", VMCB_GUEST_TR_OFFSET, sysselectload, sysselectstr ),
|
||
|
VmcbEntry( "EFER", VMCB_GUEST_EFER_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "CR4", VMCB_GUEST_CR4_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "CR3", VMCB_GUEST_CR3_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "CR0", VMCB_GUEST_CR0_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "DR6", VMCB_GUEST_DR6_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "DR7", VMCB_GUEST_DR7_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "RFLAGS", VMCB_GUEST_RFLAGS_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "RIP", VMCB_GUEST_RIP_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "RSP", VMCB_GUEST_RSP_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "RAX", VMCB_GUEST_RAX_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "STAR", VMCB_GUEST_STAR_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "LSTAR", VMCB_GUEST_LSTAR_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "CSTAR", VMCB_GUEST_CSTAR_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "SFMASK", VMCB_GUEST_SFMASK_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "KERNEL GS Base", VMCB_GUEST_KERNELGS_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "SYSENTER CS", VMCB_GUEST_SYSENTER_CS_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "SYSENTER ESP", VMCB_GUEST_SYSENTER_ESP_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "SYSENTER EIP", VMCB_GUEST_SYSENTER_EIP_OFFSET, ptrQWord, hex ),
|
||
|
VmcbEntry( "CR2", VMCB_GUEST_CR2_OFFSET, ptrQWord, hex ),
|
||
|
|
||
|
]
|
||
|
|
||
|
|
||
|
self.controlArea.sort( key=lambda v: v.offset )
|
||
|
self.guestArea.sort( key=lambda v: v.offset )
|
||
|
|
||
|
for vmcbEntry in self.controlArea: vmcbEntry.load( addr )
|
||
|
for vmcbEntry in self.guestArea: vmcbEntry.load( addr )
|
||
|
|
||
|
def __str__ ( self ):
|
||
|
|
||
|
s = "\nVMCB Start Address: %x\n" % self.addr;
|
||
|
|
||
|
s += "\n*** CONTROL AREA ***\n"
|
||
|
|
||
|
|
||
|
for vmcbEntry in self.controlArea:
|
||
|
s += "\t+%03x %s: %s\n" % ( vmcbEntry.offset, vmcbEntry.desc, str(vmcbEntry) )
|
||
|
|
||
|
|
||
|
s += "\n*** GUEST STATE AREA ***\n"
|
||
|
|
||
|
for vmcbEntry in self.guestArea:
|
||
|
s += "\t+%03x %s: %s\n" % ( vmcbEntry.offset, vmcbEntry.desc, str(vmcbEntry) )
|
||
|
|
||
|
return s
|
||
|
|
||
|
|
||
|
def main():
|
||
|
|
||
|
if not isWindbgExt():
|
||
|
dprintln( "script is launch out of windbg" )
|
||
|
return
|
||
|
|
||
|
if len( sys.argv ) <= 1:
|
||
|
dprintln( "usage: !py vmcb <addr>" )
|
||
|
return
|
||
|
|
||
|
|
||
|
try:
|
||
|
|
||
|
dprint( str( Vmcb( expr( sys.argv[1] ) ) ) )
|
||
|
|
||
|
except MemoryException, e:
|
||
|
|
||
|
dprintln( e.desc() )
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|