|
想要查看内容赶紧注册登陆吧!
您需要 登录 才可以下载或查看,没有账号?立即注册
x
简介在学习vt时了解到无限硬件断点技术,即不依赖于dr寄存器实现硬件断点。
由于硬件断点依赖于调试寄存器 dr0-dr3,这就意味着只能设置4个硬件断点。 无限硬件断点的原理 :
根据目标地址计算出其PTE地址,设置PTE的 nx/xd 属性,即不可执行属性。
(由于PTE控制着4KB物理页的属性,因此目标代码所属的整个物理页都被设置为不可执行。)
当执行流执行至目标物理页时,由于代码的不可执行属性而触发 #PF 缺页中断。
此时根据触发缺页中断的线性地址判断是否为目标地址?若是,则修改PTE的执行属性并进行事件注入至 #DB,内核异常处理函数将会将该异常派发给调试器。若不是,则仍需要修复PTE的可执行属性,置位rflags.TF以便于下条指令触发 #DB 异常被vmm接管,修复cr2并进行事件注入 #PF。
当vmm接管 #DB 异常时,判断是否为目标进程的目标线性地址,并根据情况进行分类处理。
源码实现关键函数的源码如下: - void HandleOfInterruption()
- {
- Rflags rflags = { 0 };
- VmExitInterruptInformation exit_interrupt_info = { 0 };
- ExitQualification exit_qualification = { 0 };
- IA32_DEBUGCTL_STRUCRION ia32_debugctl = { 0 };
- rflags.all = g_pGuestRegs->rflags;
- asm_vmread32(&g_vmm_handle_config.exit_instruction_length, VM_EXIT_INSTRUCTION_LEN);
- asm_vmread(&exit_qualification, EXIT_QUALIFICATION);
- asm_vmread32(&exit_interrupt_info, VM_EXIT_INTR_INFO);
- asm_vmread32(&ia32_debugctl, IA32_DEBUGCTL);
- if (exit_interrupt_info.Bits.valid)
- {
- /*
- * 中断类型: 0.外部中断, 2.nmi, 3.硬件中断, 6.软中断
- */
- switch (exit_interrupt_info.Bits.vector)
- {
- case 1: // debug 硬件中断
- {
- // signel-step exit_qualification.Bits.bs=true
- if (rflags.Bits.tf && !ia32_debugctl.Bits.btf)
- {
- DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] #DB signel-step ==> GuestRIP: 0x%p, GuestRSP: 0x%p\n", g_pGuestRegs->rip, g_pGuestRegs->rsp);
- /*
- * 是否开启无线硬件中断? 若开启则重新设置页属性nx
- */
- if (g_vmx_config.enable_unlimit_hardware_breakpoint)
- {
- unsigned __int64 guest_cr3;
- asm_vmread(&guest_cr3, GUEST_CR3);
- if (directory_table_base.user_cr3 == guest_cr3 ||
- directory_table_base.kernel_cr3 == guest_cr3)
- {
- SetupPteNx(g_pGuestRegs->rip, TRUE);
- rflags.Bits.tf = FALSE;
- asm_vmwrite(GUEST_RFLAGS, rflags.all);
- break;
- }
- }
- g_vmm_handle_config.Config.Bits.event_inject = TRUE;
- break;
- }
- // haredWare breakpointer
- if (!rflags.Bits.tf && (exit_qualification.all & 0xf))
- {
- DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] #DB hard-ware ==> GuestRIP: 0x%p, GuestRSP: 0x%p\n", g_pGuestRegs->rip, g_pGuestRegs->rsp);
- g_vmm_handle_config.Config.Bits.event_inject = TRUE;
- break;
- }
- break;
- }
- case 3: // int3 软中断
- {
- DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] #BP ==> GuestRIP: 0x%p, GuestRSP: 0x%p\n", g_pGuestRegs->rip, g_pGuestRegs->rsp);
- g_vmm_handle_config.Config.Bits.event_inject = TRUE;
- break;
- }
- case 0xe: // page_fault 软中断
- {
- unsigned __int64 guest_cr3;
- asm_vmread(&guest_cr3, GUEST_CR3);
- if (g_vmx_config .enable_unlimit_hardware_breakpoint && (
- directory_table_base.user_cr3 == guest_cr3 ||
- directory_table_base.kernel_cr3 == guest_cr3))
- {
- DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] #PF ==> GuestRIP: 0x%p, GuestRSP: 0x%p, fault_address: 0x%p\n", g_pGuestRegs->rip, g_pGuestRegs->rsp, exit_qualification.all);
-
- /*
- * 目标地址: 1.取消nx; 2.将异常注入给#DB;
- */
- if (exit_qualification.all == targetAddress)
- {
- exit_interrupt_info.Bits.type = 3;
- exit_interrupt_info.Bits.vector = 1;
- exit_interrupt_info.Bits.error_code_valid = FALSE;
- g_vmm_handle_config.Config.Bits.event_inject = TRUE;
- SetupPteNx(exit_qualification.all, FALSE);
- }
- else
- { /* 程序正常返回执行 signel-step */
- SetupPteNx(exit_qualification.all, FALSE);
- g_vmm_handle_config.Config.Bits.event_inject = FALSE;
- rflags.Bits.tf = TRUE;
- asm_vmwrite(GUEST_RFLAGS, rflags.all);
- }
- }
- else
- {
- asm_WriteCr2(exit_qualification.all);
- g_vmm_handle_config.Config.Bits.event_inject = TRUE;
- }
- break;
- }
- default:
- DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] 未处理中断 ==> type: %d, index: %d\n", exit_interrupt_info.Bits.type, exit_interrupt_info.Bits.vector);
- }
- /*
- * 事件注入
- */
- if (g_vmm_handle_config.Config.Bits.event_inject)
- {
- VmEntryInterruptionInformationField interruption_information_field = { 0 };
- interruption_information_field.Bits.valid = TRUE;
- interruption_information_field.Bits.type = exit_interrupt_info.Bits.type;
- interruption_information_field.Bits.vector = exit_interrupt_info.Bits.vector;
- if (exit_interrupt_info.Bits.error_code_valid)
- {
- UINT64 ExitInterruptErrorCode = 0;
- interruption_information_field.Bits.deliver_error_code = TRUE;
- asm_vmread(&ExitInterruptErrorCode, VM_EXIT_INTR_ERROR_CODE);
- asm_vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, ExitInterruptErrorCode);
- }
- asm_vmwrite(VM_ENTRY_INSTRUCTION_LEN, g_vmm_handle_config.exit_instruction_length);
- asm_vmwrite(VM_ENTRY_INTR_INFO_FIELD, interruption_information_field.all);
- /*VmxProcessorBasedControls process_base;
- asm_vmread(&process_base.all, CPU_BASED_VM_EXEC_CONTROL);
- process_base.Bits.monitor_trap_flag = TRUE;
- asm_vmwrite(CPU_BASED_VM_EXEC_CONTROL, process_base.all);*/
- }
-
- }
- else
- DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[!] 无效ExitInterruptInfo.\n");
- tag_ret:
- return;
- }
- __int64 pte_base; // 用于线性地址与pte的转换
- DirectoryTableBase directory_table_base = { 0 };
- __int64* targetAddress = 0x0000000140001130;
- _PsLookupProcessByProcessId WkPsLookUpProcessByProcessId;
- void SetupPteNx(__int64* address, BOOLEAN setup)
- {
- PHYSICAL_ADDRESS pa;
- pa.QuadPart = 0xffffffffffffffff;
- PAttachProcessStruct attach_procee = (PAttachProcessStruct)MmAllocateContiguousMemory(sizeof(AttachProcessStruct), pa);
-
- attach_procee->target_cr3 = directory_table_base.kernel_cr3;
- attach_procee->pte = (((__int64)address >> 9) & 0x7ffffffff8) + pte_base;
- attach_procee->setup = setup;
- /*
- * 切换Cr3并修改pte
- */
- AttachProcess(attach_procee->target_cr3, &attach_procee->currect_cr3);
- memcpy(&attach_procee->pte_t, (void*)attach_procee->pte, 8);
- attach_procee->pte_t.Bits.xd = attach_procee->setup;
- memcpy((void*)attach_procee->pte, &attach_procee->pte_t, 8);
- AttachProcess(attach_procee->currect_cr3, &attach_procee->currect_cr3);
- MmFreeContiguousMemory(attach_procee);
- }
- void InitDirectoryTableBaseByPid(__int64 pid)
- {
- PEPROCESS pEProcess;
- WkPsLookUpProcessByProcessId(pid, &pEProcess);
- directory_table_base.kernel_cr3 = *(__int64*)((__int64)pEProcess + 0x28);
- directory_table_base.user_cr3 = *(__int64*)((__int64)pEProcess + 0x280);
- ObDereferenceObject(pEProcess);
- }
- void UnlimitHareWareBreakpoint(int index)
- {
- UNICODE_STRING unicode_PsLookUpProcessByProcessId;
- UNICODE_STRING unicode_MiSystemFault;
- idt_hook_config.Bits.set_pte_nx = TRUE;
- // 初始化PsLookupProcessByProcessId
- RtlInitUnicodeString(&unicode_PsLookUpProcessByProcessId, L"PsLookupProcessByProcessId");
- WkPsLookUpProcessByProcessId = (_PsLookupProcessByProcessId)MmGetSystemRoutineAddress(&unicode_PsLookUpProcessByProcessId);
- pte_base = *(__int64*)((__int64)MmProtectMdlSystemAddress + 0xc9);
- InitDirectoryTableBaseByPid(3724);
- SetupPteNx(targetAddress, TRUE);
- }
- asm_AttachProcess proc
- mov rax, cr3
- mov [rdx], rax
- mov cr3, rcx
- ret
- asm_AttachProcess endp
复制代码 效果图:
|
|