tianhongzhang
驱动牛犊
驱动牛犊
  • 注册日期2009-09-02
  • 最后登录2016-09-03
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望61点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:3701回复:6

求助大家一下,如何实现进程的保护?

楼主#
更多 发布于:2010-01-20 10:30
下面是一个进程保护的代码,代码如下:

但是问题是:为什么这段代码只能够保护一个进程,而不能够保护多个进程?
代码是根据进程的ID号来进行进程保护的。
如何才能够实现对多个进程的保护呢?
请大家指点指点

#include "ntddk.h"

#define NT_DEVICE_NAME      L"\\Device\\ProtectProcess"
#define DOS_DEVICE_NAME    L"\\DosDevices\\ProtectProcess"

#define IOCTL_PROTECT_CONTROL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)

NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT  DeviceObject,IN PIRP  Irp);
VOID OnUnload(IN PDRIVER_OBJECT DriverObject);


//定义SSDT表的结构
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()

__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

#define SYSTEMSERVICE(_function)  KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]

NTSYSAPI NTSTATUS NTAPI ZwOpenProcess(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);
typedef NTSTATUS (*ZWOPENPROCESS)(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);


ZWOPENPROCESS OldZwOpenProcess;

long pid = -1; //定义进程ID号

/////////////////////////////////////////////////////////////////

NTSTATUS NewZwOpenProcess(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL)
{
//用来替换的新函数
NTSTATUS nStatus = STATUS_SUCCESS;
if((long)ClientId->UniqueProcess == pid)
{
DbgPrint("保护进程 PID:%ld\n",pid);
return STATUS_ACCESS_DENIED;
}

nStatus = OldZwOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
return STATUS_SUCCESS;
}

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
//卸载时会调用
UNICODE_STRING DeviceLinkString;
PDEVICE_OBJECT DeviceObjectTemp1=NULL;
PDEVICE_OBJECT DeviceObjectTemp2=NULL;

DbgPrint("驱动程序卸载...\n");

RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&DeviceLinkString);
if(DriverObject)
{
DeviceObjectTemp1=DriverObject->DeviceObject;
while(DeviceObjectTemp1)
{
DeviceObjectTemp2=DeviceObjectTemp1;
DeviceObjectTemp1=DeviceObjectTemp1->NextDevice;
IoDeleteDevice(DeviceObjectTemp2);
}
}  
DbgPrint("设备已经卸载\n");

DbgPrint("修复SSDT表\n");
(ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess)) = OldZwOpenProcess;

DbgPrint("驱动卸载完毕.\n");
}

NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT  DeviceObject,IN PIRP  Irp)
{
NTSTATUS nStatus = STATUS_SUCCESS;
ULONG IoControlCode = 0;
PIO_STACK_LOCATION IrpStack = NULL;

long* inBuf = NULL;
char* outBuf = NULL;
ULONG inSize = 0;
ULONG outSize = 0;
PCHAR buffer = NULL;
PMDL mdl = NULL;

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;

IrpStack = IoGetCurrentIrpStackLocation(Irp);

switch(IrpStack->MajorFunction)
{
case IRP_MJ_CREATE:
DbgPrint("IRP_MJ_CREATE 被调用\n");
break;
case IRP_MJ_CLOSE:
DbgPrint("IRP_MJ_CLOSE 被调用\n");
break;
case IRP_MJ_DEVICE_CONTROL:
DbgPrint("IRP_MJ_DEVICE_CONTROL 被调用\n");
IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
switch(IoControlCode)
{
case IOCTL_PROTECT_CONTROL:
inSize = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
outSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
inBuf = (long*)Irp->AssociatedIrp.SystemBuffer; //获取进程的id号

/*获取从应用层传递下来的进程的ID号,保存到全局变量pid中
  这个ID号所对应的进程就是我们要保护的进程
*/
pid = *inBuf;

DbgPrint("===========================\n");
DbgPrint("IOCTL_PROTECT_CONTROL 被调用,通讯成功!\n");
DbgPrint("输入缓冲区大小: %d\n",inSize);
DbgPrint("输出缓冲区大小: %d\n",outSize);
DbgPrint("输入缓冲区内容: %ld\n",*inBuf);
DbgPrint("当前保护进程ID: %ld\n",pid);
DbgPrint("===========================\n");

strcpy(Irp->UserBuffer,"OK!\n");
break;
default:
break;
}
break;
default:
DbgPrint("未知请求包被调用\n");
break;
}

nStatus = Irp->IoStatus.Status;

IoCompleteRequest(Irp,IO_NO_INCREMENT);

return nStatus;
}

