-
-
[讨论]Intel 硬件虚拟化接管host idtr用以处理host时nmi以及未知msr等
-
发表于: 2023-4-25 21:12 6643
-
新人新帖,有啥不对,欢迎指出;
简单来讲就是自己构造一个idt,填到host_idtr字段里(废话)....
讲一下我的代码,当然,抄的开源项目,改了一些东西(狗头)
下面是构造idt的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | void ALvmSetIdteFunAdd(IDTE * idte_, UINT64 FunctionAdd) { IDTE * pIdte = (IDTE * )idte_; pIdte - >offset_low = (FunctionAdd >> 0 ) & 0xFFFF ; pIdte - >offset_middle = (FunctionAdd >> 16 ) & 0xFFFF ; pIdte - >offset_high = (FunctionAdd >> 32 ) & 0xFFFFFFFF ; } UINT64 ALvmIdtInitialization() { GDTR64_t idtr = { 0 }; __sidt(&idtr); auto ret = ALvmMMallocateMemory( 0x1000 ); if (ret && idtr.base) { memcpy(ret, (PVOID)idtr.base, 0x1000 ); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x00 ], (UINT64)&interrupt_handler_00_DE); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x01 ], (UINT64)&interrupt_handler_01_DB); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x02 ], (UINT64)&interrupt_handler_02_NMI); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x03 ], (UINT64)&interrupt_handler_03_BP); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x04 ], (UINT64)&interrupt_handler_04_OF); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x05 ], (UINT64)&interrupt_handler_05_BR); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x06 ], (UINT64)&interrupt_handler_06_UD); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x07 ], (UINT64)&interrupt_handler_07_NM); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x08 ], (UINT64)&interrupt_handler_08_DF); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x10 ], (UINT64)&interrupt_handler_10_TS); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x11 ], (UINT64)&interrupt_handler_11_NP); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x12 ], (UINT64)&interrupt_handler_12_SS); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x13 ], (UINT64)&interrupt_handler_13_GP); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x14 ], (UINT64)&interrupt_handler_14_PF); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x16 ], (UINT64)&interrupt_handler_16_MF); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x17 ], (UINT64)&interrupt_handler_17_AC); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x18 ], (UINT64)&interrupt_handler_18_MC); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x19 ], (UINT64)&interrupt_handler_19_XF); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x20 ], (UINT64)&interrupt_handler_20_VE); ALvmSetIdteFunAdd(&((IDTE * )ret)[ 0x21 ], (UINT64)&interrupt_handler_21_CP); for ( int i = 0 ; i < 255 ; i + + ) { if ((((PUINT64)ret)[i * 2 ] & 0x700 ) = = 0b110 << 8 ) gALvmIDTinterruptGateBitMap[i] = 1 ; } return (UINT64)ret; } else return 0 ; } |
大概就是,前32个中断都用了我自己的函数代替,其他的是复制的系统的
下面是构造自己的中断函数,这些函数都是用宏构造的,跳转至同一个异常处理.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | xtern ALvmIdtHandler : proc extern gALvmIdtKey : qword .code ; defined in trap - frame.h trap_frame struct ; general - purpose registers $rax qword ? $rcx qword ? $rdx qword ? $rbx qword ? $rbp qword ? $rsi qword ? $rdi qword ? $r8 qword ? $r9 qword ? $r10 qword ? $r11 qword ? $r12 qword ? $r13 qword ? $r14 qword ? $r15 qword ? ; interrupt vector $vector qword ? ; _MACHINE_FRAME $error qword ? $rip qword ? $cs qword ? $rflags qword ? $rsp qword ? $ss qword ? trap_frame ends ; pushes error code to stack IDT_HANDLER macro proc_name:req,code:req proc_name proc ; allocate space for the trap_frame structure (minus the size of the ; _MACHINE_FRAME, error code, and interrupt vector) sub rsp, 78h ; general - purpose registers mov trap_frame.$rax[rsp], rax mov trap_frame.$rcx[rsp], rcx mov trap_frame.$rdx[rsp], rdx mov trap_frame.$rbx[rsp], rbx mov trap_frame.$rbp[rsp], rbp mov trap_frame.$rsi[rsp], rsi mov trap_frame.$rdi[rsp], rdi mov trap_frame.$r8[rsp], r8 mov trap_frame.$r9[rsp], r9 mov trap_frame.$r10[rsp], r10 mov trap_frame.$r11[rsp], r11 mov trap_frame.$r12[rsp], r12 mov trap_frame.$r13[rsp], r13 mov trap_frame.$r14[rsp], r14 mov trap_frame.$r15[rsp], r15 ; first argument is the trap frame mov rcx, rsp ; call handle_host_interrupt sub rsp, 20h call ALvmIdtHandler add rsp, 20h mov trap_frame.$vector[rsp],rax ;把获取到的地址放在向量里 ; int 3 ; general - purpose registers mov rax, trap_frame.$rax[rsp] mov rcx, trap_frame.$rcx[rsp] mov rdx, trap_frame.$rdx[rsp] mov rbx, trap_frame.$rbx[rsp] mov rbp, trap_frame.$rbp[rsp] mov rsi, trap_frame.$rsi[rsp] mov rdi, trap_frame.$rdi[rsp] mov r8, trap_frame.$r8[rsp] mov r9, trap_frame.$r9[rsp] mov r10, trap_frame.$r10[rsp] mov r11, trap_frame.$r11[rsp] mov r12, trap_frame.$r12[rsp] mov r13, trap_frame.$r13[rsp] mov r14, trap_frame.$r14[rsp] mov r15, trap_frame.$r15[rsp] ; free the trap_frame add rsp, 78h ; pop the interrupt vector add rsp, 8 test qword ptr[rsp - 8 ], - 1 jnz to_system ; pop the error code add rsp, 8 ; int 3 iretq to_system: ;pop 错误代码 add rsp, code ;mov rax,qword ptr[rsp - 8 - code] ; int 3 jmp qword ptr[rsp - 8 - code] ;跳到system idt proc_name endp endm ; pushes error code to stack DEFINE_ISR macro interrupt_vector:req, proc_name:req proc_name proc ; interrupt vector is stored right before the machine frame push interrupt_vector jmp ALvmIdtHandler_asm_yes proc_name endp endm ; doesn't push error code to stack DEFINE_ISR_NO_ERROR macro interrupt_vector:req, proc_name:req proc_name proc ; push a dummy error code onto the stack push 0 ; interrupt vector is stored right before the machine frame push interrupt_vector jmp ALvmIdtHandler_asm_no proc_name endp endm IDT_HANDLER ALvmIdtHandler_asm_no , 8 IDT_HANDLER ALvmIdtHandler_asm_yes , 0 DEFINE_ISR_NO_ERROR 0 , interrupt_handler_00_DE ;; / * * Divide - by - Zero - Error Exception (Vector 0 ) * / DEFINE_ISR_NO_ERROR 1 , interrupt_handler_01_DB ;; / * * Debug Exception (Vector 1 ) * / DEFINE_ISR_NO_ERROR 2 , interrupt_handler_02_NMI ;; / * * Non - Maskable - Interrupt Exception (Vector 2 ) * / DEFINE_ISR_NO_ERROR 3 , interrupt_handler_03_BP ;; / * * Breakpoint Exception (Vector 3 ) * / DEFINE_ISR_NO_ERROR 4 , interrupt_handler_04_OF ;; / * * Overflow Exception (Vector 4 ) * / DEFINE_ISR_NO_ERROR 5 , interrupt_handler_05_BR ;; / * * Bound - Range Exception (Vector 5 ) * / DEFINE_ISR_NO_ERROR 6 , interrupt_handler_06_UD ;; / * * Invalid - Opcode Exception (Vector 6 ) * / DEFINE_ISR_NO_ERROR 7 , interrupt_handler_07_NM ;; / * * Device - Not - Available Exception (Vector 7 ) * / DEFINE_ISR 8 , interrupt_handler_08_DF ;; / * * Double - Fault Exception (Vector 8 ) * / DEFINE_ISR_NO_ERROR 10 , interrupt_handler_10_TS ;; / * * Invalid - TSS Exception (Vector 10 ) * / DEFINE_ISR 11 , interrupt_handler_11_NP ;; / * * Segment - Not - Present Exception (Vector 11 ) * / DEFINE_ISR 12 , interrupt_handler_12_SS ;; / * * Stack Exception (Vector 12 ) * / DEFINE_ISR 13 , interrupt_handler_13_GP ;; / * * General - Protection Exception (Vector 13 ) * / DEFINE_ISR 14 , interrupt_handler_14_PF ;; / * * Page - Fault Exception (Vector 14 ) * / DEFINE_ISR_NO_ERROR 16 , interrupt_handler_16_MF ;; / * * x87 Floating - Point Exception - Pending (Vector 16 ) * / DEFINE_ISR 17 , interrupt_handler_17_AC ;; / * * Alignment - Check Exception (Vector 17 ) * / DEFINE_ISR_NO_ERROR 18 , interrupt_handler_18_MC ;; / * * Machine - Check Exception (Vector 18 ) * / DEFINE_ISR_NO_ERROR 19 , interrupt_handler_19_XF ;; / * * SIMD Floating - Point Exception (Vector 19 ) * / DEFINE_ISR_NO_ERROR 20 , interrupt_handler_20_VE ;;EPT violations This exception can occur only on processors ;; that support the 1 - setting of the “EPT - violation #VE” VM-execution control. DEFINE_ISR 21 , interrupt_handler_21_CP ;; / * * Control - Protection Exception (Vector 21 ) * / |
在异常处理内判断是否认识此异常,如果不认识,则返回系统异常处理函数地址,然后跳过去执行,让系统接管不认识的异常,经过测试,可以正常单步之类的调试...理论上缺页异常啥的也不是不行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | extern "C" UINT64 ALvmIdtHandler(trap_frame * frame) { / / ALdbgPut(); switch (frame - >vector) { / / host NMIs case X86_EXCEPTION_VECTOR_NMI: { if (gALvmCpuObject.cpuType = = OR_VM_CPU_TYPE_intel) { VMX_PRIMARY_PROCBASED_EXEC_CONTROLS ctrl = { 0 }; UINT64 a = 0 ; __vmx_vmread(VMX_VMCS32_CTRL_PROC_EXEC, &a); ctrl.bits = a; ctrl.nmi_window_exiting = 1 ; __vmx_vmwrite(VMX_VMCS32_CTRL_PROC_EXEC, ctrl.bits); auto currentCore = ALvmGetCurrentCoreObject(); currentCore - >vmxInfo.queuedNmis + + ; return 0 ; } else break ; } / / host exceptions default: { / / no registered exception handler if (!frame - >r10 || frame - >r11 ! = gALvmIdtKey) break ; / / jump to the exception handler frame - >rip = frame - >r10; / / slightly helps prevent infinite exceptions frame - >r10 = 0 ; frame - >r11 = 0 ; auto currentCore = ALvmGetCurrentCoreObject(); currentCore - >exceptionInfo.find = 1 ; currentCore - >exceptionInfo.vector = frame - >vector; currentCore - >exceptionInfo.errorCode = frame - >error; return 0 ; } } / / ALdbgKill(frame - >rcx, 0 ); / / ALdbgKill(frame - >rip, frame); auto a = ALvmGetSystemIdt(frame - >vector); / / ALdbgPut( "%p" , frame - >vector); return a; } |
接管完idt就可以自定义带异常处理指令调用了,
类似:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ALvmIdtAsm_rdmsr proc mov r11,gALvmIdtKey mov r10,find xor rax,rax xor rdx,rdx rdmsr find: shl rdx, 32 or rax,rdx ret ALvmIdtAsm_rdmsr endp |
想处理你其实还要有其他操作,拦截2号中断,开启虚拟nmi啥的.下面的项目里都有,挑着抄呗
这个项目把常见的一些检测都处理了...然并卵
抄的项目
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2023-4-25 21:18
被aljt_糖刀编辑
,原因:
赞赏
看原图
赞赏
雪币:
留言: