首页
社区
课程
招聘
[原创]一个可拦截DR,CR,Int 1, Int3操作的VT驱动
发表于: 2015-12-21 11:20 12795

[原创]一个可拦截DR,CR,Int 1, Int3操作的VT驱动

2015-12-21 11:20
12795

滴水之恩,涌泉相报,之前遇到的VT问题在看雪解决了,现在分享下源码,因为每个人的代码侧重点不一样,所以可能对刚刚入门VT的朋友影响也不同,我吃VT的亏吃了两三个月,坚决不能让朋友们再吃亏了,这次非得普及下,现在代码可以拦截rdmsr wrmsr int 1  int 3 dr cr,目前只有这些功能,目前只支持xp单核(win7还没来得及调试),卸载通过调用的VMCALL,但是有时候会蓝屏 (⊙﹏⊙) 希望有兴趣的朋友和这方面的大牛可以加群探讨:522814899  (我们争取不做水群)

下载: VtTest.rar


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 3
支持
分享
最新回复 (23)
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
2
感谢楼主的热心分享
2015-12-21 11:57
0
雪    币: 2324
活跃值: (4963)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
这个····支持下·1~
2015-12-21 12:18
0
雪    币: 3725
活跃值: (624)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
一个接一个的放出源码,藏龙卧虎啊!火钳...
2015-12-21 13:23
0
雪    币: 83
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
楼主最近大放血~~
2015-12-21 13:48
0
雪    币: 302
活跃值: (246)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
6
哈哈,你怎么知道啊
2015-12-21 14:19
0
雪    币: 302
活跃值: (246)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
7
哈哈,就当普及下VT吧
2015-12-21 14:21
0
雪    币: 302
活跃值: (246)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
8
谢谢,看您的精华就知道您是位神牛!
2015-12-21 14:22
0
雪    币: 302
活跃值: (246)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
9
哈哈,多谢大牛的支持
2015-12-21 14:24
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
10
VT现在已经算是比较普及的东西了~
2015-12-21 17:25
0
雪    币: 302
活跃值: (246)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
11
嗯嗯,只不过现在网上除了Ddvp和NBP,基本很少有介绍VT的代码了,这里就共享啦
2015-12-21 18:03
0
雪    币: 191
活跃值: (848)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
12
感谢分享
2015-12-21 18:24
0
雪    币: 173
活跃值: (1204)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
老V的AGP的代码里不也有VT的东西么,可以看不懂
2015-12-21 19:25
0
雪    币: 44
活跃值: (186)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
楼主很牛....果断顶贴
2015-12-21 22:22
0
雪    币: 21
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
感谢楼主的无私奉献,顶!
2015-12-22 09:39
0
雪    币: 443
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
楼主是怎么调试VT的呢?IDA加VMWARE?还是bochs?
什么时候来个调试VT的教程呢?
2015-12-24 16:08
0
雪    币: 302
活跃值: (246)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
17
源码里有个错误,我今天才发现,就是696行那个PUSH POP操作,当时在测试些东西,忘了恢复了,非常抱歉。。。

源码里是:
                        PUSH        EntryEDI
                        PUSH        EntryESI
                        PUSH        EntryEBP
                        PUSH        EntryESP
                        PUSH        EntryEBX
                        PUSH        EntryEDX
                        PUSH        EntryECX
                        PUSH        EntryEAX
                        POPAD

正确的应该是:
                  PUSH        EntryEAX
                        PUSH        EntryECX
                        PUSH        EntryEDX       
                        PUSH        EntryEBX                                       
                        PUSH        EntryESP                       
                        PUSH        EntryEBP
                        PUSH        EntryESI                               
                        PUSH        EntryEDI
                        POPAD
