首页
社区
课程
招聘
[求助]SSDT HOOK ZwOpenProcess
发表于: 2009-7-21 12:34 9587

[求助]SSDT HOOK ZwOpenProcess

2009-7-21 12:34
9587
我看了梧桐先生的驱动扫盲 HOOK SSDT一文 看着他的代码改了一下 准备勾取 ZwOpenProcess ,编译老是出错,各位老大帮忙看下 有两个错误 实在找不到是哪里错了
代码如下:
/*

  SSDTHook.c
  
  Author: Adly
  Last Updated: 2008-11-16
       
*/

#include <ntddk.h>

#include "SSDTHook.h"

//
// A structure representing the instance information associated with
// a particular device
//

typedef struct _DEVICE_EXTENSION
{
        ULONG  StateVariable;
       
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

//////////////////////////////////////////////////////////////////////////
//
//【1】 添加下列内容
//要挂钩SSDT,就必须先要由内核到处一个KeServiceDescriptorTable,
//那么我们还要先定义一个KeServiceDescriptorTable类型的的结构体

//#pragma 预处理指令pack(内存对齐)
#pragma pack(1)

//定义数据结构
typedef struct ServiceDescriptorEntry
{
        //unsigned无符号参数
        unsigned int *ServiceTableBase;  //keServiceDescriptorTable的基地址
        unsigned int *ServiceCounterTableBase; //Used only in checked build
        unsigned int NumberOfServices;// //包含的项数
        unsigned char *ParamTableBase;
} SSDTEntry;

//

__declspec(dllimport) SSDTEntry KeServiceDescriptorTable;

#pragma pack()

//【2】 HOOK函数声明定义了KSDT的结构,那么我们想想要HOOK那个函数呢,
//好吧,就以ZwTerminateProcess为例,我们开动,首先定义一个ZwTerminateProcess函数结构.
//函数原型:

原先是【NTKERNELAPI NTSTATUS ZwTerminateProcess(
        IN HANDLE ProcessHandle OPTIONAL,
        IN NTSTATUS ExitStatus
);】 这个函数 我替换成这个了
NTKERNELAPI NTSTATUS  
  ZwOpenProcess (
    __out PHANDLE  ProcessHandle,
    __in ACCESS_MASK  DesiredAccess,
    __in POBJECT_ATTRIBUTES  ObjectAttributes,
    __in_opt PCLIENT_ID  ClientId
    );

//【3】定义新函数结构。
原先是这个【typedef NTSTATUS(*_ZwTerminateProcess)(
        IN HANDLE ProcessHandle OPTIONAL,
        IN NTSTATUS ExitStatus
);】我替换的
typedef NTSTATUS
  *_ZwOpenProcess (
    __out PHANDLE  ProcessHandle,
    __in ACCESS_MASK  DesiredAccess,
    __in POBJECT_ATTRIBUTES  ObjectAttributes,
    __in_opt PCLIENT_ID  ClientId
    );
//声明old 旧函数地址
原先是这个【_ZwTerminateProcess Old_ZwTerminateProcess;】
_ZwOpenProcess Old_ZwOpenProcess;

//【4】我们要HOOK ZwTerminateProcess,那么我们是不是要先找出它在KSDT中的位置呢,
//没错,那么我们来定义一个通过SSDT服务号得到函数地址的宏以达到我们的目的:

#define GetSystemFunc(FuncName) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)FuncName+1)]

//【5】想要达到改写SSDT的目的,那么首先要解决的是内存保护机制的问题,
//众所周知,Windows的某些版本对内存区域启用了写保护的功能,在XP和2003中更为常见,SSDT是只读的,那怎么办呢?
//有的网友此刻估计已经明白了。
//没错,就是 Memory Descriptor List,简称 MDL。
//有的同学可能会问了,MDL究竟是个什么东西呢?
//从字面意思看,不难理解,内存描述符列表。MDL包含了内存区域的起始、拥有者proc、字节数、标记等。OK,我们需要先定义一个MDL的指针。
PMDL MDSystemCall;

//【6】 定义了MDL的指针以后,
//我们要通过MAPPED系列的参数来使内存拥有可写性,然后锁定内存中的MDL,那么我们就要定义一个PVOID的指针,来供MmMap操作。
PVOID *MappedSCT;

//【7】 下面就是替换函数了,修改SSDT中函数地址指向的位置,下面是宏定义:
#define GetIndex(_Function) *(PULONG)((PUCHAR)_Function+1)

//【8】 HOOK开启
#define HookOn(_Old, _New) \
(PVOID) InterlockedExchange( (PLONG) &MappedSCT[GetIndex(_Old)], (LONG) _New)
//【9】 HOOK关闭
#define UnHook(_Old, _New) \
InterlockedExchange( (PLONG) &MappedSCT[GetIndex(_Old)], (LONG) _New)

//【10】 新函数实现
原先是这个【NTSTATUS NewZwTerminateProcess(
        IN HANDLE ProcessHandle OPTIONAL,
        IN NTSTATUS ExitStatus
)】
NTSTATUS
  NewZwOpenProcess (
    __out PHANDLE  ProcessHandle,
    __in ACCESS_MASK  DesiredAccess,
    __in POBJECT_ATTRIBUTES  ObjectAttributes,
    __in_opt PCLIENT_ID  ClientId
    )
{
        return STATUS_UNSUCCESSFUL;
}
//////////////////////////////////////////////////////////////////////////

//
// 【11】服务函数定义
//

NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath);

