通过编写简单的进程hook保护驱动并运行,分析如何解除驱动保护
设计思路分析1、通过编写简单的进程hook保护驱动并运行,用以保护记事本进程
2、分析如何过保护
对象分析
运行自写程序HookProcess.exe选择要保护的进程(记事本),自动加载同目录下的驱动hook.sys并进行驱动保护
主要函数介绍NtOpenProcess
驱动层函数,用于打开进程,原型参考如下
NTSTATUS ZwOpenProcess(
Out PHANDLE ProcessHandle, //句柄指针
In ACCESS_MASK DesiredAccess, //渴望得到的访问权限(标志)
In POBJECT_ATTRIBUTES ObjectAttributes, //属性结构指针
In_opt PCLIENT_ID ClientId //进程标示符结构指针
);
编写测试效果

运行保护程序保护记事本,使用CE(非内核模式)无法打开记事本,OD(无插件)也检测不到记事本进程

用工具检测SSDT发现NtOpenProcess确实被HOOK了

这时选择被HOOK内核函数NtOpenProcess把它恢复就可以了

也可以反汇编当前被HOOK地址,让他跳回正常内核函数NtOpenProcess原地址


恢复后CE能扫描,且OD也能检测到进程了
// 自定义的NtOpenProcess函数MyNtOpenProcessextern "C" NTSTATUS __stdcall MyNtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId ) {
NTSTATUS rc;
HANDLE PID;
KdPrint(("进入了MyNtOpenProcess"));
if(ClientId != NULL) {
PID = ClientId->UniqueProcess;
KdPrint(( "进程PID=%d\n",(int*)PID ));
if(PID == hookPID) { //判断是否为需要保护的进程pid
KdPrint(("%d是被保护进程 hookPID=%d \n",(int)PID, (int)hookPID));
KdPrint(("进程正在保护,NtOpenProcess失败!!!!!\n"));
ProcessHandle = NULL;
rc = STATUS_ACCESS_DENIED; //拒绝访问
EP = PsGetCurrentProcess(); //也可使用PsLookupProcessByProcessId((ULONG)PID,&EP);
KdPrint(("进程名:%s\n",(PTSTR)((ULONG)EP+0x174)));
} else {
KdPrint(("%d不是被保护进程 hookPID=%d \n",(int)PID, (int)hookPID));
rc = (NTSTATUS)RealNtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}
}
return rc;
} // HOOK 函数构建
VOID HookNtOpenProcess() {
ssdthook_flag=true;
LONG PSSDT_Addr, *PNtOpenProcessr_Addr, NtOpenProcessr_Addr;
PSSDT_Addr=(LONG)KeServiceDescriptorTable->ServiceTableBase;
PNtOpenProcessr_Addr=(PLONG)(PSSDT_Addr+0x7A*4);
NtOpenProcessr_Addr=*PNtOpenProcessr_Addr;
RealNtOpenAddress = *PNtOpenProcessr_Addr;
RealNtOpenProcess = (NTOPENPROCESS *)RealNtOpenAddress;
KdPrint(("真实的NtOpenProcess地址: %x\n",(int)RealNtOpenAddress));
KdPrint(("伪造NTOpenProcess地址: %x\n", (int)MyNtOpenProcess));
__asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
// 修改SSDT
*PNtOpenProcessr_Addr= (ULONG)MyNtOpenProcess;
KdPrint(("UnHook修改NTOpenProcess OK \n"));
__asm
{
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
return;
}
//UnHook函数构建
VOID UnHookNtOpenProcess() {
ULONG PNtOpenProcessr_Addr;
PNtOpenProcessr_Addr = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;
if (ssdthook_flag) {
ssdthook_flag=false;
__asm
{
cli
mov eax, cr0
and eax, not 10000h
mov cr0, eax
}
// 还原SSDT
*((ULONG*)PNtOpenProcessr_Addr) = (ULONG)RealNtOpenAddress;
KdPrint(("UnHook还原NTOpenProcess OK \n"));
__asm
{
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
}
return;
} 总体评价
本驱动保护比较简单,很容易就会被OD插件解除,仅用于学习原理,在windowsXP下测试成功,EXE由MFC编写可能部分有不完美之处,控制台可参考
本文链接地址: https://www.dbgpro.com/archives/4830.html
――版权声明――







