VC加载驱动

本文介绍了如何使用VC++在Windows系统中加载和卸载NT驱动程序。提供了详细的代码示例,包括使用OpenSCManager创建驱动服务的方法及注意事项,并对比了使用ZwLoadDriver隐藏加载驱动的方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

VC 加载驱动
#include <windows.h> 
#include <winsvc.h> 
#include <conio.h> 
#include <stdio.h>

#define DRIVER_NAME "123467"
#define DRIVER_PATH "..\\HelloDDK.sys"

//装载NT驱动程序
BOOL LoadNTDriver(char* lpszDriverName,char* lpszDriverPath)
{

/************************ 加载NT驱动的代码*******************************
   ① 调用OpenSCManager,打开SCM管理器.如果返回NULL,则返回失败,否则继续
   ② 调用CreateService,创建服务,创建成功则转步骤 ⑥
      ③ 用GetLastError的得到错误返回值
   ④ 返回值为ERROR_IO_PENDING,说明服务已经创建过,用OpenService打开此服务.
   ⑤ 返回值为其他值, 创建武服务失败,返回失败.
   ⑥ 调用StartService开启服务
   ⑦ 成功返回
************************************************************************/

char szDriverImagePath[256];
//得到完整的驱动路径
GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);

BOOL bRet = FALSE;

SC_HANDLE hServiceMgr=NULL;// SCM管理器的句柄
SC_HANDLE hServiceDDK=NULL;// NT驱动程序的服务句柄


//打开服务控制管理器
hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

if( hServiceMgr == NULL ) 
{
   // OpenSCManager失败
   printf( "OpenSCManager() Faild %d ! \n", GetLastError() );
   bRet = FALSE;
   goto BeforeLeave;
}
else
{
   // OpenSCManager成功
   printf( "OpenSCManager() ok ! \n" ); 
}


//创建驱动所对应的服务
hServiceDDK = CreateService( hServiceMgr,
   lpszDriverName,         // 驱动程序的在注册表中的名字 
   lpszDriverName,         // 注册表驱动程序的 DisplayName 值 
   SERVICE_ALL_ACCESS,     // 加载驱动程序的访问权限 
   SERVICE_KERNEL_DRIVER, // 表示加载的服务是驱动程序 
   SERVICE_DEMAND_START,   // 注册表驱动程序的 Start 值 
   SERVICE_ERROR_IGNORE,   // 注册表驱动程序的 ErrorControl 值 
   szDriverImagePath,      // 注册表驱动程序的 ImagePath 值 
   NULL, 
   NULL, 
   NULL, 
   NULL, 
   NULL);

DWORD dwRtn;
// 判断服务是否失败
if( hServiceDDK == NULL ) 
{ 
   dwRtn = GetLastError();
   if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS ) 
   { 
    //由于其他原因创建服务失败
    printf( "CrateService() Faild %d ! \n", dwRtn ); 
    bRet = FALSE;
    goto BeforeLeave;
   } 
   else 
   {
    //服务创建失败,是由于服务已经创立过
    printf( "CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n" ); 
   }

   // 驱动程序已经加载,只需要打开 
   hServiceDDK = OpenService( hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS ); 
   if( hServiceDDK == NULL ) 
   {
    // 如果打开服务也失败,则意味错误
    dwRtn = GetLastError(); 
    printf( "OpenService() Faild %d ! \n", dwRtn ); 
    bRet = FALSE;
    goto BeforeLeave;
   } 
   else 
   {
    printf( "OpenService() ok ! \n" );
   }
} 
else 
{
   printf( "CrateService() ok ! \n" );
}

// 开启此项服务
bRet= StartService( hServiceDDK, NULL, NULL ); 
if( !bRet ) 
{ 
   DWORD dwRtn = GetLastError(); 
   if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING ) 
   { 
    printf( "StartService() Faild %d ! \n", dwRtn ); 
    bRet = FALSE;
    goto BeforeLeave;
   } 
   else 
   { 
    if( dwRtn == ERROR_IO_PENDING ) 
    { 
     // 设备被挂住
     printf( "StartService() Faild ERROR_IO_PENDING ! \n");
     bRet = FALSE;
     goto BeforeLeave;
    } 
    else 
    { 
     // 服务已经开启
     printf( "StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n");
     bRet = TRUE;
     goto BeforeLeave;
    } 
   } 
}
bRet = TRUE;
// 离开前关闭句柄
BeforeLeave:
if(hServiceDDK)
{
   CloseServiceHandle(hServiceDDK); // 服务句柄
}
if(hServiceMgr)
{
   CloseServiceHandle(hServiceMgr); // SCM句柄
}
return bRet;
}