NTSTATUS
SsdthookDispatchCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

NTSTATUS
SsdthookDispatchClose(IN PDEVICE_OBJECT        DeviceObject,IN PIRP Irp);

NTSTATUS
SsdthookDispatchDeviceControl(IN PDEVICE_OBJECT        DeviceObject,IN PIRP Irp);

VOID
SsdthookUnload(IN PDRIVER_OBJECT DriverObject);

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, SsdthookDispatchCreate)
#pragma alloc_text(PAGE, SsdthookDispatchClose)
#pragma alloc_text(PAGE, SsdthookDispatchDeviceControl)
#pragma alloc_text(PAGE, SsdthookUnload)
#endif // ALLOC_PRAGMA

NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
        NTSTATUS                        Status = STATUS_SUCCESS;   
        UNICODE_STRING                ntDeviceName;
        UNICODE_STRING                dosDeviceName;
        PDEVICE_EXTENSION        deviceExtension;
        PDEVICE_OBJECT                deviceObject = NULL;
       
       
        KdPrint(("[SSDTHook] DriverEntry: %wZ\n", RegistryPath));
       
       
        //初始化UNICODE字符串
        RtlInitUnicodeString(&ntDeviceName, SSDTHOOK_DEVICE_NAME_W);
       
        //IoCreateDevice 创建设备对象
        Status = IoCreateDevice(
                DriverObject,
                sizeof(DEVICE_EXTENSION),                // DeviceExtensionSize
                &ntDeviceName,                                        // DeviceName
                FILE_DEVICE_SSDTHOOK,        // DeviceType
                0,                                                                // DeviceCharacteristics
                TRUE,                                                        // Exclusive
                &deviceObject                                        // [OUT]
                );
       
        if(!NT_SUCCESS(Status))
        {
                KdPrint(("[SSDTHook] IoCreateDevice Error Code = 0x%X\n", Status));
               
                return Status;
        }
       
        deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
       
        //
        // Set up synchronization objects, state info,, etc.
        //
       
        //
        // Create a symbolic link that Win32 apps can specify to gain access
        // to this driver/device
        //
       
        RtlInitUnicodeString(&dosDeviceName, SSDTHOOK_DOS_DEVICE_NAME_W);
        //创建符号链接
        Status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);
       
        if(!NT_SUCCESS(Status))
        {
                KdPrint(("[SSDTHook] IoCreateSymbolicLink Error Code = 0x%X\n", Status));
               
                //
                // Delete Object
                //

                IoDeleteDevice(deviceObject);
               
                return Status;
        }
       
        //
        // Create dispatch points for device control, create, close.
        //
       
        DriverObject->MajorFunction[IRP_MJ_CREATE]                        = SsdthookDispatchCreate;
        DriverObject->MajorFunction[IRP_MJ_CLOSE]                        = SsdthookDispatchClose;
        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]        = SsdthookDispatchDeviceControl;
        DriverObject->DriverUnload                                                        = SsdthookUnload;
       
        //////////////////////////////////////////////////////////////////////////
        //
        // 安装HOOK
        //

        //找出旧函数地址并保存
