复习:windows对象管理(1)内核对象组织结构

好久没来了!最近在整理以前的一些笔记,也希望把以前学过但没记下来的东西补全,于是这是新一轮复习的第一篇。

一、一些概念

xp下内核对象的布局结构如下(由低到高):


object quota info

object handle info

object name info

object creater info

OBJECT_HEADER

object

对象在内核中以哈希树的形式存储,根目录有37个槽,以下是根目录的打印输出


0: kd> !object \
Object: e1009030  Type: (863e9348) Directory
    ObjectHeader: e1009018 (old version)
    HandleCount: 0  PointerCount: 34
    Directory Object: 00000000  Name: \
    128 symbolic links snapped through this directory


    Hash Address  Type          Name
    ---- -------  ----          ----
     00  e100a628 Directory     ArcName
         863caf18 Device        Ntfs
     01  e1952ef8 Port          SeLsaCommandPort
     03  e101a490 Key           \REGISTRY
     09  e1447310 Directory     NLS
     10  e1009260 SymbolicLink  DosDevices
         8623a0c8 FilterConnectionPort Safe360Port
     13  e15732c0 Port          SeRmCommandPort
     14  e19d5850 Port          LsaAuthenticationPort
         863c9030 Device        Dfs
         86280b78 Event         LanmanServerAnnounceEvent
     16  e13234c8 Directory     Driver
     19  e1011700 Directory     Device
     20  e1632a08 Directory     Windows
     21  e163c370 Directory     Sessions
         860fe188 Event         SAM_SERVICE_STARTED
     22  e1422428 Directory     RPC Control
         e14cda40 Port          SmApiPort
     23  e14cb998 Directory     BaseNamedObjects
         e1000200 Directory     KernelObjects
     24  e13045e0 Directory     FileSystem
         e1008b50 Directory     GLOBAL??
     26  e1009b50 Directory     ObjectTypes
     27  e1adebf8 Port          ErrorLogPort
         e100c118 Directory     Security
     31  e10138b8 SymbolicLink  SystemRoot
         861e6208 Device        Cdfs
     32  e10010d8 Directory     Callback
     33  860bd708 Event         SeLsaInitEvent
         860be4a8 Event         UniqueSessionIdEvent
     35  e15021f0 Directory     KnownDlls


内核自己定义的对象类型也放在对象目录中,打印如下


0: kd> !object \ObjectTypes
Object: e1009b50  Type: (863e9348) Directory
    ObjectHeader: e1009b38 (old version)
    HandleCount: 0  PointerCount: 26
    Directory Object: e1009030  Name: ObjectTypes


    Hash Address  Type          Name
    ---- -------  ----          ----
     00  863e9348 Type          Directory
     01  863b2368 Type          Mutant
         863b5ca0 Type          Thread
     03  863c7738 Type          FilterCommunicationPort
     05  8639e380 Type          Controller
     06  85da9770 Type          360Type
     07  863b1ad0 Type          Profile
         863b2708 Type          Event
         863e9518 Type          Type
     09  863e9178 Type          SymbolicLink
         863b1248 Type          Section
         863b2538 Type          EventPair
     10  863b1560 Type          Desktop
     11  863b1ca0 Type          Timer
     12  863e7ad0 Type          File
         863b1730 Type          WindowStation
     16  863e7e70 Type          Driver
     18  863e1d78 Type          WmiGuid
         863b1900 Type          KeyedEvent
     19  863e7040 Type          Device
         863b5040 Type          Token
     20  863b5298 Type          DebugObject
     21  863e7ca0 Type          IoCompletion
     22  863b5e70 Type          Process
     24  8639e550 Type          Adapter
     26  863ab420 Type          Key
     28  863b5ad0 Type          Job
     31  8639ee70 Type          WaitablePort
         8639e040 Type          Port
     32  863b1040 Type          Callback
     33  863c7908 Type          FilterConnectionPort
     34  863b1e70 Type          Semaphore

对象目录结构如下

0: kd> dt nt!_OBJECT_DIRECTORY
   +0x000 HashBuckets      : [37] Ptr32 _OBJECT_DIRECTORY_ENTRY
   +0x094 Lock             : _EX_PUSH_LOCK
   +0x098 DeviceMap        : Ptr32 _DEVICE_MAP
   +0x09c SessionId        : Uint4B
   +0x0a0 Reserved         : Uint2B
   +0x0a2 SymbolicLinkUsageCount : Uint2B

entry 结构如下

0: kd> dt _OBJECT_DIRECTORY_ENTRY
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : Ptr32 _OBJECT_DIRECTORY_ENTRY
   +0x004 Object           : Ptr32 Void


