vc++實現內核級進程保護

保護核心代碼

#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
#include
#include
#include

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

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/yincheng01/archive/2009/08/17/4455267.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章