日期:2014-05-17  浏览次数:20752 次

做过SSDT HOOK 或者 懂驱动的帮忙看下代码
这是很简单的一个SSDT HOOK CreateSection的例子,为了测试,我仅仅是把原函数换个地方执行而已,可是每次服务启动后,就无法打开程序了,好像原函数换个地方就错误了··好奇怪,照常,我贴出代码:
C/C++ code

#include "ntddk.h"
#pragma pack(1)
typedef struct _SYS_SERVICE_TABLE { 
    void*ServiceTable;//指向函数表地址 
    void *CounterTable; //指向函数调用次数记录表,用于调试阶段 
    unsigned long ServiceLimit; //服务数
    void*ArgumentsTable; //参数表
}SYS_SERVICE_TABLE,*PSSDT; //系统服务表述表                     SYS_SERVICE_TABLE
#pragma pack()
extern PSSDT KeServiceDescriptorTable; 
PMDL   g_pmdlSystemCall;//MDL指针
void *MappedSSDT;//用于保存我们使用MDL描述的原SSDT表的地址,这个地址的SSDT的内存保护设为了“可写”
const WCHAR devicename[]=L"\\Device\\Protector";//设备名
const WCHAR devicelink[]=L"\\DosDevices\\PROTECTOR";//设备符号连接名
typedef NTSTATUS (*CREATESECTION)(OUT PHANDLE  SectionHandle,IN ACCESS_MASK  DesiredAccess,IN POBJECT_ATTRIBUTES  ObjectAttributes OPTIONAL,IN PLARGE_INTEGER  MaximumSize OPTIONAL,IN ULONG  SectionPageProtection,IN ULONG  AllocationAttributes,IN HANDLE  FileHandle OPTIONAL);
CREATESECTION RealCallee;//保存原先本来该调用的函数地址

ULONG SSDT_Address;//用于保存相关函数的地址,用于最后退出程序时修改过来

//-----------------------------------------判断是否允许使用-------------------------------------
//this function decides whether we should allow NtCreateSection() call to be successfull
NTSTATUS MyCreateSection(OUT PHANDLE  SectionHandle,IN ACCESS_MASK  DesiredAccess,IN POBJECT_ATTRIBUTES  ObjectAttributes OPTIONAL,IN PLARGE_INTEGER  MaximumSize OPTIONAL,IN ULONG  SectionPageProtection,IN ULONG  AllocationAttributes,IN HANDLE  FileHandle OPTIONAL) 
{
   
   return RealCallee(SectionHandle,DesiredAccess,ObjectAttributes,MaximumSize,SectionPageProtection,AllocationAttributes,FileHandle); 
}


//----------------------------Dispatch Routine--------------------------------
NTSTATUS DrvDispatch(IN PDEVICE_OBJECT device,IN PIRP Irp)
{
    ULONG Input; //暂存

    PIO_STACK_LOCATION loc=IoGetCurrentIrpStackLocation(Irp);//获取IRP堆栈地址

    if(loc->Parameters.DeviceIoControl.IoControlCode==1000)//如果是自己制定的操作,操作号设成了1000,见主程序代码
    {
          SSDT_Address=(ULONG)(((PSSDT)MappedSSDT)->ServiceTable)+4*50;//获取函数在的SSDT表的表项地址
          RealCallee=(CREATESECTION)(*((ULONG*)SSDT_Address));//记录真实的被调用者
          Input=(ULONG)MyCreateSection;//赋给Input
          RtlMoveMemory((ULONG*)SSDT_Address,&Input,4);//把我们自己的函数地址放到SSDT中
         
    }
     Irp->IoStatus.Status=0;
          IoCompleteRequest(Irp,IO_NO_INCREMENT);
     return 0;
}

//---------------------------------打开关闭请求的处理--------------------------------------

// nothing special
NTSTATUS DrvCreateClose(IN PDEVICE_OBJECT device,IN PIRP Irp)

{
    
Irp->IoStatus.Information=0;
Irp->IoStatus.Status=0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return 0;

}


//------------------------------------------------------------------------
// nothing special -just a cleanup
void DrvUnload(IN PDRIVER_OBJECT driver)
{
UNICODE_STRING devlink;
RtlMoveMemory((PVOID)SSDT_Address,&RealCallee,4);//把原地址复原

if(g_pmdlSystemCall)
{
MmUnmapLockedPages(MappedSSDT,g_pmdlSystemCall);//取消MDL内存映射
MmUnlockPages(g_pmdlSystemCall);//取消内存锁定
IoFreeMdl(g_pmdlSystemCall);
}
RtlInitUnicodeString(&devlink,devicelink);
IoDeleteSymbolicLink(&devlink);
IoDeleteDevice(driver->DeviceObject);
KdPrint(("驱动卸载完毕.\n"));
}

//--------------------------------------------------------------------
//DriverEntry just creates our device - nothing special here 初始化映射SSDT
NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver,IN PUNICODE_STRING path)
{

PDEVICE_OBJECT devobject;

UNICODE_STRING devlink,devname;//设备符号链接名和设备名
devobject=0;
RtlInitUnicodeString(&devname,devicename);//赋值
RtlInitUnicodeString(&devlink,devicelink);

IoCreateDevice(driver,256,&devname,FILE_DEVICE_UNKNOWN,0,TRUE,&devobject);//创建设备
IoCreateSymbolicLink(&devlink,&devname);//把符号链接名和设备名相关联

driver->Majo