测试环境:Windows Xp SP 32位
Xp貌似在内核中不用关闭WP位,可以直接修改
Ring3代码:
#include "stdafx.h"
#include<windows.h>
#include<winioctl.h>
#include<stdio.h>
#include <winsvc.h>
#include <conio.h>
#pragma comment(lib, "Advapi32.lib")
//宏定义之获取一个32位的宏控制码 参数:设备类型(鼠标,键盘...Unkonwn);0x000-0x7FF保留,0x800-0xfff随便填一个;数据交互类型(缓冲区,IO,其他);对这个设备的权限
#define OPER1 CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define OPER2 CTL_CODE(FILE_DEVICE_UNKNOWN,0x900,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define SYMBOLICLINK_NAME "\\\\.\\MyTestDriver"
#define DRIVER_PATH "HOOK-SSDT.sys"
#define DRIVER_NAME "HOOK-SSDT"
HANDLE g_hDevice; //全局驱动句柄
BOOL LoadNTDriver() {
char szDriverImagePath[256];
//得到完整的驱动路径
GetFullPathName(DRIVER_PATH, 256, szDriverImagePath, NULL);
//replace(szDriverImagePath);
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,
DRIVER_NAME, //驱动程序的在注册表中的名字
DRIVER_NAME, // 注册表驱动程序的 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, DRIVER_NAME, 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()
{
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, DRIVER_NAME, 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;
}
BOOL Open(TCHAR* pLinkName)
{
//在3环获取设备句柄
TCHAR szBuffer[10] = { 0 };
//CreateFile 打开的是内核的设备对象
g_hDevice = ::CreateFile(pLinkName, GENERIC_READ | GENERIC_WRITE, 0,0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (g_hDevice != INVALID_HANDLE_VALUE)
return TRUE;
else
return FALSE;
}
BOOL Load(){
DWORD ByteReturned=0;
LoadNTDriver();
//1.通过符号链接,打开设备
if (!Open(SYMBOLICLINK_NAME))
{
printf("设备对象打开失败!!!");
getchar();
return false;
}
DeviceIoControl(g_hDevice,OPER1,0, 0, 0, 0,&ByteReturned,NULL);
return TRUE;
}
BOOL UnLoad(){
DWORD ByteReturned=0;
DeviceIoControl(g_hDevice,OPER2,0, 0, 0, 0,&ByteReturned,NULL);
CloseHandle(g_hDevice);
UnloadNTDriver();
return TRUE;
}
int main(int argc, char* argv[])
{
HWND hwnd = FindWindow("#32770","Kernel-Mode Driver Manager");
Load();
hwnd = FindWindow("11111","22222");
UnLoad();
getchar();
return 0;
}
Ring0头文件:
#pragma once
#include "ntifs.h"
#define i 0x17A
#define DEVICE_NAME L"\\Device\\MyDevice"
#define SYMBOLICLINE_NAME L"\\??\\MyTestDriver" //ring3用CreateFile打开设备时,用"\\\\.\\MyTestDriver"//相当于起的别名
#define OPER1 CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define OPER2 CTL_CODE(FILE_DEVICE_UNKNOWN,0x900,METHOD_BUFFERED,FILE_ANY_ACCESS)
typedef struct _SERVICE_TABLE {
ULONG* FunAddr;
ULONG Count;
ULONG ServiceLimit;
UCHAR* ParaSize;
}SERVICE_TABLE, *PSERVICE_TABLE;
typedef struct _SERVICE_TABLE_ENTANCE {
SERVICE_TABLE Blue_Table;
SERVICE_TABLE Yellow_Table;
SERVICE_TABLE Reserve1;
SERVICE_TABLE Reserve2;
}SERVICE_TABLE_ENTANCE;
__declspec(dllimport) SERVICE_TABLE_ENTANCE KeServiceDescriptorTable;
typedef NTSTATUS(*pfun)(ULONG hWndParent, ULONG hWndChildAfter, UNICODE_STRING* lpszClassName, UNICODE_STRING* lpszWindowName, ULONG UnKnow);
SERVICE_TABLE_ENTANCE* ShawTalbe;
ULONG HookAddr;
pfun FindWindow;
Ring0代码:
#include "Struct.h"
//开启保护
VOID OpenWP() {
_asm {
cli;
mov eax, cr0;
or eax, 0x10000;
mov cr0, eax;
}
}
//关闭保护
VOID CloseWP() {
_asm {
mov eax, cr0;
and eax, not 0x10000;
mov cr0, eax;
sti;
}
}
VOID DriverUnload(PDRIVER_OBJECT pDriver) {
UNICODE_STRING SymbolicLinkName = { 0 };
RtlInitUnicodeString(&SymbolicLinkName, SYMBOLICLINE_NAME);
IoDeleteDevice(pDriver->DeviceObject);
IoDeleteSymbolicLink(&SymbolicLinkName);
DbgPrint("\nUninsta!\n");
}
NTSTATUS IrpCreateProc(PDEVICE_OBJECT pDeviceObject/*设备信息*/, PIRP pIrp/*参数信息*/) {
DbgPrint("DispatchCreate ... \n");
pIrp->IoStatus.Status = STATUS_SUCCESS;//getlasterror()得到的就是这个值
pIrp->IoStatus.Information = 0;//返回给3环多少数据,没有填0
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS IrpDefaultProc(PDEVICE_OBJECT pdriver, PIRP pIrp) {
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS HOOK(ULONG hWndParent,ULONG hWndChildAfter,UNICODE_STRING* lpszClassName, UNICODE_STRING* lpszWindowName,ULONG UnKnow) {
DbgPrint("\nFindWindow(%wZ,%wZ,%x)\n", lpszClassName, lpszWindowName, UnKnow);
return FindWindow(hWndParent, hWndChildAfter, lpszClassName, lpszWindowName, UnKnow);
}
VOID Modify() {
_asm {
mov eax, KeServiceDescriptorTable;
mov[ShawTalbe], eax;
sub[ShawTalbe], 0x40;
}
HookAddr = ShawTalbe->Yellow_Table.FunAddr[i];
ShawTalbe->Yellow_Table.FunAddr[i] = HOOK;
FindWindow = (pfun)HookAddr;
DbgPrint("VirtualAddress:%x\nPhyicalAddress:%x\n", HookAddr, HOOK);
}
NTSTATUS IrpDeviceContrlProc(PDEVICE_OBJECT pdriver, PIRP pIrp) {
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION pIrpStack;//定义一个指向IO_STACK_LOCATION结构体的指针
ULONG uIoControCode;
//从当前Irp中获取数据
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);//根据从ring3发来的
//获取控制码 Parameters里面是一个联合体 Read Write DeviceIoControl
uIoControCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
switch(uIoControCode) {
case OPER1:
{
Modify();
pIrp->IoStatus.Information = 0;
break;
}
case OPER2:
{
DbgPrint("关闭中\n");
ShawTalbe->Yellow_Table.FunAddr[i] = HookAddr;
DbgPrint("IrpDeviceContrlProc -> OPER1 ...\n");
pIrp->IoStatus.Information = 0;
break;
}
}
//设置返回状态
DbgPrint("DispatchDeviceControl ... \n");
pIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING ppath) {
DbgPrint("%x %x\n", HOOK, Modify);
NTSTATUS status = 0;
ULONG uIndex = 0;
PDEVICE_OBJECT pDeviceObj = NULL;
UNICODE_STRING DeviceName;
UNICODE_STRING SymbolicLinkName;
DbgPrint("hello\n");
//创建设备名称
RtlInitUnicodeString(&DeviceName, DEVICE_NAME);
//创建设备 让三环的API能够找到,才能实现通信
status = IoCreateDevice(pDriver, 0, &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObj);
if(status != STATUS_SUCCESS) {
DbgPrint("创建设备失败! status=%x\r\n", status);
return status;
}
//设置交互数据方式
pDeviceObj->Flags |= DO_BUFFERED_IO;
//创建符号链接名称,就是给该设备在三环起个能用的别名
RtlInitUnicodeString(&SymbolicLinkName, SYMBOLICLINE_NAME);
//创建符号链接
status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
if(!NT_SUCCESS(status)) {
DbgPrint("创建符号链接失败!\r\n");
IoDeleteDevice(pDeviceObj);
return status;
}
//设置派遣函数和卸载函数
//设置派遣函数和卸载函数
for(ULONG j = 0; j < IRP_MJ_MAXIMUM_FUNCTION; j++) {
pDriver->MajorFunction[j] = IrpDefaultProc;
}
pDriver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IrpDeviceContrlProc;
pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
以下为图片效果: