在学习vt时了解到无限硬件断点技术,即不依赖于dr寄存器实现硬件断点。
由于硬件断点依赖于调试寄存器 dr0-dr3,这就意味着只能设置4个硬件断点。
无限硬件断点的原理 :
关键函数的源码如下:
效果图:
需要注意的是,我的测试环境为Windows10,单核。
参考:https://bbs.kanxue.com/thread-111149.htm
自己踩过的坑:
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.
将异常注入给
*
/
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
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.
将异常注入给
*
/
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;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2023-5-6 15:28
被ALwalker编辑
,原因: