aswcy815174418 发表于 2021-9-9 14:49

HOOK-ShadowTable监控FindWindow



**测试环境: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;
    //得到完整的驱动路径
    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 = { 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, eax;
                sub, 0x40;
        }
        HookAddr = ShawTalbe->Yellow_Table.FunAddr;

        ShawTalbe->Yellow_Table.FunAddr = 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 = 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 = IrpDefaultProc;
        }
        pDriver->MajorFunction = IrpDeviceContrlProc;
        pDriver->DriverUnload = DriverUnload;
       
        return STATUS_SUCCESS;
}
```

**以下为图片效果:**

davelu 发表于 2021-9-9 15:26

不错,这个厉害!

aswcy815174418 发表于 2021-9-9 16:25

davelu 发表于 2021-9-9 15:26
不错,这个厉害!

抛砖引玉而已,花拳绣腿

a4826800 发表于 2021-9-9 19:18

厉害,大佬

jack666 发表于 2021-9-9 20:07

LIHAILIA66666

yemaozi1982 发表于 2021-9-9 22:43

膜拜。。 好想学习

aswcy815174418 发表于 2021-9-10 05:54

yemaozi1982 发表于 2021-9-9 22:43
膜拜。。 好想学习

从滴水三期开始学吧

风过无痕52 发表于 2021-9-10 12:35

感谢楼主学习一下

zhoutl 发表于 2021-11-15 09:41

厉害了我的哥{:301_1000:}
页: [1]
查看完整版本: HOOK-ShadowTable监控FindWindow