首页
论坛
课程
招聘
[原创](开源)一个简单的ssdthook进程名 保护进程 兼容2000以后所有x86系统
2010-12-6 13:46 32290

[原创](开源)一个简单的ssdthook进程名 保护进程 兼容2000以后所有x86系统

2010-12-6 13:46
32290
大牛已经把这些 玩的烂熟了
小小小菜鸟 把一个 修改了 无数次的代码发出来
希望 大家多多 提出意见 代码是非常的挫(本代码 修改自一个 网络博客的代码只是修改函数和部分通讯 把r3 r0 通讯 修改为 进程名 保护不需要通讯 直接加载驱动就可以了
虽说不是原原创 但是也是花了很多心血 )

/*
	Project Name:	Processes Guard
	Description:	Protection user	specified process(es)
	Date:			2010-5-5
	Version:		1.0
	Author:	Kernone     Alter:     君君寒
	Blog:			http://hi.baidu.com/kernone
	File Name:		ProcGuard.c
	Copyright(c)	Kernone Soft 2010
*/
#include <Ntifs.h>


#pragma pack(1)
typedef struct _SYSTEM_SERVICES_DESCRIPTOR_TABLE
{
	PULONG			*ServiceTableBase;
	PULONG			*ServiceCounterTableBase;	//Used in check builds only
	unsigned int	NumberOfServices;
	PULONG			*ParamTableBase;
}SSDT, *PSSDT;
#pragma pack()

typedef struct _DEVICE_EXTENSION
{
	PDEVICE_OBJECT	pDevObj;
	UNICODE_STRING	uniSymLink;
	PMDL			pMdl;
	PULONG			pulSSDTMapped;
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;

typedef NTSTATUS (__stdcall *ZWOPENPROCESS)(
                       OUT PHANDLE ProcessHandle,
                       IN ACCESS_MASK DesiredAccess,
                       IN POBJECT_ATTRIBUTES ObjectAttributes,
                       IN PCLIENT_ID PCLIENT_ID OPTIONAL
);

typedef NTSTATUS  (__stdcall *ZWOPENTHREAD) (
                          OUT PHANDLE ProcessHandle,
                          IN ACCESS_MASK DesiredAccess,
                          IN POBJECT_ATTRIBUTES ObjectAttributes,
                          IN PCLIENT_ID PCLIENT_ID OPTIONAL

); 



NTSYSAPI
NTSTATUS
NTAPI 
ZwOpenProcess( OUT PHANDLE ProcessHandle,
         IN ACCESS_MASK AccessMask,                                           
         IN POBJECT_ATTRIBUTES ObjectAttributes,
               IN PCLIENT_ID ClientId);

NTSYSAPI
NTSTATUS
NTAPI 
ZwOpenThread( OUT PHANDLE ProcessHandle,
              IN ACCESS_MASK AccessMask,                                           
              IN POBJECT_ATTRIBUTES ObjectAttributes,
              IN PCLIENT_ID ClientId);



    
	
/*Getting system service function address, the index of function locates 1 bytes offset*/
#define	SYSTEM_SERVICE(_Func)	KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_Func + 1)]
#define	SYSTEM_INDEX(_Func)		(*(PULONG)((PUCHAR)_Func + 1))
//#define	SYSTEM_SERVICEONE(_Func)	KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_Func + 1)]
//#define	SYSTEM_INDEXONE(_Func)		(*(PULONG)((PUCHAR)_Func + 1))

#define	IOCTL_START_PROTECTION	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define	C_MAXPROCNUMS			12

//Global variable
//__declspec(dllimport) SSDT	KeServiceDescriptorTable;
__declspec(dllimport) SSDT	KeServiceDescriptorTable;
ZWOPENPROCESS	      ZwOpenProcessReal;
ZWOPENTHREAD          ZwOpenThreadReal;

ULONG	ulPIDs[C_MAXPROCNUMS];

DRIVER_UNLOAD	DriverUnload;
DRIVER_DISPATCH	DispatchDevOpen, DispatchDevCtl;
NTSTATUS ZwOpenProcessHook(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);
NTSTATUS ZwOpenThreadHook(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);


NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryPath)
{
	PDEVICE_OBJECT		pDevObj;
	PDEVICE_EXTENSION	pDevExt;
	UNICODE_STRING		uniSymLink, uniDevName;
	NTSTATUS			ntStatus;
	PMDL				pMdl;
	PULONG				pulSSDTMapped;
	
	RtlInitUnicodeString(&uniSymLink, L"\\DosDevices\\ProcessesGuard");
	RtlInitUnicodeString(&uniDevName, L"\\Device\\ProcessesGuard");
	pDriverObj->DriverUnload = DriverUnload;
	pDriverObj->MajorFunction[IRP_MJ_CREATE] = 
	pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchDevOpen;
	pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDevCtl;
	
	ntStatus = IoCreateDevice(pDriverObj, sizeof (DEVICE_EXTENSION), &uniDevName, FILE_DEVICE_UNKNOWN, 
		0, FALSE, &pDevObj);
	if (!NT_SUCCESS(ntStatus))
		return(ntStatus);
		
	IoCreateSymbolicLink(&uniSymLink, &uniDevName);
	pDevObj->Flags |= DO_BUFFERED_IO;
	pDevExt = pDevObj->DeviceExtension;
	pDevExt->pDevObj = pDevObj;
	pDevExt->uniSymLink = uniSymLink;
	
	pMdl = IoAllocateMdl(KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices * 4,
		FALSE, FALSE, NULL);
	if (pMdl == NULL)
	{
		IoDeleteSymbolicLink(&uniSymLink);
		IoDeleteDevice(pDevObj);
		return(STATUS_INSUFFICIENT_RESOURCES);
	}
	
	MmBuildMdlForNonPagedPool(pMdl);
	pMdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;	//Write SSDT
	
	pulSSDTMapped = (PULONG)MmMapLockedPagesSpecifyCache(pMdl, KernelMode, MmNonCached, NULL, FALSE, NormalPagePriority);
	if (pulSSDTMapped == NULL)
	{
		IoDeleteSymbolicLink(&uniSymLink);
		IoDeleteDevice(pDevObj);
		IoFreeMdl(pMdl);
		return(STATUS_UNSUCCESSFUL);
	}
	
	pDevExt->pMdl = pMdl;
	pDevExt->pulSSDTMapped = pulSSDTMapped;
	
	ZwOpenProcessReal = (ZWOPENPROCESS)SYSTEM_SERVICE(ZwOpenProcess);
	pulSSDTMapped[SYSTEM_INDEX(ZwOpenProcess)] = (PULONG)ZwOpenProcessHook;

	ZwOpenThreadReal = (ZWOPENTHREAD)SYSTEM_SERVICE(ZwOpenThread);
	pulSSDTMapped[SYSTEM_INDEX(ZwOpenThread)] = (PULONG)ZwOpenThreadHook;

	
	return(ntStatus);
}

