• 1520阅读
  • 1回复

VT实例-如何用VT在操作系统不知情的情况下修改内核入口 [复制链接]

上一主题 下一主题
离线啊冲
 

只看楼主 倒序阅读 使用道具 楼主  发表于: 2016-02-02


VT实例-如何用VT在操作系统不知情的情况下修改内核入口

发表于 2015 年 12 月 20 日

sysenter hook这种技术到现在几乎十年了,基本都是用驱动通过wrmsr 0x176来实现的,但是现在很多AntiRookit工具,他们在检测sysenter hook的时候,会通过rdmsr 0x176与操作系统版本相对应的值进行比较,如果不相等,那么很显然,内核入口被修改了,现在做个试验,MSR.SYS
#include "msr.H"
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-全局变量-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
int nHookInc;
int VarVectorBaseAddress;
MSR OldMsr;
int OldMsrAddr;

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=Unload Driver-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void HelloDDK(IN PDRIVER_OBJECT driver)
{
KdPrint(("Enter HelloDDK\n"));
KdPrint(("[HookMsr]: IA32_SYSENTER_EIP: %08x\n",OldMsr.low));
FWriteMsr(&OldMsr,IA32_SYSENTER_EIP);
KdPrint(("Leave HelloDDK\n"));
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-Modified MSR CallBack-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-
_declspec(naked) MsrCallBack()
{
_asm{
pushad
pushfd
cmp eax,0x30
jnz Hook
}
_asm{
popfd
popad
mov eax,0
jmp OldMsr
}
_asm{
Hook:
popfd
popad
jmp OldMsr
}
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-HOOK MSR-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=
void HookMsr()
{
MSR NewMsr;
NewMsr.high=OldMsr.high;
NewMsr.low=(int)MsrCallBack;
KdPrint(("[HookMsr]: IA32_SYSENTER_EIP: %08x\n",OldMsr.low));
KdPrint(("[HookMsr]: IA32_SYSENTER_EIP: %08x\n",NewMsr.low));
FWriteMsr(&NewMsr,IA32_SYSENTER_EIP);
return;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-HOOK CPU-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
int HookCpu()
{
UNICODE_STRING ProcName;
KAFFINITY CpuCount;
PKTHREAD hThread;
int KeSetAffinityThread;
RtlInitUnicodeString(&ProcName,L"KeSetAffinityThread");
KeSetAffinityThread = (int)MmGetSystemRoutineAddress(&ProcName);
KdPrint(("[HookCpu]: KeSetAffinityThread: %08x\n",KeSetAffinityThread));
CpuCount = KeQueryActiveProcessors();
hThread = KeGetCurrentThread();
for(int i=1;i<nCpus;i++)
{
if(CpuCount>=i)
{
_asm{
mov eax, KeSetAffinityThread
mov ecx, i
mov edx, hThread
push ecx
push edx
call eax
}
HookMsr();
}
}
PsTerminateSystemThread(STATUS_SUCCESS);
return;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=DriverEntry-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver,IN PUNICODE_STRING regpath)
{
HANDLE hSystemThread;
int nProcessors;
LARGE_INTEGER time;
time.QuadPart=500;
FReadMsr(&OldMsr,IA32_SYSENTER_EIP);
OldMsrAddr=OldMsr.low;
PsCreateSystemThread(&hSystemThread,0,0,0,NULL,(PKSTART_ROUTINE)HookCpu,0); //创建系统线程
nProcessors=KeNumberProcessors;
while( KeWaitForSingleObject(&hSystemThread,Executive,KernelMode,FALSE,&time)!=STATUS_SUCCESS )
{
//idle loop
}
ZwClose(hSystemThread);
driver->DriverUnload=HelloDDK;
return STATUS_SUCCESS;
}
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-Get the Base Address of Vector-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
int FReadMsr(MSR* MsrAddr,int num)
{
_asm{
mov ecx,num //SYSENTER_EIP
rdmsr
mov ebx,MsrAddr
mov [ebx],eax
mov [ebx+4],edx
}
return 0;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-Comprie the Function Address of Vector-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
int FWriteMsr(PMSR MsrAddr,int num)
{
_asm{
mov ecx,num
mov ebx,MsrAddr
mov edx,[ebx+4]
mov eax,[ebx]
wrmsr
}
return 0;
}
这个驱动就是通过wrmsr来实现修改内核入口的,但是用XueTr,则会瞬间被检测到,如下图所示

也对,既然你的驱动可以读取,那么我的驱动也能读取,毕竟都在R0权限,那么有什么办法阻止呢,这里就要用到VT了,首先在DriverEntry处保存原入口的值,然后修改 GUEST_SYSENTER_EIP为Hook sysenter的地址,最后在VM-EXIT中,处理rdmsr 和 wrmsr的拦截,wrmsr的处理默认不执行任何操作,也就是拒绝操作系统或者操作系统下的任何驱动能写入Hook值到内核入口,rdmsr的处理把原内核入口地址返回给eax,这里就不开放源码了,省得大徒弟ML这货觊觎我的胜利成果,不过为了方便,还会开放驱动文件 下载: test
好了,下面看下试验成果




对了,该VT目前还支持DR拦截和CR拦截,但是都没怎么操作,默认返回了。。。如果要反硬件调试,直接修改下DR7就行了

善者 慈悲心常在 无怨无恨 以苦为乐
默认压缩密码www.hifyl.com
文件分享密码问题:http://www.hifyl.com/read-htm-tid-4444.html
离线v2680267313

只看该作者 沙发  发表于: 2016-04-30
用户被禁言,该主题自动屏蔽!
快速回复
限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
上一个 下一个