2015-12-24 20:08
0
雪    币: 302
活跃值: (246)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
18
这个很简单啊,windbg+VM10,很多大牛都说不能调试,可是我却真真的调试了,奇怪,可能是HOST和GUEST相同CR3的原因吧
2015-12-24 20:10
0
雪    币: 22
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
感谢分享
2015-12-25 09:40
0
雪    币: 475
活跃值: (64)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
20
我以前用bochs是因为电脑的cpu本身不带vt无法使用vm的嵌套vt来调试,重新购买了支持vt的cpu后可以使用新版vm进行调试。我所传的vt代码带有手动开启bochs的主板vt开关的部分在真机上那个地方是不能修改的,所以在真机上蓝屏,只要bin里nop掉一个字节就可在真机上运行。i5 cpu win7 sp1,vista sp2  x86真机测试通过。
你这个vt还是只是个开始,难的还在后面,多核虚拟化、idt重定向都很麻烦。楼主加油,早日成功!
2015-12-25 11:45
0
雪    币: 302
活跃值: (246)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
21
哇哇哇,法师大神,我看过你的好多帖子,收益颇丰,现在在处理多核虚拟化,遇到了个很棘手的问题,如果多个CPU共用一个HOST_RIP的话,得保证每次只能有一个处理器VM-EXIT,不然有其他处理器修改HOST_RIP中的变量,会造成不可预测的错误,看了其他很多人的64位代码,有些是直接共用,有些是对HOST_RIP的开始处的IRQL增加到DPC,然后结束处恢复到原来的IRQL,于是我也比着葫芦画瓢的在HOST_RIP开始处增加到DPC,中间处理代码,处理完后降低为原来的IRQL,可是经常蓝屏或者卡死,于是一步步缩小代码,发现是MOV EAX, CR3的问题,也就是系统中只能有一次MOV EAX,CR3的操作,如果再有MOV EAX,CR3的指令,系统就会卡死,我在拦截MOV EAX,CR3的地方下了个断点,只能断下来一次,如果再有MOV EAX,CR3的操作,根本无法断下来,代码我检查了好几遍了,也没发现什么错误,法师大神能不能帮忙看下啊


ULONG	GuestEAX;
ULONG	GuestEBX;
ULONG	GuestECX;
ULONG	GuestEDX;
ULONG	GuestEBP;
ULONG	GuestESP;
ULONG	GuestESI;
ULONG	GuestEDI;
KIRQL 	VmExitChangeIrql, VmExitCurrentIrql;

//////////////////////////////////////////// 虚拟机处理系统 ////////////////////////////////////////////////////////
__declspec( naked ) VOID VMMEntryPoint( )
{	

	_asm	CLI
	_asm	PUSHAD

	VmExitChangeIrql = 0;
	VmExitCurrentIrql = KeGetCurrentIrql();
	if (VmExitCurrentIrql < DISPATCH_LEVEL)
	{
		VmExitChangeIrql = KeRaiseIrqlToDpcLevel();
	}
	
	_asm	STI
	_asm	POPAD

	
	_asm{
		CLI
			MOV GuestEAX, EAX
			MOV GuestEBX, EBX
			MOV GuestECX, ECX
			MOV GuestEDX, EDX
			MOV GuestEBP, EBP
			MOV GuestESI, ESI
			MOV GuestEDI, EDI
	}
	
	
	ReadGuestState();		
	GuestResumeEIP = GuestEIP + ExitInstructionLength;
	VMWRITE(GUEST_RIP,(ULONG)GuestResumeEIP );		//0x0000681E 	
	
	if(ExitReason==0xA){
		
		if(GuestEAX==0x123){
			
			GuestEBX=0x11111111;
			GuestECX=0x22222222;
			GuestEDX=0x33333333;	
		
		}
		
		else{		
		
			_asm{
				MOV EAX, GuestEAX
				CPUID
				MOV GuestEAX, EAX
				MOV GuestEBX, EBX
				MOV GuestECX, ECX
				MOV GuestEDX, EDX
			}
		}	
		
		_asm	JMP ResumeGuest			
	}
	
	if(ExitReason==0x1C){
		
		movcrControlRegister= (ExitQualification & 0x0000000F);		// bit0-bit3
		movcrAccessType= ( (ExitQualification>>4) & 0x00000003);	// bit4-bit5
		movcrOprandType= ( (ExitQualification>>6) & 0x00000001);	// bit6
		movcrGeneralPurposeRegister= ( (ExitQualification>>8) &0xF);// bit8-bit11
		
		if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 0 )
		{
			VMWRITE( GUEST_CR3, GuestEAX );
			_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 1 )
		{
			VMWRITE( GUEST_CR3, GuestECX );
			_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 2 )
		{
			VMWRITE( GUEST_CR3, GuestEDX );
			_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 3 )
		{
			VMWRITE( GUEST_CR3, GuestEBX );
			_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 4 )
		{
			VMWRITE( GUEST_CR3, GuestESP );
			_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 5 )
		{
			VMWRITE( GUEST_CR3, GuestEBP );
			_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 6 )
		{
			VMWRITE( GUEST_CR3, GuestESI );
			_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 7 )
		{
			VMWRITE( GUEST_CR3, GuestEDI );
			_asm	JMP ResumeGuest	
		}


		//	Control Register Access (reg32 <-- CR3)
		// 
		if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 0 )

		{
//    错误出现在这里,我在MOV EAX,GuestCR3这里下了个断点,只能断下来一次,比如打开DbgView和Xuer都有MOV EAX,CR3的操作
// 如果先打开DbgView程序会断到这里,如果再打开Xuer,程序就断不到这里了,系统会卡死
// 如果先打开Xuer,程序会断到这里,再打开DbgView的话,程序就断不下来了

//也就是只有一次MOV EAX,CR3的操作,我怀疑是不是把EAX赋值给GuestEAX的过程中GuestEAX会不会被改写了,但是这也仅仅只是个猜测,无法证实


				_asm	MOV EAX	, GuestCR3
				_asm	MOV GuestEAX, EAX
				_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 1 )
		{
				_asm	MOV EAX	, GuestCR3
				_asm	MOV GuestECX, EAX
				_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 2 )
		{
				_asm	MOV EAX	, GuestCR3		
				_asm	MOV GuestEDX, EAX
				_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 3 )
		{
				_asm	MOV EAX	, GuestCR3		
				_asm	MOV GuestEBX, EAX
				_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 4 )
		{	
				VMWRITE(GUEST_RSP, GuestCR3);
				_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 5 )
		{
				_asm	MOV EAX	, GuestCR3		
				_asm	MOV GuestEBP, EAX
				_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 6 )
		{
				_asm	MOV EAX	, GuestCR3			
				_asm	MOV GuestESI, EAX
				_asm	JMP ResumeGuest	
		}
		if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOprandType == 0 && movcrGeneralPurposeRegister == 7 )
		{
				_asm	MOV EAX	, GuestCR3			
				_asm	MOV GuestEDI, EAX
				_asm	JMP ResumeGuest	
		}   		
	}
	
	PrintGuestState();
	