VOID DriverUnload(PDRIVER_OBJECT pDriverObj)
{
	PDEVICE_OBJECT		pDevObj = pDriverObj->DeviceObject;
	PDEVICE_EXTENSION	pDevExt = pDevObj->DeviceExtension;
	PULONG				pulSSDTMapped = pDevExt->pulSSDTMapped;
	PMDL				pMdl = pDevExt->pMdl;
	
	pulSSDTMapped[SYSTEM_INDEX(ZwOpenProcess)] = (PULONG)ZwOpenProcessReal;
	pulSSDTMapped[SYSTEM_INDEX(ZwOpenThread)] = (PULONG)ZwOpenThreadReal;//先这个顺序
	MmUnmapLockedPages(pulSSDTMapped, pMdl);
	IoFreeMdl(pMdl);
	while (pDevObj)
	{
		pDevExt = pDevObj->DeviceExtension;
		pDevObj = pDevObj->NextDevice;
		
		IoDeleteSymbolicLink(&pDevExt->uniSymLink);
		IoDeleteDevice(pDevExt->pDevObj);
	}
}

NTSTATUS DispatchDevOpen(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	NTSTATUS	ntStatus = STATUS_SUCCESS;
	
	pIrp->IoStatus.Status = ntStatus;
	pIrp->IoStatus.Information = 0;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return(ntStatus);
}

NTSTATUS DispatchDevCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	PIO_STACK_LOCATION	pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
	ULONG				ulIoCode, ulBufLength, ulRtn, ulCounts = 0, ulIndex;
	PVOID				pvBuf;
	NTSTATUS			ntStatus;
	
	ulIoCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
	switch (ulIoCode)
	{
	case IOCTL_START_PROTECTION:
		ulBufLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
		pvBuf = pIrp->AssociatedIrp.SystemBuffer;
		ulCounts = ulBufLength / sizeof (ULONG);
		KdPrint(("Protection Numbers: %d\n"), ulCounts);
		for (ulIndex = 0; ulIndex < ulCounts && ulIndex < C_MAXPROCNUMS; ulIndex++)
		{
			ulPIDs[ulIndex] = ((PULONG)pvBuf)[ulIndex];
			KdPrint(("Index %d -- PID %d\n"), ulIndex, ulPIDs[ulIndex]);
		}
		ntStatus = STATUS_SUCCESS;
		ulRtn = ulBufLength;
		break;
	default:
		ntStatus = STATUS_INVALID_PARAMETER;
		ulRtn = 0;
		break;
	}
	
	pIrp->IoStatus.Status = ntStatus;
	pIrp->IoStatus.Information = ulRtn;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return(ntStatus);
}


