# # # 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 " ) return try: dprint( str( Vmcb( expr( sys.argv[1] ) ) ) ) except MemoryException, e: dprintln( e.desc() ) if __name__ == "__main__": main()