首页
社区
课程
招聘
[讨论]Intel 硬件虚拟化接管host idtr用以处理host时nmi以及未知msr等
发表于: 2023-4-25 21:12 6681

[讨论]Intel 硬件虚拟化接管host idtr用以处理host时nmi以及未知msr等

2023-4-25 21:12
6681

新人新帖,有啥不对,欢迎指出;

 

简单来讲就是自己构造一个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_糖刀编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//