CHAR *TerminateName = "demo.exe";      //这里就是我们的进程名   
UCHAR *PsGetProcessImageFileName( IN PEPROCESS Process );   
  
BOOLEAN IsProtect(CHAR *temp)            //判断正在结束的进程是否是我们要保护的进程   
{   
    ULONG len = strcmp(TerminateName, temp);   
    if(!len)   
        return TRUE;   
    return FALSE;   
} 
NTSTATUS ZwOpenProcessHook(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)//我们自己的//NtZwOpenProcess   
{   
  PEPROCESS process;  //接受通过ProcessHandle返回的进程   
  NTSTATUS status;    
   CHAR *pName;        //接受进程的进程名 
   HANDLE	hID;
   ULONG dwProcessId = NULL;
	PEPROCESS EProcessToOpen;
       

	     status = PsLookupProcessByProcessId(
          ClientId->UniqueProcess,
          &process
           );
       
  if(!NT_SUCCESS(status))    
     return(ZwOpenProcessReal(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId)); 
	

     pName = (CHAR*)PsGetProcessImageFileName(process); //获取进程名  
    

   if(IsProtect(pName)) //判断是否是我们要保护的进程,是则返回权限不足,否则调用原函数结束进程   
    {   
        if(process != PsGetCurrentProcess())   
        {   
            
			hID = PsGetProcessId(process);//获得进程id
			KdPrint(("Protection Pid: %d\n"), hID);
		return STATUS_ACCESS_DENIED;   
        }   
   }  
	
       
   return(ZwOpenProcessReal(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId));    
} 


NTSTATUS ZwOpenThreadHook(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)//我们自己的NtZwOpenProcess   
{   
    PEPROCESS process;  //接受通过ProcessHandle返回的进程   
    NTSTATUS status;    
    CHAR *pName;        //接受进程的进程名 
    HANDLE	hID;
    ULONG dwProcessId = NULL;
	//PEPROCESS EProcessToOpen;
       

	     status = PsLookupProcessByProcessId(
            ClientId->UniqueProcess,
            &process
            );
       
    if(!NT_SUCCESS(status))    
        return(ZwOpenThreadReal(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId)); 
	

     pName = (CHAR*)PsGetProcessImageFileName(process); //获取进程名  
    

    if(IsProtect(pName)) //判断是否是我们要保护的进程,是则返回权限不足,否则调用原函数结束进程   
    {   
        if(process != PsGetCurrentProcess())   
        {   
            
			hID = PsGetProcessId(process);//获得进程id
			KdPrint(("Protection Pid: %d\n"), hID);
			return STATUS_ACCESS_DENIED;   
        }   
    }  
	
       
   return(ZwOpenThreadReal(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId));    
} 

 


代码是完全可以编译的  (wdk  7600)
具体的就是 ssdt hook
希望大家保留 原原创的版权
既然他给大家做了 贡献 就要尊重别人的成果
还有希望下了代码的都留点 痕迹 呵呵

win7 系统下稳定运行截图

解压密码kanxue                   发错代码跟附件 居然没人说我 羞死了。


看雪招聘平台创建简历并且简历完整度达到90%及以上可获得500看雪币~

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (40)
雪    币: 2566
活跃值: 活跃值 (644)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
zhouws 活跃值 2 2010-12-6 14:44
2
0
好像记得有人说过lookup后还要deref的
雪    币: 72
活跃值: 活跃值 (554)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
君君寒 活跃值 2010-12-6 17:07
3
0
希望多提一些意见
现在稳定性 什么的还是一个比较重要的事情---------测试了干净系统的 xp 2003 vista win7 都稳定 2008没测试过 x86的不是64位系统
如果有测试蓝屏的 大家一定要说下
还有在2003系统下一定要记得 数据执行保护 允许 否则可能会蓝

伤心了 第一次 发的代码 发错了 无法编译居然没人提醒。。o...
雪    币: 138
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pinkchild 活跃值 2010-12-7 09:03
4
0
支持楼主发源码。

是要Obderefer的~

