TBWood
驱动牛犊
驱动牛犊
  • 注册日期2010-02-05
  • 最后登录2010-04-07
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望31点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2724回复:2

【大虾们给个解】SSDT HOOK CreateSection 到底哪有错?

楼主#
更多 发布于:2010-03-29 23:37
就是以下相当简单的代码,可每次运行后,系统都不能执行程序了,我仅仅是把CreateSection 换个函数执行啊...到底是错哪了 ?照常我附上代码:
#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 BOOL (*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;//用于保存相关函数的地址,用于最后退出程序时修改过来

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);
}



NTSTATUS DrvDispatch(IN PDEVICE_OBJECT device,IN PIRP Irp)
{
    ULONG Input; //用于获取函数在SSDT的索引号
    ULONG *pbuff;

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

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


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->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DrvDispatch;//设置设备控制的IRP都由DrvDispatch来处理
driver->MajorFunction[IRP_MJ_CREATE]=DrvCreateClose;//设置设备打开的IRP由DrvCreateClose来处理
driver->MajorFunction[IRP_MJ_CLOSE]=DrvCreateClose;//设置设备关闭的IRP由DrvCreateClose来处理
driver->DriverUnload=DrvUnload;//唯一一个不放在分发函数中的函数:卸载函数,允许动态卸载驱动。
g_pmdlSystemCall =IoAllocateMdl(KeServiceDescriptorTable->ServiceTable,KeServiceDescriptorTable->ServiceLimit*4,FALSE,FALSE,NULL);//创建分配一个MDL

if(!g_pmdlSystemCall)
  return STATUS_UNSUCCESSFUL;
  
MmBuildMdlForNonPagedPool(g_pmdlSystemCall);//初始化MDL页码数组
//g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;// 改变MDL的flags为可读状态

MmProbeAndLockPages(g_pmdlSystemCall,KernelMode,IoWriteAccess);//在内存中锁定,并且指明对它的改写权力
MappedSSDT=MmMapLockedPagesSpecifyCache(            
                g_pmdlSystemCall,
                KernelMode,
                MmCached,//是否允许用作CPU缓冲区,有三个可选的枚举值 MmNonCached=0
                NULL,//当第二个参数为UserMode的时候才有效
                FALSE,//如果发生错误,直接返回NULL
                NormalPagePriority//表明成功开辟这个空间的重要性
                );            //获取映射内存区地址                                
                                                            

return 0;

}
谦虚,谨慎,多劳,勿躁
cyndy_li
驱动牛犊
驱动牛犊
  • 注册日期2009-03-09
  • 最后登录2010-04-29
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望71点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2010-03-30 10:26
你的索引号是从irp的参数里面取的,这个是从应用层传进来的么?
TBWood
驱动牛犊
驱动牛犊
  • 注册日期2010-02-05
  • 最后登录2010-04-07
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望31点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2010-03-30 12:28
回 1楼(cyndy_li) 的帖子
恩,是那个InputData,传进来的数据应该没有问题,就是好像每次运行后,就不能打开程序了,感觉RealCallee函数没有用到···
谦虚,谨慎,多劳,勿躁
游客

返回顶部