支持X64下EPT开启,代码仿照joen的VT源码写的,在硬盘一年啦,没一点用,发出来给新手学习下,下代码的请点个赞,谢谢~!
交流QQ群,请去John大神的DdvpDbg群
写一下关于DR寄存器拦截
//DR寄存器字段结构如下
typedef struct _MOV_DR_QUALIFICATION {
unsigned DebugRegIndex : 3;//记录访问的dr调试寄存器
unsigned Reserved1 : 1;
unsigned DirectionAccess : 1;//读还是写
unsigned Reserved2 : 3;
unsigned GeneralReg : 4;//记录使用的通用寄存器
unsigned Reserved3 : 20;
} MOV_DR_QUALIFICATION, *PMOV_DR_QUALIFICATION;
//DR寄存器访问
BOOLEAN HandleDrAccess(PCPU pCpu, PGUEST_REGS pGuestRegs)
{
ULONG32 Exit;
ULONG32 DrREW = 0;
ULONG64 Dr,RegDrn;
ULONG64 Reg;
HANDLE Thireaid,ProcessID;
ULONG64 InstructionLength;
ULONG64 GuestCr3;
PMOV_DR_QUALIFICATION pExitQualification;
ULONG64 RegDr0, RegDr1, RegDr2, RegDr3, RegDr6, RegDr7;
//nt!KiSaveDebugRegisterState nt!KiRestoreDebugRegisterState:
//只有这2个函数访问时候才有陷阱帧
PKTRAP_FRAME TrapFrame = (PKTRAP_FRAME)(pGuestRegs->rbp - 0x80);
ULONG64 GuestDr7;// = (ULONG32)TrapFrame->Dr7;
PDEBUG_DR7 pRegDr7;// = (PDEBUG_DR7)&GuestDr7;
ULONG64 GuestRip = ReadVMCS(GUEST_RIP);
RegDr0 = RegGetDrn(0);
RegDr1 = RegGetDrn(1);
RegDr2 = RegGetDrn(2);
RegDr3 = RegGetDrn(3);
RegDr6 = RegGetDrn(6);
RegDr7 = RegGetDrn(7);
Thireaid = PsGetCurrentThreadId();
ProcessID = PsGetCurrentProcessId();
GuestCr3 = ReadVMCS(GUEST_CR3);
Exit = (ULONG32)ReadVMCS(EXIT_QUALIFICATION);
pExitQualification = (PMOV_DR_QUALIFICATION)&Exit;
if (MOV_FROM_DR == pExitQualification->DirectionAccess)//判断读 从
{
Dr = RegGetDrn(pExitQualification->DebugRegIndex);
SetReg(pGuestRegs, pExitQualification->GeneralReg, Dr);
}
if (MOV_TO_DR == pExitQualification->DirectionAccess)//判断写
{
Reg = GetReg(pGuestRegs, pExitQualification->GeneralReg);
RegSetDrn(pExitQualification->DebugRegIndex, Reg);
}
InstructionLength = ReadVMCS(VM_EXIT_INSTRUCTION_LEN);
WriteVMCS(GUEST_RIP, ReadVMCS(GUEST_RIP) + InstructionLength);
return TRUE;
}
拦截DR寄存器在虚拟机里不能同时拦截INT3异常或者INT1一起开启,
如果同时拦截,当产生int1 int3异常,虚拟机会卡死,个人觉得是虚拟机的BUG
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法