首页
社区
课程
招聘
[求助]关于驱动程序里面使用 HOOK+全局变量 的分析和疑问
发表于: 2010-5-7 20:54 4918

[求助]关于驱动程序里面使用 HOOK+全局变量 的分析和疑问

2010-5-7 20:54
4918
各位大哥 大姐 小弟又搞了一晚上 结果N多东西没有弄懂  特来请教~
小弟依葫芦画瓢的 写了个文件保护的驱动程序  单是加载驱动后 能够实现隐藏驱动程序里面写死了的文件  为了动态的隐藏一个文件  我在外面写了个程序 用函数DeviceIoControl()来与驱动进行数据传输

下面是我化简了的驱动程序

//下面两个结构体是声明要HOOK的原型和HOOK本身
NTSYSAPI NTSTATUS NTAPI ZwQueryDirectoryFile(....);
NTSTATUS HookZwQueryDirectoryFile(....);

// 直接申请一个全局变量 用C的老写法
ANSI_STRING HDF={1,1,"0000"}

NTSTATUS DriverEntry(.......)
{
   ....
    // HOOK ZwQueryDirectoryFile 并保存原 ZwQueryDirectoryFile 函数地址
   HOOK_SYSCALL(ZwQueryDirectoryFile, HookZwQueryDirectoryFile, OriginalZwQueryDirectoryFile);
....

}

NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)   //传进参数来关键靠这个函数
{
    NTSTATUS           status = STATUS_SUCCESS;
    PIO_STACK_LOCATION irpStack;
    PVOID              ioBuf;
    ULONG              inBufLength, outBufLength;
    ULONG              ioControlCode;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    Irp->IoStatus.Information = 0;

    //关键在这里
    ioBuf = Irp->AssociatedIrp.SystemBuffer;
    RtlInitAnsiString(&HDF, ioBuf);
    dprintf("inbuffer is  %Z \n",&HDF);  //这里用dbgview打印出来 确实是传进来的那个参数 准确无误
    .....
}

//HOOK的过程函数
NTSTATUS HookZwQueryDirectoryFile(...)
{....

    // 执行真正的 ZwQueryDirectoryFile 函数
    rc = OriginalZwQueryDirectoryFile(......);

    //把上面传过来的参数通过全局变量赋值到HideDirFile
    HideDirFile=HDF;
    //打印出来
    dprintf("hidedirfile name is   %Z \n",&HideDirFile);
    dprintf("global           is   %Z \n",&HDF);
    //结果这上面两排打印出来的完全就变了 两个变量都变了~变得很怪
....
}


下面是我在dbgview里面打印出来的 由于是HOOK 所以 一加载SYS那个驱动 他就一直打印HOOK函数里面的东西了 不全部列出来 只看变化的那一点点
....前面这些都一样
00000116	10.81239510	hidedirfile name is   0   //0是因为初始化全局变量的时候赋值为0	
00000117	10.81240845	global           is   0 	
00000118	11.28203011	inbuffer is abcdefg	  //这里是输入的abcdefg 输进去正常 传出来就挂了
00000120	15.00038242	hidedirfile name is   ?S	
00000121	15.00040245	global           is   ?S
...后面这些也一样


这个是怎么回事??

接下来我改全局变量为设备扩展存储  在外面定义了一个结构体用来存储
typedef struct _DEVICE_EXTENSION
{
        PDEVICE_OBJECT pDevice;
        UNICODE_STRING ustrDeviceName;        //设备名称
        UNICODE_STRING ustrSymLinkName;        //符号链接名

        ANSI_STRING buffer;//缓冲区
        ULONG file_length;//模拟的文件长度,必须小于MAX_FILE_LENGTH
    ULONG StateVariable;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

然后指定义了个全局变量的指针来指这个固定的扩展  因为我看到他们都是用的全局变量指针 都没有问题

同样在下面这个函数里面接参数:
NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    NTSTATUS           status = STATUS_SUCCESS;
    PIO_STACK_LOCATION irpStack;
    PVOID              ioBuf;
    ULONG              inBufLength, outBufLength;
    ULONG              ioControlCode;
    PDEVICE_EXTENSION pDevExt;
    ANSI_STRING a1;

    irpStack = IoGetCurrentIrpStackLocation(Irp);

    Irp->IoStatus.Information = 0;
    ioBuf = Irp->AssociatedIrp.SystemBuffer;
    inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

        RtlInitAnsiString(&a1, ioBuf);
        pDevExt=(PDEVICE_EXTENSION)devObj->DeviceExtension;   //devObj是那个全局指针
        pDevExt->buffer=a1;

        dprintf("extension buffer is %Z\n",&(pDevExt->buffer));
        dprintf("inbuffer is  %Z \n",&a1);
        //上面两行在接收参数后 打印出来准确无误,说明参数确实传进来了的,和上面那种情况一样      
     ....
}