3.其他内容

这里仅仅罗列一些关键词,以后逐渐补完

object type链表

object查询解析(parse、open等)

object权限检查

句柄与句柄表

二、一些应用

1.可以通过以下代码获得“对象目录”这个对象的对象类型。

	status = ObReferenceObjectByHandle(hRootDir,
		DIRECTORY_ALL_ACCESS,
		NULL,
		KernelMode,
		(PVOID*)&g_pRootObj,
		NULL);
	POBJECT_HEADER poh =  (POBJECT_HEADER)(OBJ_TO_HEAD(g_pRootObj));
	g_pDirObjectType = poh->Type;

2.遍历对象树,递归搜索驱动对象(兼容xp~win7)

VOID SearchDriverObjByTree(ULONG dir)
{
	//nt!_OBJECT_DIRECTORY
	//	+0x000 HashBuckets      : [37] 0xe10003b8 _OBJECT_DIRECTORY_ENTRY
	//	+0x094 Lock             : _EX_PUSH_LOCK
	//	+0x098 DeviceMap        : (null) 
	//	+0x09c SessionId        : 0xffffffff
	//	+0x0a0 Reserved         : 0
	//	+0x0a2 SymbolicLinkUsageCount : 0x76

	for (int i=0;i<37;i++)
	{
		ULONG dir_entry = *(PULONG)(dir+i*4);
		if (0!=dir_entry)
		{
			//nt!_OBJECT_DIRECTORY_ENTRY
			//	+0x000 ChainLink        : (null) 
			//	+0x004 Object           : 0xe1803da8 
			do 
			{//chainlink 遍历
				ULONG pObject =  *(ULONG*)(dir_entry+4);
				if (pObject!=0)
				{
					POBJECT_HEADER poh = (POBJECT_HEADER)((ULONG)pObject-0x18);
					if (g_dwBuildNumber <7600)
					{
						if (poh->Type == *IoDriverObjectType)
						{
							if (pObject>g_MaxDriObjAddr)
							{
								//记录最大的内核对象地址 作为内存搜索的参考
								g_MaxDriObjAddr = pObject;
							}
							IsScanedDri((PDRIVER_OBJECT)pObject);
						}
						else if (poh->Type == (PVOID)*IoDeviceObjectType)
						{ 
							PDEVICE_OBJECT pdev = (PDEVICE_OBJECT)pObject;
							do 
							{
								IsScanedDri((PDRIVER_OBJECT)pdev->DriverObject);
								pdev = pdev->AttachedDevice;
							} while (pdev!=0);
						}
						else if (poh->Type == (PVOID)g_pDirObjectType)
						{
							SearchDriverObjByTree(pObject);
						}
					}
					else 
					{
						BYTE key = *(PBYTE)((ULONG)pObject-0xc);
						switch(key)
						{
						case OB_DIR_TYPE_INDEX:
								SearchDriverObjByTree(pObject);
								break;
						case OB_DRIVER_TYPE_INDEX:
							{
								if (pObject>g_MaxDriObjAddr)
								{
									//记录最大的内核对象地址 作为内存搜索的参考
									g_MaxDriObjAddr = pObject;
								}
								IsScanedDri((PDRIVER_OBJECT)pObject);
								break;
							}
						case OB_DEVICE_TYPE_INDEX:
							{
								PDEVICE_OBJECT pdev = (PDEVICE_OBJECT)pObject;
								do 
								{
									IsScanedDri((PDRIVER_OBJECT)pdev->DriverObject);
									pdev = pdev->AttachedDevice;
								} while (pdev!=0);
								break;
							}
						default:
							break;
						}

					}
					
				}
				dir_entry = *(PULONG)dir_entry;
			} while (0!=dir_entry);
		}

	}

}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows内核对象是系统提供给用户模式下代码与内核模式下代码进行交互的基本接口。它们是一种管理资源的机制,用于在操作系统内部进行进程间通信、同步线程、共享数据等操作。 Windows内核对象可以通过使用Process Explorer来查看其创建情况,并且可以使用对象句柄继承来实现进程边界共享内核对象。此外,lsobj工具可以使用NtQueryDirectoryObject()函数来列出Windows内核对象名称空间中的所有可见对象。它最初具有与WinObj相同的功能,可以在无头服务器和服务器孤岛上运行。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Windows核心编程(三)内核对象](https://blog.csdn.net/jzz5072/article/details/112848284)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [lsobj:列出Windows内核对象名称空间(命令行WinObj)中的所有可见对象](https://download.csdn.net/download/weixin_42117082/18786082)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值