一
简介
二
源码实现
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
需要注意的是,我的测试环境为Windows10,单核。
看雪ID:ALwalker
https://bbs.kanxue.com/user-home-832354.htm
# 往期推荐
3、安卓加固脱壳分享
球分享
球点赞
球在看