// 卸载驱动程序 
BOOL UnloadNTDriver( char * szSvrName ) 
{
/************************* 卸载NT驱动的代码******************************
   ① 调用OpenSCManager,打开SCM管理器,如果返回NULL,则返回失败,否则继续.
   ② 调用OpenService.如果返回NULL,则返回失败,否则继续
   ③ 调用DeleteService卸载此项服务.
   ④ 成功返回.
************************************************************************/

BOOL bRet = FALSE;
SC_HANDLE hServiceMgr=NULL;// SCM管理器的句柄
SC_HANDLE hServiceDDK=NULL;// NT驱动程序的服务句柄
SERVICE_STATUS SvrSta;
// 打开SCM管理器
hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); 
if( hServiceMgr == NULL ) 
{
   // 打开SCM管理器失败
   printf( "OpenSCManager() Faild %d ! \n", GetLastError() ); 
   bRet = FALSE;
   goto BeforeLeave;
} 
else 
{
   // 打开SCM管理器失败成功
   printf( "OpenSCManager() ok ! \n" ); 
}

// 打开驱动所对应的服务
hServiceDDK = OpenService( hServiceMgr, szSvrName, SERVICE_ALL_ACCESS );

if( hServiceDDK == NULL ) 
{
   // 打开驱动所对应的服务失败
   printf( "OpenService() Faild %d ! \n", GetLastError() ); 
   bRet = FALSE;
   goto BeforeLeave;
} 
else 
{ 
   printf( "OpenService() ok ! \n" ); 
}

// 停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。 
if( !ControlService( hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ) ) 
{ 
   printf( "ControlService() Faild %d !\n", GetLastError() ); 
} 
else 
{
   // 打开驱动所对应的失败
   printf( "ControlService() ok !\n" ); 
} 
// 动态卸载驱动程序。 
if( !DeleteService( hServiceDDK ) ) 
{
   // 卸载失败
   printf( "DeleteSrevice() Faild %d !\n", GetLastError() ); 
} 
else 
{ 
   // 卸载成功
   printf( "DelServer:eleteSrevice() ok !\n" ); 
} 
bRet = TRUE;
BeforeLeave:
// 离开前关闭打开的句柄
if(hServiceDDK)
{
   CloseServiceHandle(hServiceDDK); // 服务句柄
}
if(hServiceMgr)
{
   CloseServiceHandle(hServiceMgr); // SCM 句柄
}
return bRet; 
}

void TestDriver()
{
// 测试驱动程序 
HANDLE hDevice = CreateFile("\\\\.\\HelloDDK", 
   GENERIC_WRITE | GENERIC_READ, 
   0, 
   NULL, 
   OPEN_EXISTING, 
   0, 
   NULL); 
if( hDevice != INVALID_HANDLE_VALUE ) 
{
   MessageBox(NULL,"SUCESSFULLY....ComeOn...","Yes",0);
   printf( "Create Device ok ! \n" ); 
}
else 
{
   printf( "Create Device faild %d ! \n", GetLastError() ); 
   MessageBox(NULL,"Faild...Fuckking...","No",0);
}
CloseHandle( hDevice );
}

int main(int argc, char* argv[]) 
{  

UnloadNTDriver(DRIVER_NAME);
// 加载驱动
BOOL bRet = LoadNTDriver(DRIVER_NAME,DRIVER_PATH);
if (!bRet)
{
   printf("LoadNTDriver error\n");
   return 0;
}
// 加载成功

printf( "press any to create device!\n" ); 
getch();

TestDriver();

// 这时候你可以通过注册表,或其他查看符号连接的软件验证。 
printf( "press any to unload the driver!\n" ); 
getch();

// 卸载驱动
UnloadNTDriver(DRIVER_NAME);
// if (!bRet)
// {
//   printf("UnloadNTDriver error\n");
//   return 0;
// }
system("pause");
return 0; 
}


