-
-
[分享]小菜学进程保护
-
发表于:
2010-1-23 21:33
10433
-
作者:IaaIe
链接:
http://bbs.kanxue.com/showthread.php?t=105811
个人主页:
http://hi.baidu.com/iaaie
小菜学习了一段时间的SSDT HOOK,大概对SSDT HOOK有些了解了,先把自己的学习过程发布出来,供和我一样的初学者学习、交流!!我做的是保护记事本进程防止关闭,只些都是各位大大玩剩下的,但对小菜来说还是挺有意思的。程序有一点问题,通过任务管理器不能结束进程,但是单击记事本的关闭按钮以后,windbg会暂停下来,用windbg跟踪的结果是,第一次传入的句柄是空,第二次传入的句柄有值,怎么会这样??希望各位大大能指点一下。。。
SSDT HOOK我是通过各位大大的帖子进行学习的,堕落天才的SSDT Hook的妙用-对抗ring0 inline hook 、云舒的简单说说SSDT、李马的城里城外看SSDT等帖子,也是在此时学会了windbg的更多常用命令。
PS:此代码只用来简单理解SSDT,不具备通用性,里面省去了rootkit一书中提到的各种宏。。。
#include <ntddk.h>
typedef struct _SystemServiceDescriptorTable
{
PVOID ServiceTableBase; //SSDT表的基地址
PULONG ServiceCounterTableBase; //指向另一个索引表,该表包含了每个服务表项被调用的次数
ULONG NumberOfService; //当前系统所支持的服务个数
ULONG ParamTableBase; //包含了每个服务所需的参数字节数
}SystemServiceDescriptorTable,*PSystemServiceDescriptorTable;
extern PSystemServiceDescriptorTable KeServiceDescriptorTable; //导出函数,DDK的头文件中并未声明
typedef NTSTATUS (*NTTERNIMATEPROCESS)( IN HANDLE ProcessHandle,
IN NTSTATUS ExitStatus ); //定义一个函数指针
NTTERNIMATEPROCESS pRealNtTerminateAddr;
ULONG RealServiceAddress; //接受被hook的函数地址
CHAR *TerminateName = "notepad.exe"; //这里就是我们的记事本进程名
UCHAR* PsGetProcessImageFileName( IN PEPROCESS Process );
BOOLEAN IsProtect(CHAR *temp) //判断正在结束的进程是否是我们要保护的记事本进程
{
ULONG len = strcmp(TerminateName, temp);
if(!len)
return TRUE;
return FALSE;
}
NTSTATUS MyNtTerminateProcess(IN HANDLE ProcessHandle, IN NTSTATUS ExitStatus)//我们自己的NtTerminateProcess
{
PEPROCESS process; //接受通过ProcessHandle返回的进程
NTSTATUS status;
CHAR *pName; //接受进程的进程名
status = ObReferenceObjectByHandle(ProcessHandle,
FILE_READ_DATA,
0,
KernelMode,
&process,
NULL); //获取进程
if(!NT_SUCCESS(status))
return (NTSTATUS)(NTTERNIMATEPROCESS)pRealNtTerminateAddr(ProcessHandle, ExitStatus);
pName = (CHAR*)PsGetProcessImageFileName(process); //获取进程名
if(IsProtect(pName)) //判断是否是我们要保护的进程,是则返回权限不足,否则调用原函数结束进程
return STATUS_ACCESS_DENIED;
return (NTSTATUS)(NTTERNIMATEPROCESS)pRealNtTerminateAddr(ProcessHandle, ExitStatus);
}
NTSTATUS Hook()
{
ULONG Address;
Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x101 * 4;//0x101可以用windbg获得,或者查询debugman论坛里面SSDT表
RealServiceAddress = *(ULONG*)Address;
pRealNtTerminateAddr = (NTTERNIMATEPROCESS)RealServiceAddress;
//开启SSDT 表为可写
_asm
{
cli;
mov eax, cr0;
and eax, not 10000h;
mov cr0, eax;
}
*((ULONG*)Address) = (ULONG)MyNtTerminateProcess; //替换为我们自己的NtTerminateProcess函数
//设置SSDT表位只读
_asm
{
mov eax, cr0;
or eax, 10000h;
mov cr0, eax;
sti;
}
}
VOID UnHook()//把SSDT中的NtTerminateprocess函数还原
{
ULONG Address;
Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x101 * 4;
__asm
{
cli
mov eax, cr0;
and eax, not 10000h ;
mov cr0, eax ;
}
*((ULONG*)Address) = (ULONG)RealServiceAddress;
__asm
{
mov eax, cr0 ;
or eax, 10000h ;
mov cr0, eax ;
sti ;
}
}
VOID Unload(PDRIVER_OBJECT driver)
{
UNREFERENCED_PARAMETER(driver);
UnHook();
DbgPrint(("EXIT..."));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING str)
{
NTSTATUS status;
UNREFERENCED_PARAMETER(str);
driver->DriverUnload = Unload;
status = Hook();
return STATUS_SUCCESS;
}
希望各位路过的大大能指点一下出现的问题。。。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课