原先是这个【Old_ZwTerminateProcess =(_ZwTerminateProcess)(GetSystemFunc(ZwTerminateProcess));】
        Old_ZwOpenProcess =(_ZwOpenProcess)(GetSystemFunc(ZwOpenProcess));
       
        MDSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4);
        if(!MDSystemCall)
                return STATUS_UNSUCCESSFUL;

    //MmBuildMdlForNonpagedPool 来更新临时 MDL

        MmBuildMdlForNonPagedPool(MDSystemCall);
        MDSystemCall->MdlFlags = MDSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
        //MmMapLockedPages来锁定内存中的MDL页
        MappedSCT = MmMapLockedPages(MDSystemCall, KernelMode);

        // 开启HOOK
原先这个【HookOn( ZwTerminateProcess, NewZwTerminateProcess);】
        HookOn( ZwOpenProcess, NewZwOpenProcess);
    DbgPrint("驱动安装成功");
        return Status;
}

NTSTATUS
SsdthookDispatchCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
        NTSTATUS Status = STATUS_SUCCESS;
       
        Irp->IoStatus.Information = 0;
       
        KdPrint(("[SSDTHook] IRP_MJ_CREATE\n"));
       
        Irp->IoStatus.Status = Status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
       
        return Status;
}

NTSTATUS
SsdthookDispatchClose(IN PDEVICE_OBJECT        DeviceObject,IN PIRP Irp)
{
        NTSTATUS Status = STATUS_SUCCESS;
       
        Irp->IoStatus.Information = 0;
       
        KdPrint(("[SSDTHook] IRP_MJ_CLOSE\n"));
       
        Irp->IoStatus.Status = Status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
       
        return Status;
}

NTSTATUS
SsdthookDispatchDeviceControl(IN PDEVICE_OBJECT        DeviceObject,IN PIRP Irp)
{
        NTSTATUS                        Status = STATUS_SUCCESS;
        PIO_STACK_LOCATION        irpStack;
        PDEVICE_EXTENSION        deviceExtension;
        PVOID                                ioBuf;
        ULONG                                inBufLength, outBufLength;
        ULONG                                ioControlCode;
       
        irpStack = IoGetCurrentIrpStackLocation(Irp);
        deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
       
        Irp->IoStatus.Information = 0;
       
        //
        // Get the pointer to the input/output buffer and it's length
        //
       
        ioBuf = Irp->AssociatedIrp.SystemBuffer;
        inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
        outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
        ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
        // Irp->UserBuffer;                // If METHOD_NEITHER, This is Output Buffer
       
        switch (ioControlCode)
        {
        case IOCTL_SSDTHOOK_TEST0:
                {
                        //
                        // Sample IO Control
                        //
                        KdPrint(("[SSDTHook] TEST0 IOCTL: 0x%X", ioControlCode));
                       
                        break;
                }

        case IOCTL_SSDTHOOK_TEST1:
                {
                        //
                        // Sample IO Control
                        //
                        KdPrint(("[SSDTHook] TEST1 IOCTL: 0x%X", ioControlCode));
                       
                        break;
                }
               
        default:
                {
                        Status = STATUS_INVALID_PARAMETER;
                       
                        KdPrint(("[SSDTHook] Unknown IOCTL: 0x%X (%04X,%04X)",
                                ioControlCode, DEVICE_TYPE_FROM_CTL_CODE(ioControlCode),
                                IoGetFunctionCodeFromCtlCode(ioControlCode)));
                       
                        break;
                }
        }
       
       
        Irp->IoStatus.Status = Status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
       
       
        return Status;
}

