首页
社区
课程
招聘
[转帖]vt idt redirect (idt重定向)
发表于: 2011-3-2 16:26 16475

[转帖]vt idt redirect (idt重定向)

2011-3-2 16:26
16475
1、检测你的CPU是否支持VMX
MOV EAX,1
CPUID
检测ECX的第5位,如果为1则支持VMX
2、初始化VMXON region
pVMXONRegion = MmAllocateNonCachedMemory( 4096 );
RtlZeroMemory( pVMXONRegion, 4096 );
PHYSICAL_ADDRESS       PhysicalVMXONRegionPtr=MmGetPhysicalAddress( pVMXONRegion );
__asm
{
MOV             ECX, IA32_VMX_BASIC_MSR_CODE //0x480
RDMSR
LEA              EBX, vmxBasicMsr
MOV             [EBX+4], EDX
MOV             [EBX], EAX
}
*(pVMXONRegion) = vmxBasicMsr.RevId;
3、设置VMXE位(CR4)
CR4_REG                                         cr4_reg = {0};
__asm
{
PUSH     EAX
_emit      0x0F       // MOV   EAX, CR4
_emit      0x20
_emit      0xE0
MOV             cr4_reg, EAX
POP        EAX
}
cr4_reg.VMXE = 1;
__asm
{
PUSH     EAX
MOV             EAX, cr4_reg
_emit      0x0F       // MOV   CR4, EAX
_emit      0x22
_emit      0xE0
POP        EAX
}
4、执行VMXON指令
__asm
{
PUSH     DWORD PTR PhysicalVMXONRegionPtr.HighPart
PUSH     DWORD PTR PhysicalVMXONRegionPtr.LowPart
_emit      0xF3       // VMXON [ESP]
_emit      0x0F
_emit      0xC7
_emit      0x34
_emit      0x24
PUSHFD
POP        eFlags
ADD              ESP, 8
}
if( eFlags.CF == 1 )
{
Log( "ERROR : VMXON operation failed." , 0 );
return 0;
}
//到这里说明已经进入了VMX模式,并且工作在ROOT下了

5、初始化VMCS region
//这是个4K大小的内存块
ULONG *pVMCSRegion = MmAllocateNonCachedMemory( 4096 );
RtlZeroMemory( pVMCSRegion, 4096 );
PHYSICAL_ADDRESS  PhysicalVMCSRegionPtr = MmGetPhysicalAddress( pVMCSRegion );
*(pVMCSRegion) = vmxBasicMsr.RevId;
__asm
{
PUSH     DWORD PTR PhysicalVMCSRegionPtr.HighPart
PUSH     DWORD PTR PhysicalVMCSRegionPtr.LowPart
_emit      0x66       // VMCLEAR [ESP]
_emit      0x0F
_emit      0xc7
_emit      0x34
_emit      0x24
ADD       ESP, 8
PUSHFD
POP        eFlags
}
if( eFlags.CF != 0 || eFlags.ZF != 0 )
{
Log( "ERROR : VMCLEAR operation failed." , 0 );
return 0;
}
//到这里,说明VMCS region初始化完成了
6、装载VMCS region
__asm
{
PUSH     DWORD PTR PhysicalVMCSRegionPtr.HighPart
PUSH     DWORD PTR PhysicalVMCSRegionPtr.LowPart
_emit      0x0F       // VMPTRLD [ESP]
_emit      0xC7
_emit      0x34
_emit      0x24
ADD       ESP, 8
}
7、设置VMCS region中的相关域
这些域包括:
A、Guest的各个段寄存器的selector,base,limit,access right
B、Host的各个段寄存器的selector,base,limit,access right
C、Guest的CR0,CR3,CR4,IDTR,GDTR,LDTR,Rflag,SYSENTER_CS,SYSENTER_EIP,SYSENTER_ESP
D、Host的CR0,CR3,CR4,IDTR,GDTR,LDTR,Rflag,SYSENTER_CS,SYSENTER_EIP,SYSENTER_ESP
如:
USHORT    seg_selector = 0;
__asm  MOV      seg_selector, ES
Log( "Setting Guest ES Selector" , seg_selector );
WriteVMCS( 0x00000800, seg_selector );
//Guest CS selector                                                             00000802H
__asm  MOV      seg_selector, CS
Log( "Setting Guest CS Selector" , seg_selector );
WriteVMCS( 0x00000802, seg_selector );

