vc++实现内核级进程保护

保护核心代码
本文介绍了一个内核级驱动程序的设计与实现,该驱动程序通过修改系统服务描述表(SSDT)来拦截特定的系统调用,例如ZwOpenProcess,并阻止对指定进程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);

#pragma pack(1)//SSDT表的结构
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
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;

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)
{
//IRP_MJ_DEVICE_CONTROL的响应函数
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;

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;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING theRegistryPath)
{
//驱动入口函数
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING ntDeviceName;
UNICODE_STRING DeviceLinkString;
PDEVICE_OBJECT deviceObject = NULL;

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

RtlInitUnicodeString( &ntDeviceName, NT_DEVICE_NAME );

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");

//修改 ZwOpenProcess 函数地址
OldZwOpenProcess =(ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess));
(ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess)) = NewZwOpenProcess;

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

return STATUS_SUCCESS;
}

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <process.h>

#define BUF_SIZE 4096

int main(int argc,char* argv[])
{
char path[BUF_SIZE];
char base[BUF_SIZE];
char sername[BUF_SIZE];
char disname[BUF_SIZE];
memset(path,0,BUF_SIZE);
memset(base,0,BUF_SIZE);
memset(sername,0,BUF_SIZE);
memset(disname,0,BUF_SIZE);

SC_HANDLE rh = NULL;
SC_HANDLE sh = NULL;
if (argc == 1)
{
printf("use: install/start/uninstall\n");
exit(0);
}

::GetModuleFileName(0,base,BUF_SIZE);
int p = strlen(base);
while(base[p] != '\\'){p--;}
strncpy(path,base,p+1);
memset(base,0,BUF_SIZE);
sprintf(base,"%sInstall.ini",path);
memset(path,0,BUF_SIZE);
::GetPrivateProfileString("Config","Path","",path,BUF_SIZE,base);
::GetPrivateProfileString("Config","ServiceName","",sername,BUF_SIZE,base);
::GetPrivateProfileString("Config","DisplayName","",disname,BUF_SIZE,base);

printf("[*]Service Name:%s\n",sername);
printf("[*]Display Name:%s\n",disname);
printf("[*]Driver Path:%s\n",path);


sh = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

if (!sh){
printf("[-]Error OpenSCManger.\n");
exit(0);
}


if (argc == 2 && !strcmp(argv[1],"install"))
{
if (!strcmp(path,""))
{
printf("[-]error read Install.ini\n");
exit(0);
}

rh = CreateService(sh,sername,disname,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
//{
//SERVICE_SYSTEM_START,
SERVICE_DEMAND_START,
//}
SERVICE_ERROR_NORMAL,
path,
NULL,NULL,NULL,NULL,NULL);

if (!rh){
printf("[-]error CreateService.\n");
exit(0);
}

printf("[-]Install Service Complete...\n");
}else if (argc == 2 && !strcmp(argv[1],"start"))
{

rh = OpenService(sh,sername,SERVICE_ALL_ACCESS);

if (!rh){
printf("error OpenService.\n");
exit(0);
}

StartService(rh,NULL,NULL);

printf("[-]Start Service Complete...\n");

}else if (argc == 2 && !strcmp(argv[1],"uninstall"))
{
rh = OpenService(sh,sername,SERVICE_ALL_ACCESS);

if (!rh){
printf("error OpenService.\n");
exit(0);
}

SERVICE_STATUS ss;
ControlService(rh,SERVICE_CONTROL_STOP,&ss);

printf("[-]Stop Service Complete...\n");

DeleteService(rh);

printf("[-]Delete Service Complete...\n");
}

CloseServiceHandle(rh);
CloseServiceHandle(sh);

return 1;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值