//卸载驱动服务
VOID SsdthookUnload(IN PDRIVER_OBJECT DriverObject)
{
        UNICODE_STRING dosDeviceName;
       
        //////////////////////////////////////////////////////////////////////////
        // 卸载HOOK
原先这个【UnHook( ZwTerminateProcess, Old_ZwTerminateProcess);】
        UnHook( ZwOpenProcess, Old_ZwOpenProcess);
       
        if(MDSystemCall)
        {
                MmUnmapLockedPages(MappedSCT, MDSystemCall);
                IoFreeMdl(MDSystemCall);
        }

        //
        // 释放任何的资源

       
       
        //删除符号链接
        RtlInitUnicodeString(&dosDeviceName, SSDTHOOK_DOS_DEVICE_NAME_W);
        IoDeleteSymbolicLink(&dosDeviceName);
       
       
        // 删除设备对象
       
        IoDeleteDevice(DriverObject->DeviceObject);
       
        KdPrint(("[SSDTHook] Unloaded"));
        DbgPrint("驱动卸载成功");
}

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (15)
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
2
我把原代码发上来吧
上传的附件:
2009-7-21 12:35
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
3
求求大家了 这是我学习的第一个驱动 帮帮忙
2009-7-21 15:18
0
雪    币: 223
活跃值: (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
至少把错误信息贴出来或者描述一下了,要不然谁有时间来找错啊。
2009-7-21 16:03
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
5
有尴尬图像的地方都是我替换的函数 用BUILD编译 说是两个地方有错误,我换成原先的函数没有错误能编译
谢谢了
2009-7-21 16:25
0
雪    币: 100
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
编译遇到问题,放出来,这样比较容易解决问题。
2009-7-21 17:41
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
7
我已经把代码放在2楼了 我用的是WDK
2009-7-21 18:07
0
雪    币: 1505
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
8
太神奇了,膜拜下楼主.
ssdt竟然能hook zw
2009-7-21 18:30
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
9
难道 ZwTerminateProcess 与ZwOpenProcess 不是一个系的?
2009-7-21 18:41
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
10
ZwTerminateProcess 这个函数 我应经HOOK 成功了 用XUETR查看 应经勾取了
2009-7-21 18:43
0
雪    币: 1505
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
11
XUETR 上ssdt列表里面有zw开头的函数?
2009-7-21 18:54
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
12
没有 我就是不明白 为什么ZwTerminateProcess 能成功,但是ZwOpenProcess不行
2009-7-21 19:16
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
错在两个小地方:
1. 行 68 "*_ZwOpenProcess"  --> "(*_ZwOpenProcess)"
2. 行 76 "Old__ZwOpenProcess" --> "Old_ZwOpenProcess"

用build工具编译,马上指出错在什么地方了,
2009-9-28 16:05
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
14
改动了如下地方

第一处:

//【3】定义新函数结构。
typedef NTSTATUS
(* ZWOPENPROCESS) (
                                 PHANDLE ProcessHandle,
                                 ACCESS_MASK DesiredAccess,
                                 POBJECT_ATTRIBUTES ObjectAttributes,
                                 PCLIENT_ID ClientId
                                 );

//声明old 旧函数地址
ZWOPENPROCESS Old_ZwOpenProcess;

第二处:

Old_ZwOpenProcess =(ZWOPENPROCESS)(GetSystemFunc(ZwOpenProcess));

这样即可编译通过了。
上传的附件:
2009-9-28 16:37
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
这个驱动简单,在xp上起作用了,
2009-9-28 16:39
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
迅雷把这个干掉了,蓝屏
2009-9-28 16:47
0
游客
登录 | 注册 方可回帖
返回
//