E、Exception bitmap
作为调试器,我们需要拦截INT1和INT3中断,因此,Exception bitmap起码要这样设置:
ULONG        temp32 = 0x00000000;
SetBit( &temp32, 1 );                                              // Single Step (INT 1) int1
SetBit( &temp32, 3 );                                              // Software Interrupt (INT 3)
WriteVMCS( 0x00004004, temp32 );
F、VMX Abort Error Code域
这个域需要清成0
RtlZeroMemory( (pVMCSRegion + 4), 4 );
G、Guest的ESP和EIP
WriteVMCS( 0x0000681C, (ULONG)GuestStack );
WriteVMCS( 0x0000681E, (ULONG)GuestReturn );
H、Host的ESP和EIP
PVOID   HostStack = ExAllocatePoolWithTag( NonPagedPool , 0x8000, 'kSkF' );
If(HostStack == NULL)
{
//…出错…
}
WriteVMCS( 0x00006C14, ((ULONG)HostStack + 0x7FFF) );
WriteVMCS( 0x00006C16, (ULONG)VMExitProc );// VMExitProc就是VMM的程序入口
8、执行VMLAUNCH
__asm
{
_emit      0x0F       // VMLAUNCH
_emit      0x01
_emit      0xC2
}

// 如果成功,就不会到这里了!
__asm
{
PUSHFD
POP        eFlags
}
Log( "VMLAUNCH Failure" , 0xDEADDEAD );
if( eFlags.CF != 0 || eFlags.ZF != 0 || TRUE )
{
ULONG  ErrorCode= VMRead_ULONG(0x00004400);
Log( "VM Instruction Error" , ErrorCode );
}

VMMExitProc
extern "C"
__declspec( naked ) VOID VMMExitProc( )
{
__asm CLI
__asm PUSHAD

  //保存通用寄存器
__asm MOV GuestEAX, EAX
__asm MOV GuestEBX, EBX
__asm MOV GuestECX, ECX
__asm MOV GuestEDX, EDX
__asm MOV GuestEDI, EDI
__asm MOV GuestESI, ESI
__asm MOV GuestEBP, EBP

  //保存调试寄存器
__asm
{
push eax
mov eax,dr0
mov GuestDr0,eax
mov eax,dr1
mov GuestDr1,eax
mov eax,dr2
mov GuestDr2,eax
mov eax,dr3
mov GuestDr3,eax
mov eax,dr6
mov GuestDr6,eax
pop eax
}
GuestDr7 = VMRead_ULONG(VMX_VMCS_GUEST_DR7);//0x681A

  GuestEIP = VMRead_ULONG(VMX_VMCS_GUEST_RIP);//0x681E
GuestEFlags = VMRead_ULONG(VMX_VMCS_GUEST_RFLAGS);//0x6820

//获取本次Exit的详细信息
ULONG ExitReason = VMRead_ULONG(VMX_VMCS_RO_EXIT_REASON);//0x4402
ULONG ExitInterruptionInformation = VMRead_ULONG(VMX_VMCS_RO_EXIT_INTERRUPTION_INFO);//0x4404
ULONG ExitInstructionLength = VMRead_ULONG(VMX_VMCS_RO_EXIT_INSTR_LENGTH);//0x440C
ULONG ExitQualification = VMRead_ULONG(VMX_VMCS_RO_EXIT_QUALIFICATION);//0x6400

  if(ExitReason==0)//是个Exception
{
int IntrNo = ExitInterruptionInformation & 0xFF;
if(IntrNo==1 || IntrNo==3)//是INT1或者INT3
{
if(IsMyBreakPoint())
{//是我们自己设置的断点
DoSomeThing();
}
else
{//我们该向Guest注入一个异常,让Guest的中断处理程序能够继续处理,仿佛一切都没发生
ULONG InjectIrqInfo = 0x80000300 | IntrNo;
// 设置 VM-Entry Exception域
WriteVMCS( VMX_VMCS_CTRL_ENTRY_INSTR_LENGTH, ExitInstructionLength);
WriteVMCS( VMX_VMCS_CTRL_ENTRY_IRQ_INFO, InjectIrqInfo);
}
}
}
if(ExitReason==0x12)//VMMCALL
{//我们用一个VMMCALL指令来通知VMM结束VMX
if(GuestEAX == 0x12345678)//我们自己约定的规则
{
GuestEIP += ExitInstructionLength;
goto Exit;
}
}
goto Resume;
Exit:
//  关闭VMX.
DbgPrint("Terminating VMX Mode.");
__asm
{
_emit 0x0F  // VMXOFF
_emit 0x01
_emit 0xC4
POPAD
MOV   ESP, GuestESP
STI
JMP   GuestEIP
}

  Resume:   
//  Need to execute the VMRESUME without having changed
//  the state of the GPR and ESP et cetera.
__asm
{
push      eax
mov       eax,GuestDr0
mov       DR0,eax
mov       eax,GuestDr1
mov       DR1,eax
mov       eax,GuestDr2
mov       DR2,eax
mov       eax,GuestDr3
mov       DR3,eax
mov       eax,GuestDr6
mov       DR6,eax
pop       eax
POPAD
MOV   EAX, GuestEAX
MOV   EBX, GuestEBX
MOV   ECX, GuestECX
MOV   EDX, GuestEDX
MOV   ESI, GuestESI
MOV   EDI, GuestEDI
MOV   EBP, GuestEBP
STI
_emit 0x0F  // VMRESUME
_emit 0x01
_emit 0xC3

//永远不会到这里
}  

转身 http://www.debugvt.com/#2
不知道又是哪个大牛的vt调试器诞生了.....

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (16)
雪    币: 34
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
沙发,无法看懂,只能膜拜~
2011-3-2 17:39
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
3
难点 就在这里 唉,
谁能告诉下呀
if(IsMyBreakPoint())
{//是我们自己设置的断点
DoSomeThing();
}
2011-3-2 22:35
0
雪    币: 196
活跃值: (135)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
4
看着有点眼熟的代码,查了一下,果然是的  :)
2011-3-2 23:30
0
雪    币: 475
活跃值: (64)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
那个DoSomeThing();里的东西才是idt redirect
2011-3-3 09:27
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
哟西,都知道的太多了
2011-3-3 11:30
0
雪    币: 33
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
DebugVT 是一款利用Intel-VT和AMD-V技术实现的一个内核级调试器,与传统调试器相比有以下优势:

1、 与操作系统无关,不使用操作系统的调试接口

2、 不修改操作系统的IDT

3、 不挂钩操作系统内核代码

4、 保护DR寄存器,透明使用,不会被检测和清除

5、 可中断关键指令,或者进行模拟处理,如:CPUID,SYSENTER,RDTSC,MOV to CR,MOV from CR等
2011-3-3 15:33
0
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
自己保存一份IDT表 然后退到VMM后再自己重定向地址 你们懂的
2011-3-6 05:23
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
9
exetxt 兄 ,怎么重定向呀
设置bit 位 断在 VM-exit interruption information
处理完就写入 eip,eip 里的地址 就是要断点的地址
VmWrite(0x681E, ExitEip[ccpu]);
VmWrite(0x401A, ExitInstructionLength[ccpu]);   

我当时也有想法 在这里 替换 中断表
但是事件处理完毕后,不管匝地还是调用了系统的 int1 中断
要换回 中断表也没地方换,如果在替换的过程中,检测程序也检测
中断是否修改的话,还是的完蛋。。。。。。求解。
2011-3-7 15:00
0
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
别问我。。。我到现在都被把VT的代码看懂
2011-3-10 10:33
0
雪    币: 217
活跃值: (45)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
我用1行汇编代码就能检测是不是在VT GUEST状态.....
2011-3-10 13:33
0
雪    币: 217
活跃值: (45)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
并不是我吹,
我用10行汇编代码就能检测本系统是不是在VT GUEST调试状态.....
包括Intel和AMD的所有CPU
2011-3-10 13:35
0
雪    币: 34
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
那块放代码啊
2011-3-10 14:56
0
雪    币: 217
活跃值: (45)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
代码就不放了,简单说个发现《WRMSR/RDMSR的INTERCEPT》的方法。
RING3和RING0,或#GP异常中 嵌套写 产生#GP异常的指令,WRMSR!!!

逐步返回,RING3程序在异常处理等待指定结果,如果没进来,就说明这里有鬼了。

唯一不被发现的方法是HOST模拟WRMSR和RDMSR。
但是这个实现起来相当的困难,因为MSR太多太多,而且每个MSR产生的Exption理由也不同。
至于ExpCode......
2011-3-15 17:52
0
雪    币: 123
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
貌似VMX的开发资料很少...有没有人提供一份观摩下?
2011-3-16 06:17
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
膜拜装逼犯~

另:exitcode filter
2011-3-16 08:39
0
雪    币: 217
活跃值: (45)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
17
我擦,居然被说成....
能否该词,我倒是喜欢“装逼大王”..

另外搞这方面的同志,可以找我,我也在制造VMDebugger中...
可以互相探讨,共享资源。
2011-3-18 15:39
0
游客
登录 | 注册 方可回帖
返回
//