ResumeGuest:

    if (VmExitCurrentIrql < DISPATCH_LEVEL)
    {
        KeLowerIrql(VmExitChangeIrql);
    }	

	_asm
	{	
			MOV EAX, GuestEAX
			MOV ECX, GuestECX
			MOV EDX, GuestEDX
			MOV EBX, GuestEBX
			MOV ESP, GuestESP
			MOV EBP, GuestEBP
			MOV ESI, GuestESI
			MOV EDI, GuestEDI
			
			STI	
			_emit	0x0F	      // VMRESUME
			_emit	0x01
			_emit	0xC3
	}	
	
}

VOID ReadGuestState()
{
	HandlerLogging=0;

	ExitInstructionLength = VMREAD(VM_EXIT_INSTRUCTION_LEN);
	ExitReason = VMREAD(VM_EXIT_REASON);
	ExitQualification=VMREAD(EXIT_QUALIFICATION);
	
	GuestEIP = VMREAD(GUEST_RIP);
	GuestESP = VMREAD(GUEST_RSP);
	GuestCR3 = VMREAD(GUEST_CR3);
	GuestDR7 = VMREAD(GUEST_DR7);	
}

VOID PrintGuestState()
{
	Log( "----- VMM  Guest  -----", 0 );
	
	Log("The GuestEAX:",GuestEAX);
	Log("The GuestEBX:",GuestEBX);
	Log("The GuestECX:",GuestECX);
	Log("The GuestEDX:",GuestEDX);
	Log("The GuestESP:",GuestESP);
	Log("The GuestEBP:",GuestEBP);
	Log("The GuestESI:",GuestESI);
	Log("The GuestEDI:",GuestEDI);

	
	Log("The GuestCR3:",GuestCR3);
	Log("The GuestEIP:",GuestEIP);	
	Log("The ExitReason:",ExitReason);
	Log("The ExitQualification:",ExitQualification);
	
}



从前天晚上卡死到今天上午,也没办法了,恰好看到这方面的前辈了,希望前辈能帮忙解答下吧
2015-12-25 13:21
0
雪    币: 475
活跃值: (64)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
22
我就是按照bluepill里的做法做的,好像是给每个核心都留一个堆栈空间,保存寄存器状态,然后像做hook一样搞个模版通过通道回去然后再做操作。
2015-12-25 16:09
0
雪    币: 443
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
windbg调试不了root模式的代码,VT拦截INT 1,再调试VT root的代码的时候,整个VM就会死掉了。
以前看三寸法神(师)的无限硬件中断的时候偿试过用windbg+VMware调试root的代码。
2015-12-25 16:44
0
雪    币: 302
活跃值: (246)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
24
额,这个具体得看你如何处理的Int 1了,毕竟windbg也是依赖于Int 1和 Int 3的
2015-12-25 17:13
0
游客
登录 | 注册 方可回帖
返回
//