然后在HOOK过程函数里面:
NTSTATUS HookZwQueryDirectoryFile(...)
{
    NTSTATUS rc = STATUS_SUCCESS;
    ANSI_STRING ansiFileName, ansiDirName, HideDirFile;
    UNICODE_STRING uniFileName;
    PCWSTR pProcPath = NULL;
    PDEVICE_EXTENSION pDevExt;

    // 执行真正的 ZwQueryDirectoryFile 函数
    rc = OriginalZwQueryDirectoryFile(...);

    pDevExt=(PDEVICE_EXTENSION)devObj->DeviceExtension;
    HideDirFile = pDevExt->buffer;
    dprintf("hidedirfile name is   %Z \n",&HideDirFile);
    dprintf("extension buffer is   %Z \n",&(pDevExt->buffer));
    //上面两行打印出来就又变了  和前面的情况一样
....
}

在dbgview里面的情况
...
00000116	10.81239510	hidedirfile name is   0 	
00000117	10.81240845	extension buffer is   0 	
00000118	11.28203011	inbuffer is  abcdefg 	
00000119	11.28209305	extension buffer is abcdefg	
00000120	15.00038242	hidedirfile name is   ?S	
00000121	15.00040245	extension buffer is   ?S	
00000122	15.17219639	hidedirfile name is   ?S	
00000123	15.17220974	extension buffer is   ?S
....
同样开始的时候通过driverEntry赋值扩展里面的变量为0 加载后打印出来全是0
在外部程序输入的时候都是输入的abcdefg 结果接收的时候正常  再传到hook里面就不正常了 变成了问号~


随后我又用了自旋锁来进行同步  但是 用自旋锁的时候 只要把自旋锁放到HOOK函数里面 加载资源后没有问题  但是 过几秒钟 虚拟机就蓝屏了

然后我用KeRaiseirql()进行提升中断 分别在接收的函数和HOOK函数里面分别把对变量赋值那部分代码放在KeRaiseirql()和KelowerIrql()中间  但是调试出来的结果还是和上面全局变量直接赋值的一样 在hook函数里面赋值了就成乱码了  

我在虚拟机里面是分配的一个CPU 我的主机本身是双核的CPU  ~~XP SP2系统

各位大哥 帮帮忙 小弟我要崩溃了

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
2
// 直接申请一个全局变量 用C的老写法
ANSI_STRING HDF={1,1,"0000"}

这个写法 - -!

UNICODE_STRING 要打印,一般是 %wZ

(UNICODE_STRING)Buffer 要打印,一般是 %ws  

~~~基础啊~
2010-5-7 22:19
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
3
SSDT hook没见过谁用自旋锁~~  要么#pragma LOCKEDDATA,要么自己申请非分页内存~~一般SSDT表里的函数都是运行在很低的IRQL上,没必要提升什么中断级别~

//把上面传过来的参数通过全局变量赋值到HideDirFile
    HideDirFile=HDF;

第一次见到ansi_string是这样赋值的  - -.  蛋痛~~
2010-5-7 22:23
0
雪    币: 192
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
大哥 我诚心请教 是怎么弄的  
你意思是说 在HOOK函数里面 不必用什么自锁 提升中断    而是我的赋值有问题?
2010-5-7 23:02
0
雪    币: 386
活跃值: (46)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
拷貝到字符数组中去吧,保存到設備扩展.指針指着的位置變動很快的
2010-5-8 03:09
0
游客
登录 | 注册 方可回帖
返回
//