PsLookupProcessByProcessID  increases the reference count on the object returned in the Process parameter.
雪    币: 230
活跃值: 活跃值 (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
winnip 活跃值 1 2010-12-7 23:23
5
0
驱动下保护进程?

看代码是不是hook  openprocess啊?
雪    币: 72
活跃值: 活跃值 (554)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
君君寒 活跃值 2010-12-8 11:00
6
0
对 还有一个函数 都是导出的 菜鸟捣鼓的程序
雪    币: 2992
活跃值: 活跃值 (2369)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
caolinkai 活跃值 2010-12-8 14:37
7
0
顶顶顶
雪    币: 18
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cyberad 活跃值 2010-12-8 15:05
8
0
路过,看一下
雪    币: 217
活跃值: 活跃值 (62)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liein 活跃值 2010-12-9 08:44
9
0
支持有原码的,拿来学习了 ,THX FOR SHOW
雪    币: 64
活跃值: 活跃值 (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
xiaobaozi 活跃值 1 2010-12-9 22:01
10
0
防止ring3足够啦,呵呵
雪    币: 69
活跃值: 活跃值 (190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dnybz 活跃值 2010-12-10 20:50
11
0
保护PID 比进程名更好吧。
雪    币: 72
活跃值: 活跃值 (554)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
君君寒 活跃值 2010-12-11 09:28
12
0
pid是不固定的,进程名是固定的
而且pid可以随机分配 进程名可以分配么?
最主要的是 保护pid要ring3下通讯
保护进程名 不需要
你说哪个更好?
一般游戏都是固定的进程名,你见过固定pid的游戏么?
你修改下原代码  可以做ssdt inline hook ssdt hook  ssdtshadow  hook  如果你水平够高 还可以弄一个 类似白名单的东西
过滤一些你要保护 和不要保护的名单 纯r0 不需要 想通讯的问题。这个只是一个 保护的例子。。用途不同 应该没有好坏的差别的。。
雪    币: 69
活跃值: 活跃值 (190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dnybz 活跃值 2010-12-11 21:08
13
0
如果叫你保护 指定一个 svchost.exe  进程请问你怎么做?
你是不是把所有的svchost.exe 进程都保护?

建意你还是多看看别人写的代码

要淡定,不要鸡动
雪    币: 72
活跃值: 活跃值 (554)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
君君寒 活跃值 2010-12-11 22:56
14
0
你误解我的初衷了
我是想保护某个非系统进程
不是想保护系统进程
而且 系统进程保护也不需要这样吧。。。
雪    币: 69
活跃值: 活跃值 (190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dnybz 活跃值 2010-12-15 10:07
15
0
你也要了解的我的意思,我只是说下而以,一个建意。没有别的意思。
雪    币: 1115
活跃值: 活跃值 (17)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
pencil 活跃值 5 2010-12-15 12:43
16
0
PsLookupProcessByProcessId()

KeStackAttachProcess()

ZwTerminateProcess(NULL,NULL)
雪    币: 212
活跃值: 活跃值 (61)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hovey 活跃值 2010-12-15 14:03
17
0
不错,对于我这菜鸟来说
雪    币: 168
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qqijiq 活跃值 2010-12-16 14:54
18
0
你这个好多无用的函数 比如DispatchDevCtl等 为什么不删除?
雪    币: 168
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qqijiq 活跃值 2010-12-16 14:56
19
0
这样就能关闭进程了
雪    币: 116
活跃值: 活跃值 (113)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ncsi 活跃值 2010-12-16 15:12
20
0
谢谢你拉,我才刚学这个,谢谢你
雪    币: 72
活跃值: 活跃值 (554)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
君君寒 活跃值 2010-12-27 13:36
21
0
方便 ring3通讯扩展 而且没太多影响啊。。。开原代码了 你随便修改那
雪    币: 122
活跃值: 活跃值 (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
butian 活跃值 2011-1-5 17:29
22
0
good!!
雪    币: 1133
活跃值: 活跃值 (556)
能力值: ( LV8,RANK:150 )
在线值:
发帖
回帖
粉丝
freakish 活跃值 1 2011-1-5 18:48
23
0
以后这个驱动被广泛应用的话,我只要把我的文件名改成和你的一样的就好了,不用费劲保护了,好.....哈哈
雪    币: 2080
活跃值: 活跃值 (274)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
exile 活跃值 1 2011-1-9 22:04
24
0
能防DuplicateHandle不??R3就挂了
雪    币: 239
活跃值: 活跃值 (42)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
binarystar 活跃值 3 2011-1-10 19:14
25
0
来顶一下姐姐的文章。纯顶帖。不懂。来学习。。。
游客
登录 | 注册 方可回帖
返回