各位大哥 大姐 小弟又搞了一晚上 结果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期)