浅析windows对象管理
时间:2010-09-05 来源:lwglucky
把以前的对象笔记帖上来...后面多加了俩个 函数..来加深理解...
一个是ZwQueryDirectoryObject来检测隐藏驱动
一个是让ZwQueryDirectoryObject检测不了的...代码比较简单..先看前面的理论再去理解后面的函数...应该可以编译出来的..否则那个
对象名字得到对象体
太长了...理论部分XX掉.
到此为止应该可以完了...... 当然还有很多内容... 但对象的总体应该有个概况
下面是用来检测隐藏驱动的...VOID Scan_Object_Directory()
{
UNICODE_STRING ObjectName;
OBJECT_ATTRIBUTES oa ;
HANDLE OpenObject;
NTSTATUS status, ntStatus;
ULONG count=0;
PDIRECTORY_BASIC_INFORMATION pBuffer2, pBuffer=NULL;
ULONG uLength = 0x800;
ULONG uContext = 0;
ULONG uResult = 0;
WCHAR ObjName[256]=L"\\Driver\\";
RtlInitUnicodeString(&ObjectName, L"\\Driver");
InitializeObjectAttributes(&oa,&ObjectName, OBJ_CASE_INSENSITIVE,
NULL, NULL);
status= ZwOpenDirectoryObject(&OpenObject,DIRECTORY_QUERY,&oa);
if(!NT_SUCCESS(status))
{
DbgPrint("failed\n");
return;
}
do
{
if (pBuffer)
ExFreePool(pBuffer);
uLength *= 2;
pBuffer=(PDIRECTORY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool
,uLength);
ntStatus = ZwQueryDirectoryObject(OpenObject, pBuffer,
uLength, FALSE, TRUE, &uContext, &uResult);
} while(ntStatus == STATUS_MORE_ENTRIES || ntStatus ==
STATUS_BUFFER_TOO_SMALL);
if (ntStatus==STATUS_SUCCESS)
{
pBuffer2=pBuffer;
while (pBuffer2->ObjectName.Length!=0&&pBuffer2-
>ObjectTypeName.Length!=0)
{
wcscat(ObjName,pBuffer2->ObjectName.Buffer);
GetDriverObjByName(ObjName); //自己实现吧..到这里有ObjName就够了
pBuffer2++;
count++;
RtlZeroMemory(ObjName,256);
wcscpy(ObjName,L"\\Driver\\");
}
}
DbgPrint("-----%d\n",count);
ExFreePool(pBuffer);
}
下面是断链的..
void ObDeleteObjectFromObjectDirectory(POBJECT_DIRECTORY pObjDir) //父节点 pObjDir
{
POBJECT_DIRECTORY_ENTRY pDirectoryEntry,pEntryPrev = NULL;
POBJECT_HEADER pObjectHeader;
PVOID Object;
int i;
PUNICODE_STRING unipObjectTypeName,uniHideDriveName;
POBJECT_DIRECTORY tmpObjDir,pDirectory;
pDirectory = pObjDir;
for(i = 0; i < 36; i ++) //DIR对象的对象体(BODY)是37个元素的数组。
{
pDirectoryEntry = pDirectory->HashTable; //子根目录
// DbgPrint("---0x%x\n", pDirectoryEntry);
while(pDirectoryEntry)
{
__try{
if(pDirectoryEntry)
{
Object = pDirectoryEntry->pObject ; //根目录对象
pObjectHeader = OBJECT_TO_OBJECT_HEADER( Object ); //根目录对象头
unipObjectTypeName = (PUNICODE_STRING)((*(ULONG*)((ULONG)pObjectHeader+8)+0x40));
//这里可以输出很多类型的对象,但我们关心的是Driver
//DbgPrint("--%ws 0x%x\n",unipObjectTypeName->Buffer,Object);
///////////////////////////////////////////////////////////////////////////////////////////////////////
// DKOM判断
if(wcscmp(unipObjectTypeName->Buffer,L"Driver")==0)
{
uniHideDriveName = (PUNICODE_STRING)((ULONG)Object+0x1c);
if(wcscmp(uniHideDriveName->Buffer,L"\\Driver\\NDIS")==0) //想隐藏的驱动对象
{
//也可以用wcschr..因为我实验的结果是有时候会出现 \Driver\Beep?? 之类的名字..
if (pEntryPrev) //前继有了
pEntryPrev->NextEntry = pDirectoryEntry->NextEntry; //匹配就开始断练了
}
pEntryPrev = pDirectoryEntry;
// DbgPrint(" %ws\n",uniHideDriveName->Buffer);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
if(wcscmp(unipObjectTypeName->Buffer,L"Directory")==0)
{
tmpObjDir = Object;
ObDeleteObjectFromObjectDirectory( tmpObjDir); //如果对象的类型是"Directory" 递归处理之
}
}
}__except(EXCEPTION_EXECUTE_HANDLER)
{
;
}
pDirectoryEntry = pDirectoryEntry->NextEntry;
}
}
}