以上是使用OpenSCManager创建驱动服务,下面介绍使用隐藏服务方式加载驱动服务。

====================================================================================================================================================

隐藏服务
驱动的加载一般有三种方式:
OpenSCManager
ZwLoadDriver
ZwSetSystemInformation
这里我们用ZwLoadDriver来加载驱动程序.便可以隐藏服务了,没试其他,冰刃和WSysCheck就看不到我们的服务了

摘链,注意加载驱动用ZwLoadDriver不要用OpenSCManager,否则如下图一样:

驱动代码比较简单

#include "ntddk.h" typedef unsigned long DWORD; typedef DWORD* PDWORD; typedef struct _DRIVER_DATA { LIST_ENTRY listEntry; DWORD unknown1; DWORD unknown2; DWORD unknown3; DWORD unknown4; DWORD unknown5; DWORD unknown6; DWORD unknown7; UNICODE_STRING path; UNICODE_STRING name; } DRIVER_DATA; VOID OnUnload( IN PDRIVER_OBJECT pDriverObject ) { DbgPrint("OnUnload called."); } NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING theRegistryPath ) {

DRIVER_DATA* driverData; driverData = *((DRIVER_DATA**)((DWORD)pDriverObject + 20)); if( driverData != NULL ) { *((PDWORD)driverData->listEntry.Blink) = (DWORD)driverData->listEntry.Flink; driverData->listEntry.Flink->Blink = driverData->listEntry.Blink; DbgPrint("Sucessfull.\n"); } pDriverObject->DriverUnload = OnUnload; return STATUS_SUCCESS; }

加载驱动后,我们用DbgView看到打出的Sucessfull就知道我们的驱动已经运行了...然后用冰刃的查看模块,服务..好像没什么动静...呵呵。

下面的图是用OpenSCManager加载驱动的效果....所以不要用OpenSCManager加载,用ZwLoadDriver加载,这样冰刃才查不出来

========================================================================================================================

再收藏一段代码:

#include <windows.h>  
#include <winsvc.h>  
#include <conio.h>  
#include <stdio.h>

#define DRIVER_NAME "HelloDDK"
#define DRIVER_PATH "..\\MyDriver\\MyDriver_Check\\HelloDDK.sys"

//装载NT驱动程序
BOOL LoadNTDriver(char* lpszDriverName,char* lpszDriverPath)
{
	char szDriverImagePath[256];
	//得到完整的驱动路径
	GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);

	BOOL bRet = FALSE;

	SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
	SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄

	//打开服务控制管理器
	hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

	if( hServiceMgr == NULL )  
	{
		//OpenSCManager失败
		printf( "OpenSCManager() Faild %d ! \n", GetLastError() );
		bRet = FALSE;
		goto BeforeLeave;
	}
	else
	{
		////OpenSCManager成功
		printf( "OpenSCManager() ok ! \n" );  
	}

	//创建驱动所对应的服务
	hServiceDDK = CreateService( hServiceMgr,
		lpszDriverName, //驱动程序的在注册表中的名字  
		lpszDriverName, // 注册表驱动程序的 DisplayName 值  
		SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限  
		SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序  
		SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值  
		SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值  
		szDriverImagePath, // 注册表驱动程序的 ImagePath 值  
		NULL,  
		NULL,  
		NULL,  
		NULL,  
		NULL);  

	DWORD dwRtn;
	//判断服务是否失败
	if( hServiceDDK == NULL )  
	{  
		dwRtn = GetLastError();
		if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS )  
		{  
			//由于其他原因创建服务失败
			printf( "CrateService() Faild %d ! \n", dwRtn );  
			bRet = FALSE;
			goto BeforeLeave;
		}  
		else  
		{
			//服务创建失败,是由于服务已经创立过
			printf( "CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n" );  
		}

		// 驱动程序已经加载,只需要打开  
		hServiceDDK = OpenService( hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS );  
		if( hServiceDDK == NULL )  
		{
			//如果打开服务也失败,则意味错误
			dwRtn = GetLastError();  
			printf( "OpenService() Faild %d ! \n", dwRtn );  
			bRet = FALSE;
			goto BeforeLeave;
		}  
		else 
		{
			printf( "OpenService() ok ! \n" );
		}
	}  
	else  
	{
		printf( "CrateService() ok ! \n" );
	}

	//开启此项服务
	bRet= StartService( hServiceDDK, NULL, NULL );  
	if( !bRet )  
	{  
		DWORD dwRtn = GetLastError();  
		if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING )  
		{  
			printf( "StartService() Faild %d ! \n", dwRtn );  
			bRet = FALSE;
			goto BeforeLeave;
		}  
		else  
		{  
			if( dwRtn == ERROR_IO_PENDING )  
			{  
				//设备被挂住
				printf( "StartService() Faild ERROR_IO_PENDING ! \n");
				bRet = FALSE;
				goto BeforeLeave;
			}  
			else  
			{  
				//服务已经开启
				printf( "StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n");
				bRet = TRUE;
				goto BeforeLeave;
			}  
		}  
	}
	bRet = TRUE;
