[2022]hypervisor: 检测与预防(四) huoji hypervisor 2022-10-01 556 次浏览 0 次点赞 copy paster们久等了 书接上回,前情回顾.如果没有看过请浏览: [[2022]hypervisor: 检测与预防(三)](https://key08.com/index.php/2022/07/10/1493.html "[2022]hypervisor: 检测与预防(三)") ### XMM寄存器 xmm寄存器在vmexit的时候不会被reset/save.一般情况下是没有什么问题的,因为理论上你vmexit不用FPU的东西也不会出问题,但是如果你是VS编译的东西,就有可能会编译器给你赛了点浮点的东西,然后正好vmexit的时候需要用到xmm的东西,正好炸了你. 解决浮点有很多方法.我只介绍两个: ZT的方法是直接关闭浮点支持,这样出问题了能看得到是哪 ```cpp noir_writecr4(state->cr4|amd64_cr4_osfxsr_bit|amd64_cr4_osxsave_bit); ``` 我的方法比较简单,在栈上保存一下,当然也有问题,保存的不完整 ```cpp movaps xmmword ptr [rsp + 20h], xmm0 movaps xmmword ptr [rsp + 30h], xmm1 movaps xmmword ptr [rsp + 40h], xmm2 movaps xmmword ptr [rsp + 50h], xmm3 movaps xmmword ptr [rsp + 60h], xmm4 movaps xmmword ptr [rsp + 70h], xmm5 movaps xmmword ptr [rsp + 80h], xmm6 movaps xmmword ptr [rsp + 90h], xmm7 call svm_vmexit_handler movaps xmm7, xmmword ptr [rsp + 90h] movaps xmm6, xmmword ptr [rsp + 80h] movaps xmm5, xmmword ptr [rsp + 70h] movaps xmm4, xmmword ptr [rsp + 60h] movaps xmm3, xmmword ptr [rsp + 50h] movaps xmm2, xmmword ptr [rsp + 40h] movaps xmm1, xmmword ptr [rsp + 30h] movaps xmm0, xmmword ptr [rsp + 20h] ``` ### CR4/CR0 CRN这些操作比较复杂,坑会比较多,涉及到TLB与VMCB相关的东西,此外一些设置如果设置不好会造成#GP,以及watch dog timeout. 最简单的验证poc: ```cpp void verification::shadow_cr() { #ifndef use_memory_load typedef union _vf_cr0_t { struct { uint64_t protection_enable : 1; uint64_t monitor_coprocessor : 1; uint64_t emulation : 1; uint64_t task_switched : 1; uint64_t extension_type : 1; uint64_t numeric_error : 1; uint64_t reserved : 10; uint64_t write_protect : 1; uint64_t reserved_1 : 1; uint64_t alignment_mask : 1; uint64_t reserved_2 : 10; uint64_t not_write_through : 1; uint64_t cache_disable : 1; uint64_t paging : 1; uint64_t reserved_3 : 32; }; uint64_t full; } vf_cr0_t; __try { vf_cr0_t cr0; cr0.full = __readcr0(); cr0.numeric_error = !cr0.numeric_error; //force a VM exit by toggling the VMX required numeric error bit; this isn't required for VMWare since it VM exits on cr0.pe cr0.protection_enable = 0; //disable the PE bit __writecr0(cr0.full); return; } __except (EXCEPTION_EXECUTE_HANDLER) { //this causes VMWare to close; good hypervisors will inject a #GP(0) DebugPrint("[verification] check shadow cr0#1 success \n"); } __try { __writecr0(__readcr0() | (1 << 23)); DebugPrint("[verification] detect hv by cr0#2 \n"); } __except (EXCEPTION_EXECUTE_HANDLER) { DebugPrint("[verification] check shadow cr0#2 success \n"); } __try { __writecr4(__readcr4() | (1 << 23)); //non-existant bit } __except (EXCEPTION_EXECUTE_HANDLER) { DebugPrint("[verification] check shadow cr4 success \n"); } __try { asm_vf_cr0(); } __except (EXCEPTION_EXECUTE_HANDLER) { DebugPrint("[verification] crash vm by cr0 write \n"); } #endif } ``` 最好的办法是严格按照手册、KVM的操作来,比如这是CR4的 ```cpp void svm_exit::handle_cr4_write(_svm_guest_status* guest_context) { unsigned long old_cr4 = guest_context->vcpu->stack->guest_vmcb.state_save.Cr4; auto new_value = get_cr_exit_value(guest_context); #ifdef eac_debug if (guest_context->eac_access) { DebugPrint("eac cr4 write: %p \n", new_value); } #endif bool inject_gp = true; do { if (new_value & CR4_RESERVED_BITS) { break; } if (!(new_value & CR4_BITS_PAE)) { break; } if ((new_value ^ old_cr4) & CR4_BITS_LA57) { break; } if ((new_value & CR4_BITS_PCIDE) && !(old_cr4 & CR4_BITS_PCIDE)) { if (!guest_cpuid_has(vcpu, X86_FEATURE_PCID)) break; // PCID can not be enabled when cr3[11:0]!=000H or EFER.LMA=0 if ((huoji::_read_cr3(vcpu) & X86_CR3_PCID_MASK) || !is_long_mode(vcpu)) break; if (guest_context->vcpu->stack->guest_vmcb.state_save.Cr3 & (1 << 17)) { break; } } inject_gp = false; } while (false); if (inject_gp) { DebugPrint("[%s] inject #PG \n", __FUNCTION__); return inject_exception_gp(guest_context); } ..... } ``` ### 合成MSR ```cpp #define is_synthetic_msr(i) ((i>>30)==1) ``` ```cpp if ((msr_value >= msr_reserved_range_low && (msr_value <= msr_reserved_range_hight)) || msr_value == amd64_debug_control || is_synthetic_msr(msr_value)) { inject_exception_gp(guest_context); return; } ``` 本文由 huoji 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。 点赞 0
还不快抢沙发