好久没来了!最近在整理以前的一些笔记,也希望把以前学过但没记下来的东西补全,于是这是新一轮复习的第一篇。
一、一些概念
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);
}
}
}