//离开前关闭句柄
BeforeLeave:
	if(hServiceDDK)
	{
		CloseServiceHandle(hServiceDDK);
	}
	if(hServiceMgr)
	{
		CloseServiceHandle(hServiceMgr);
	}
	return bRet;
}

//卸载驱动程序  
BOOL UnloadNTDriver( char * szSvrName )  
{
	BOOL bRet = FALSE;
	SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
	SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄
	SERVICE_STATUS SvrSta;
	//打开SCM管理器
	hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );  
	if( hServiceMgr == NULL )  
	{
		//带开SCM管理器失败
		printf( "OpenSCManager() Faild %d ! \n", GetLastError() );  
		bRet = FALSE;
		goto BeforeLeave;
	}  
	else  
	{
		//带开SCM管理器失败成功
		printf( "OpenSCManager() ok ! \n" );  
	}
	//打开驱动所对应的服务
	hServiceDDK = OpenService( hServiceMgr, szSvrName, SERVICE_ALL_ACCESS );  

	if( hServiceDDK == NULL )  
	{
		//打开驱动所对应的服务失败
		printf( "OpenService() Faild %d ! \n", GetLastError() );  
		bRet = FALSE;
		goto BeforeLeave;
	}  
	else  
	{  
		printf( "OpenService() ok ! \n" );  
	}  
	//停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。  
	if( !ControlService( hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ) )  
	{  
		printf( "ControlService() Faild %d !\n", GetLastError() );  
	}  
	else  
	{
		//打开驱动所对应的失败
		printf( "ControlService() ok !\n" );  
	}  
	//动态卸载驱动程序。  
	if( !DeleteService( hServiceDDK ) )  
	{
		//卸载失败
		printf( "DeleteSrevice() Faild %d !\n", GetLastError() );  
	}  
	else  
	{  
		//卸载成功
		printf( "DelServer:eleteSrevice() ok !\n" );  
	}  
	bRet = TRUE;
BeforeLeave:
//离开前关闭打开的句柄
	if(hServiceDDK)
	{
		CloseServiceHandle(hServiceDDK);
	}
	if(hServiceMgr)
	{
		CloseServiceHandle(hServiceMgr);
	}
	return bRet;	
} 

void TestDriver()
{
	//测试驱动程序  
	HANDLE hDevice = CreateFile("\\\\.\\HelloDDK",  
		GENERIC_WRITE | GENERIC_READ,  
		0,  
		NULL,  
		OPEN_EXISTING,  
		0,  
		NULL);  
	if( hDevice != INVALID_HANDLE_VALUE )  
	{
		printf( "Create Device ok ! \n" );  
	}
	else  
	{
		printf( "Create Device faild %d ! \n", GetLastError() );  
	}
	CloseHandle( hDevice );
} 

int main(int argc, char* argv[])  
{
	//加载驱动
	BOOL bRet = LoadNTDriver(DRIVER_NAME,DRIVER_PATH);
	if (!bRet)
	{
		printf("LoadNTDriver error\n");
		return 0;
	}
	//加载成功

	printf( "press any to create device!\n" );  
	getch();  

	TestDriver();

	//这时候你可以通过注册表,或其他查看符号连接的软件验证。  
	printf( "press any to unload the driver!\n" );  
	getch();  

	//卸载驱动
	UnloadNTDriver(DRIVER_NAME);
	if (!bRet)
	{
		printf("UnloadNTDriver error\n");
		return 0;
	}

	return 0;  
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值