int RegisterInterrupt() { UNICODE_STRING uniName; PVOID pvHvlRegisterAddress = NULL; PHYSICAL_ADDRESS pAdr = {0}; ULONG i,ProcessorCount; // ProcessorCount = KeQueryActiveProcessorCount(NULL); // HvlRegisterInterruptCallback DbgLog("Active processor count",ProcessorCount); RtlInitUnicodeString(&uniName,L"HvlRegisterInterruptCallback"); pvHvlRegisterAddress = MmGetSystemRoutineAddress(&uniName); if (pvHvlRegisterAddress == NULL){ DbgPrintString("Cannot find HvlRegisterInterruptCallback!"); return 0; } DbgLog16("HvlRegisterInterruptCallback address ",pvHvlRegisterAddress); // HvlpInterruptCallback, FindHvlpInterruptCallback((unsigned char *)pvHvlRegisterAddress); // ArchmHvlRegisterInterruptCallback((uintptr_t)&ArchmWinHvOnInterrupt,(uintptr_t)pvHvlpInterruptCallbackOrig,WIN_HV_ON_INTERRUP_INDEX); ArchmHvlRegisterInterruptCallback((uintptr_t)&ArchXPartEnlightenedIsr,(uintptr_t)pvHvlpInterruptCallbackOrig,XPART_ENLIGHTENED_ISR0_INDEX); ArchmHvlRegisterInterruptCallback((uintptr_t)&ArchXPartEnlightenedIsr,(uintptr_t)pvHvlpInterruptCallbackOrig,XPART_ENLIGHTENED_ISR1_INDEX); ArchmHvlRegisterInterruptCallback((uintptr_t)&ArchXPartEnlightenedIsr,(uintptr_t)pvHvlpInterruptCallbackOrig,XPART_ENLIGHTENED_ISR2_INDEX); ArchmHvlRegisterInterruptCallback((uintptr_t)&ArchXPartEnlightenedIsr,(uintptr_t)pvHvlpInterruptCallbackOrig,XPART_ENLIGHTENED_ISR3_INDEX); // SIMP , SIM
WARNING
During experiments related to the intensive work of virtual machines, it is better to replace one handler in the HvlpInterruptCallback array, since replacing all immediately leads to unstable system operation (at least, with a large flow of debug messages through KdPrint and WPP).
// , Mm MapIoSpace, for (i = 0; i < ProcessorCount; i++) {KeSetSystemAffinityThreadEx(1i64 << i); DbgLog("Current processor number",KeGetCurrentProcessorNumberEx(NULL)); pAdr.QuadPart = ArchReadMsr (HV_X64_MSR_SIMP) & 0xFFFFFFFFFFFFF000; pvSIMP[i] = MmMapIoSpace (pAdr, PAGE_SIZE, MmCached); if (pvSIMP[i] == NULL){ DbgPrintString("Error during pvSIMP MmMapIoSpace"); return 1; } DbgLog16("pvSIMP[i] address", pvSIMP[i]); pAdr.QuadPart = ArchReadMsr (HV_X64_MSR_SIEFP) & 0xFFFFFFFFFFFFF000; pvSIEFP[i] = MmMapIoSpace(pAdr, PAGE_SIZE, MmCached); if (pvSIEFP[i] == NULL){DbgPrintString("Error during pvSIEFP MmMapIoSpace"); return 1; } DbgLog16("pvSIEFP address", pvSIEFP[i]); } return 0; }
void ParseHvMessage() { PHV_MESSAGE phvMessage, phvMessage1; // ULONG uCurProcNum = KeGetCurrentProcessorNumberEx(NULL); Unlock+0x162 vmbkmcl!VmbChannelEnable+0x231 vmbus!PipeStartChannel+0x9e vmbus!PipeAccept+0x81 vmbus!InstanceCreate+0x90 .................................. nt!IopParseDevice+0x7b3 nt!ObpLookupObjectName+0x6d8 nt!ObOpenObjectByName+0x1e3 nt!IopCreateFile+0x372 nt!NtCreateFile+0x78 nt!KiSystemServiceCopyEnd+0x13 ntdll!NtCreateFile+0xa KERNELBASE!CreateFileInternal+0x30a KERNELBASE!CreateFileW+0x66 vmbuspipe!VmbusPipeClientOpenChannel+0x44 icsvc!ICTransportVMBus::ClientNotification+0x60 vmbuspipe!VmbusPipeClientEnumeratePipes+0x1ac icsvc!ICTransportVMBusClient::Open+0xe5 icsvc!ICEndpoint::Connect+0x66 icsvc!ICChild::Run+0x65 icsvc!ICKvpExchangeChild::Run+0x189 icsvc!ICChild::ICServiceWork+0x137 icsvc!ICChild::ICServiceMain+0x8f ..................................
WINDBG>k Call Sitent!IoAllocateMdl vmbus!InstanceCloseChannel+0x22d ( , ) vmbus!InstanceDeviceControl+0x118 .................................. vmbkmcl!KmclpSynchronousIoControl+0xa7 vmbkmcl!KmclpClientOpenChannel+0x2a6 vmbkmcl!KmclpClientFindVmbusAnd if (pvSIMP[uCurProcNum] != NULL){ phvMessage = (PHV_MESSAGE)pvSIMP[uCurProcNum]; } else{ DbgPrintString("pvSIMP is NULL"); return; } // 1- SIM phvMessage1 = (PHV_MESSAGE)((PUINT8)pvSIMP[uCurProcNum]+ HV_MESSAGE_SIZE); // for SINT1 if (phvMessage1->Header.MessageType != 0){ DbgPrintString("SINT1 interrupt"); } // // TLFS switch (phvMessage->Header.MessageType) { case HvMessageTypeX64IoPortIntercept: PrintIoPortInterceptMessage(phvMessage); break; case HvMessageTypeNone:DbgPrintString("HvMessageTypeNone"); break; case HvMessageTypeX64MsrIntercept:PrintMsrInterceptMessage(phvMessage); break; case HvMessageTypeX64CpuidIntercept:PrintCpuidInterceptMessage(phvMessage); break; case HvMessageTypeX64ExceptionIntercept:PrintExceptionInterceptMessage(phvMessage); break; default: DbgLog("Unknown MessageType", phvMessage-> Header.MessageType); break; } }
WINDBG>!ed 2d5bb000 aaaaaaaa WINDBG>!db 2d5bb000 \#2d5bb000 aa aa aa aa 10 19 00
WINDBG>!db 1367bb000 \#1367bb000 aa aa aa aa 10 19
WINDBG>k Child-SP RetAddr Call Site fffff800\`fcc1ea38 fffff800\`6cdc440c vmbusr!PkGetReceiveBuffer+0x2c fffff800\`fcc1ea40 fffff800\`6cdc41a7 vmbusr!PipeTryReadSingle+0x3c fffff800\`fcc1eaa0 fffff800\`6cdc4037 vmbusr!PipeProcessDeferredReadWrite+0xe7 fffff800\`fcc1eaf0 fffff800\`6c96535e vmbusr!PipeEvtChannelSignalArrived+0x63 fffff800\`fcc1eb30 fffff800\`6cdc4e3d vmbkmclr!KmclpVmbusManualIsr+0x16 fffff800\`fcc1eb60 fffff800\`fb2d31e0 vmbusr!ParentRingInterruptDpc+0x5d
WINDBG> dc ffffd0016fe33000 L1000 ………………………………………………………………………………………………………………… ffffd001\`6fe35b30 0065004e 00770074 0072006f 0041006b NetworkA ffffd001\`6fe35b40 00640064 00650072 00730073 00500049 ddressIP ffffd001\`6fe35b50 00340076 00000000 00000000 00000000 v.4............. ………………………………………………………………………………………………………………… ffffd001\`6fe35d20 00000000 00000000 00000000 00000000 ................ ffffd001\`6fe35d30 00300031 0030002e 0030002e 0033002e 1.0...0...0...3. ffffd001\`6fe35d40 00000000 00000000 00000000 00000000 ................ WINDBG>!pte ffffd001\`6fe35b30 VA ffffd0016fe35b30 PXE at FFFFF6FB7DBEDD00 PPE at FFFFF6FB7DBA0028 PDE at FFFFF6FB74005BF8 PTE at FFFFF6E800B7F1A8 contains 0000000000225863 contains 00000000003B7863 contains 000000010FB12863 contains 80000001367BD963 pfn 225 ---DA--KWEV pfn 3b7 ---DA--KWEV pfn 10fb12 ---DA-KWEV pfn 1367bd -G-DA--KW-V pfn 1367bd — PFN 3- MDL
vmbusr!PkGetReceiveBuffer+0x4e: mov r8,r10 ( r10d rdx) add r8,qword ptr [rcx+20h] — rcx+20 WINDBG>!pte @r8 VA ffffd0016ff22448 PXE at FFFFF6FB7DBEDD00 PPE at FFFFF6FB7DBA0028 PDE at FFFFF6FB74005BF8 PTE at FFFFF6E800B7F910 contains 0000000000225863 contains 00000000003B7863 contains 000000010FB12863 contains 80000001367C0963 pfn 225 ---DA--KWEV pfn 3b7 ---DA--KWEV pfn 10fb12 ---DA-KWEV pfn 1367c0 -G-DA--KW-V
WINDBG>? poi(@rcx+18) Evaluate expression: -52770386006016 = ffffd001\`6fe33000 WINDBG>!pte ffffd001\`6fe33000 VA ffffd0016fe33000 PXE at FFFFF6FB7DBEDD00 PPE at FFFFF6FB 7DBA0028 PDE at FFFFF6FB74005BF8 PTE at FFFFF6E800B7F198 contains 0000000000225863 contains 00000000003B7863 contains 000000010FB12863 contains 80000001367BB963 pfn 225 ---DA--KWEV pfn 3b7 ---DA--KWEV pfn 10fb12 ---DA--KWEV pfn 1367bb -G-DA--KW-V WINDBG>r cr3 cr3=00000000001ab000 WINDBG>!vtop 1ab000 ffffd 0016fe33000 Amd64VtoP: Virt ffffd001\`6fe33000, pagedir 1ab000 Amd64VtoP: PML4E 1abd00 Amd64VtoP: PDPE 225028 Amd64VtoP: PDE 3b7bf8 Amd64VtoP: PTE 00000001\`0fb12198 Amd64VtoP: Mapped phys 00000001\`367bb000 Virtual address ffffd0016fe33000 translates to physical address 1367bb000.
INFO
Information on KvP technology can be found on MSDN blogs:
goo.gl/R0U52l
goo.gl/UeZRK2
WINDBG>dc @r8 ffffd001\`6ff21d10 ....H........... ffffd001\`6ff21d20 ....(........... ffffd001\`6ff21d30 00020006 00000148 00000000 00000000 00000001 00000 a28 00000003 00050002 0a140000 00000000 00000515 00000103 ................ ffffd001\`6ff21d40 00000004 00000001 00000016 0000001a ................ ffffd001\`6ff21d50 0076004b 00440050 00740061 004b0061 KvPDataK ffffd001\`6ff21d60 00790065 00000000 00000000 00000000 ey............ ............................................................. .......... ffffd001\`6ff21f50 0076004b 00440050 00740061 00560061 KvPDataV ffffd001\`6ff21f60 006c0061 00650075 00000000 00000000 alue........ WINDBG>!pte ffffd001\`6ff21f50 VA ffffd0016ff21f50 PXE at FFFFF6FB7DBEDD00 PPE at FFFFF6FB7DBA0028 PDE at FFFFF6FB74005BF8 PTE at FFFFF6E800B7F908 contains 0000000000225863 contains 00000000003B7863 contains 000000010FB12863 contains 80000001367BF963 pfn 225 ---DA--KWEV pfn 3b7 ---DA--KWEV pfn 10fb12 ---DA-KWEV pfn 1367bf -G-DA--KW-V
int SetupIntercept() { HV_INTERCEPT_DESCRIPTOR Descriptor; HV_INTERCEPT_PARAMETERS Parameters = {0}; HV_STATUS hvStatus = 0; HV_PARTITION_ID PartID = 0x0, NextPartID = 0; // RAX- CPUID 0x11114444, DbgPrintString("SetupInterception was called"); Parameters.CpuidIndex = 0x11114444; Descriptor.Type = HvInterceptTypeX64Cpuid; Descriptor.Parameters = Parameters; hvStatus = WinHvGetPartitionId(&PartID); do{ hvStatus = WinHvGetNextChildPartition(PartID,NextPartID,&NextPartID); if (NextPartID != 0){ DbgLog("Child partition id", NextPartID); hvStatus = WinHvInstallIntercept(NextPartID, HV_INTERCEPT_ACCESS_MASK_EXECUTE, &Descriptor); DbgLog("hvstatus of WinHvInstallIntercept = ",hvStatus); } } while ((NextPartID != HV_PARTITION_ID_INVALID) && (hvStatus == 0)); return 0;}
void PrintCpuidInterceptMessage(PHV_MESSAGE hvMessage) {PHV_X64_CPUID_INTERCEPT_MESSAGE_phvCPUID = (PHV_X64_CPUID_NTERCEPT_MESSAGE)_hvMessage->Payload; DbgLog(" phvCPUID->DefaultResultRax",phvCPUID->DefaultResultRax); DbgLog(" phvCPUID->DefaultResultRbx",phvCPUID->DefaultResultRbx); DbgLog(" phvCPUID->DefaultResultRcx",phvCPUID->DefaultResultRcx); DbgLog(" phvCPUID->DefaultResultRdx",phvCPUID->DefaultResultRdx); if (phvCPUID->Rax == 0x11114444){ phvCPUID->DefaultResultRdx =0x12345678; DbgLog16(" phvCPUID->Header.Rip",phvCPUID->Header.Rip); DbgPrintString(" Interception was handled"); } }
Source: https://habr.com/ru/post/247273/
All Articles