那么线程会卡死。所以,我们要保证File 对象不是Pipe类型。
可以验证 FILE_OBJECT->FileName中是否含有Pipe字串就可以了。
OpenProcedure 和 ColoseProcedure 等等则提供如关闭,打开该对象等操作,可以 HOOK 这
些函数,也就是OBJECT HOOK了。
看具体代码:
[code]
objectheader=(POBJECT_HEADER)((ULONG)tableentry->Object & 0xfffffff8 |
0x80000000);//Object的低三位置0,取得对象头的地址。
DbgPrint("Object: %X ",&objectheader->Body);
objectname=(PUNICODE_STRING)((ULONG)objectheader->Type+OBJECT_TYPE_NAME
_OFFSET);//由于ntddk.h中没有定义object_type和object_等对象,只有采用硬编码。
if(objectname)
{
DbgPrint("Type: %wZ \n",objectname);
}
DbgPrint("ObjectHeader: %X \nPointerCount: %x HandleCount:
%X\n",objectheader,objectheader->PointerCount,objectheader->HandleCount
);
/*如果是命名对象,则通过NameInofOfsset数据成员得到object_header_name_info结
构,,输出Directory和名字*/
if(objectheader->NameInfoOffset)
{
obnameinfo=(POBJECT_HEADER_NAME_INFO)((ULONG)objectheader-(ULONG)object
header->NameInfoOffset);
DbgPrint("Directory Object: %X Name:
%wZ\n",obnameinfo->Directory,&obnameinfo->name);
}
/*filename是一个unicode_string的字串,为”File”,®name则是”Reg”的
UNICODE_STRING数据。
验证是否为File对象*/
if(RtlEqualUnicodeString((PCUNICODE_STRING)&filename,(PCUNICODE_STRING)
objectname,TRUE))
{
object=(PFILE_OBJECT)&objectheader->Body;
if(SpyFindSubString(&object->FileName,&pipe)) //检验是否为
Pipe类型。
goto _ret;
else
goto fuck;
}
/*验证Reg对象
if(!RtlEqualUnicodeString((PCUNICODE_STRING)®name,(PCUNICODE_STRING)
objectname,TRUE))
goto _ret;
fuck:
QueryName=0;
//得到路径解析函数地址
QueryName=(IopQueryName)(*(PULONG)((ULONG)objectheader->Type+OBJECT_TYPE
_QUERYNAME_OFFSET));
DbgPrint("the iopQueryName is %X\n",(ULONG)QueryName);
if (QueryName)
{
/*第一次调用路径解析函数会失败,由于缓冲区长度不够。,函数会在length变量中写入
需要的缓冲区长度,再次调用就可以了。*/
status=(*QueryName)(&objectheader->Body,TRUE,(POBJECT_NAME_INFORMATION)&
nameinformation,sizeof(OBJECT_NAME_INFORMATION),&length,*(PUCHAR)((ULONG)KeG
etCurrentThread()+0x140));
if(!NT_SUCCESS(status))
{
status=(*QueryName)(&objectheader->Body,TRUE,(POBJECT_NAME_INFORMATION)&
nameinformation,length,&length,*(PUCHAR)((ULONG)KeGetCurrentThread()+0x140))
;
if(NT_SUCCESS(status))
{
DbgPrint("Name: %wZ\n",&nameinformation);
}
}
}
_ret:
DbgPrint(“\n\n”);
[/code]
好了,我们看看程序运行效果。加载驱动,在R3传入要遍历的进程ID,R0中查看效果。
以上代码在vs2010+wdk 7600.16385.0编译成功,在vm+XP SP3上测试通过。
对象是很重要的,在对象上可以做的事情还是很多的,也很猥琐,不容易检测。我们这样自
己实现通过句柄定位对象有什么意义呢?我们可以HOOK explookuphandletableentry这个
函数,因为很多对于句柄的访问都会调用找个函数,我们可以有效的防止其他进程对本进程
句柄的查看,dump等操作。还可以hook object的closeprocedure openprocedure等函数,
保护自己的对象的安全。
|