/*---------------------------------------
驱动程序入口函数,处理各个IRP事件
-----------------------------------------*/
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING theRegistryPath)
{
NTSTATUS        ntStatus = STATUS_SUCCESS;
UNICODE_STRING  ntDeviceName;
UNICODE_STRING  DeviceLinkString;
PDEVICE_OBJECT  deviceObject = NULL;

ULONG CR0VALUE;

DbgPrint("驱动程序加载...\n");

RtlInitUnicodeString( &ntDeviceName, NT_DEVICE_NAME );

//建立设备对象 deviceObject
ntStatus = IoCreateDevice(
DriverObject,
0,
&ntDeviceName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&deviceObject );

if ( !NT_SUCCESS( ntStatus ) )
{
DbgPrint("无法创建驱动设备");
return ntStatus;
}

RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME);
ntStatus=IoCreateSymbolicLink(&DeviceLinkString,&ntDeviceName);

if(!NT_SUCCESS(ntStatus))
{
return ntStatus;
}

  //填充各个分发函数的入口地址
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
DriverObject->DriverUnload = OnUnload;

DbgPrint("驱动程序已经启动\n");

DbgPrint("修改SSDT表...\n");


/************************************************************************
接下来,设置CR0寄存器, 即:禁用内存写保护
这是因为: 在Windows XP或以上的系统中,如果不处理内存写保护,那么会发生蓝屏.
所以, 在这里重置CR0寄存器, 以防止PAGE_FAULT
*************************************************************************/
__asm{
mov eax, cr0
mov CR0VALUE, eax
and eax, 0fffeffffh  
mov cr0, eax
}

/********************************************************************************
把ZwOpenProcess函数的地址(也就是函数NtOpenProcess的地址)保存到OldZwOpenProces里面,
然后用新函数的地址替换掉SSDT表中的ZwOpenProcess函数(即函数NtOpenProcess)
*********************************************************************************/
OldZwOpenProcess =(ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess));
(ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess)) = NewZwOpenProcess;


DbgPrint("驱动程序加载完毕.\n");


/***********************************************************
当驱动程序加载完毕以后,设置CR0寄存器, 即:启用内存写保护
************************************************************/
__asm
{
mov eax, CR0VALUE
mov cr0, eax
}


return STATUS_SUCCESS;
}
alwaysrun
驱动小牛
驱动小牛
  • 注册日期2006-06-01
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1059分
  • 威望752点
  • 贡献值1点
  • 好评度98点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2010-02-26 09:39
if((long)ClientId->UniqueProcess == pid)
{
DbgPrint("保护进程 PID:%ld\n",pid);
return STATUS_ACCESS_DENIED;
}

这儿只处理了一个啊
一颗平常的心!
zyustc
驱动牛犊
驱动牛犊
  • 注册日期2009-04-29
  • 最后登录2010-05-17
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望11点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2010-04-23 10:39
晕,一个都会,一组你就不会了?驱动中保存一个数组[受保护进程ID]
wanghui219
禁止发言
禁止发言
  • 注册日期2007-08-28
  • 最后登录2019-07-29
  • 粉丝4
  • 关注3
  • 积分101166分
  • 威望505351点
  • 贡献值0点
  • 好评度137点
  • 原创分0分
  • 专家分4分
  • 社区居民
地板#
发布于:2010-05-04 10:49
用户被禁言,该主题自动屏蔽!
yanggao178
驱动牛犊
驱动牛犊
  • 注册日期2010-05-27
  • 最后登录2011-03-20
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望51点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2010-05-27 15:59
上楼的很对啊
dragonltx
驱动牛犊
驱动牛犊
  • 注册日期2010-02-25
  • 最后登录2010-08-04
  • 粉丝0
  • 关注0
  • 积分38分
  • 威望281点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2010-05-27 16:25
飘过!!!!!!
gezz114
驱动牛犊
驱动牛犊
  • 注册日期2010-11-19
  • 最后登录2010-11-24
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望31点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2010-11-24 01:52
PID 万恶的PID啊
游客

返回顶部