
隐藏驱动完整攻略(基础篇).pdf
6页隐藏驱动完整攻略(基础篇)学习各种高级外挂制作技术,马上去百度搜索“魔鬼作坊“,点击第一个站进入, 快速成为做挂达人完整介绍隐藏驱动的方法,部分内容属于冷饭热炒,炒一炒比较好消化~~先说一下,以下数据和结构信息来自 Windbg+WinXP SP2一、从一、从 PsLoadedModuleListPsLoadedModuleListPsLoadedModuleListPsLoadedModuleList 消失消失PsLoadedModuleList 是系统中一个用于连接所有已加载驱动的双向链表(LIST_ENTRY 结构) 每一个驱动的 DriverObject->DriverSection 其实是一个指向 LDR_DATA_TABLE_ENTRY 结构的指针,以 Beep 为例,如下:lkd> dt _DRIVER_OBJECT 871a5b80nt!_DRIVER_OBJECT+0x000 Type: 4...+0x014 DriverSection: 0x897a0458lkd> dt _LDR_DATA_TABLE_ENTRY 0x897a0458nt!_LDR_DATA_TABLE_ENTRY+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x871ecb48 - 0x871b2a28 ]//仅 LoadOrderLinks 有效+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]+0x018 DllBase: 0xbadd2000+0x01c EntryPoint: 0xbadd266c+0x020 SizeOfImage: 0x2000+0x024 FullDllName: _UNICODE_STRING+0x02c BaseDllName: _UNICODE_STRING这个结构和 PEB->Ldr 中用于记录进程已加载 DLL 的结构是一样的,不过驱动中仅 InLoadOrderLinks 有效,把这个结点从双链表中移除就可以了。
此方法仅对 ZwQuerySystemInformation(SystemModuleInformation)有效二、从二、从\Driver\Driver\Driver\Driver对象目录消失对象目录消失从 PsLoadedModuleList 消失以后,我们用 WinObj 或类似的工具仍然可以看到\Driver\DriverName 这样一个对象,要隐藏自身也必须从这里消失,这里需要一些 Windows 对象管理的知识,关于 Windows 对象管理的知识请参考《Windows 内核的分析(对象管理器)译自 gloomy 的文章,由董岩 译》等等,这里不多说\Driver 是一个对象目录,所有的 DriverObject 都放在此目录下面要操作该目录,首先我们要得到“\Driver“这个对象目录的地址,可以用 ObOpenObjectByName 直接打开得到,或者以如下方式取到:lkd> dt _OBJECT_HEADER 871a5b68nt!_OBJECT_HEADER+0x000 PointerCount: 3+0x004 HandleCount: 0+0x004 NextToFree: (null)+0x008 Type: 0x89e60ca0 _OBJECT_TYPE+0x00c NameInfoOffset: 0x10 '' //对象头名称距对象头的偏移lkd> dt _OBJECT_HEADER_NAME_INFO 871a5b68-0x10 //对象头名称信息在对象头之前,减去偏移就可到达nt!_OBJECT_HEADER_NAME_INFO+0x000 Directory: 0xe156e030 _OBJECT_DIRECTORY //这就是我们要找的ObjectDirectory+0x004 Name: _UNICODE_STRING “Beep“+0x00c QueryReferences: 1而对象目录是一个 OBJECT_DIRECTORY 结构,如下:lkd> dt _OBJECT_DIRECTORY 0xe156e030nt!_OBJECT_DIRECTORY+0x000 HashBuckets: [37] 0xe169b7c8 _OBJECT_DIRECTORY_ENTRY //Hash表+0x094 Lock: _EX_PUSH_LOCK+0x098 DeviceMap: (null)+0x09c SessionId: 0xffffffff+0x0a0 Reserved: 0+0x0a2 SymbolicLinkUsageCount : 0对象在对象目录中是以一个Hash表的方式存储的(如果不清楚Hash表的结构和用法请先补一补数据结构的知识),Hash 算法如下://计算对象名的 HashULONG GetObjectHashByName(PWCHAR ObjectName){ULONG HashIndex=0;ULONG WcharLength;ULONG Wchar;WcharLength=wcslen(ObjectName);while (WcharLength--) {Wchar = *ObjectName++;HashIndex += (HashIndex > 1);if (Wchar 'z') {HashIndex += RtlUpcaseUnicodeChar( (WCHAR)Wchar );} else {HashIndex += (Wchar - ('a'-'A'));}}HashIndex %= NUMBER_HASH_BUCKETS; //NUMBER_HASH_BUCKETS 是个宏, 值为37return HashIndex;}Hash 表中的每一个结点都是一个 OBJECT_DIRECTORY_ENTRY 结构, 该结构的 ChainLink 域链向下一个 Hash 值相同的结点,构成了单链表,链表头就是 ObjectDirectory.HashBuckets[对象的 Hash 值],而对象则保存在 Object 域中。
lkd> dt _OBJECT_DIRECTORY_ENTRY 0xe169b7c8nt!_OBJECT_DIRECTORY_ENTRY+0x000 ChainLink: 0xe101dda8 _OBJECT_DIRECTORY_ENTRY+0x004 Object: 0x871a5b80 //注意看,这就是我们要找的 Beep对象,其 Hash 为0遍历此链表,找到我们要隐藏的驱动的 DriverObject(可参考 ObpLookupObjectName 函数的实现过程),从链表中移除就可以了当然, 从链表中移除结点时需要根据该结点在链表头或中间进行分别处理, 这个仍然是数据结构的知识~~位于链表中间很容易处理,位于链表头的话要注意移除目标 Object 之后更新 ObjectDirectory.HashBuckets[对象的 Hash 值],也就是链表头,否则你会蓝得很难看~~DeviceObject 同法处理,不过这样处理完后,就不能以常规手段打开你的 Device 来 DeviceIoControl 了(系统找不到它,囧),所以我们还是不要 DeviceObject 为好~~三、从三、从 TypeListTypeListTypeListTypeList 消失消失TypeList 也是一个双向链表(LIST_ENTRY)结构,这个链表的头在哪儿呢?在 OBJECT_TYPE 的 TypeList 域:lkd> dt _OBJECT_TYPE 89e60ca0nt!_OBJECT_TYPE+0x000 Mutex: _ERESOURCE+0x038 TypeList: _LIST_ENTRY [ 0x89e60cd8 - 0x89e60cd8 ]//就是这个 LIST+0x040 Name: _UNICODE_STRING “Driver“ //DriverType+0x048 DefaultObject: 0x80562e20可以看到,上面的 TypeList 链表是空的,并无任何内容,因为 TypeList 并不总是有效的~~仅当 NtGlobalFlag 设置了 MaintainTypeList标志(可以使用 Windbg 自带的 Global Flags 工具查看和修改),系统在创建 Object 之后,才会将其插入 ObjectType->TypeList 链表。
要知道该标志是否有效,可以检查 ObjectHeader->Flags 标志的 OB_FLAG_CREATOR_INFO位是否有效在设置该标志之后, 对象头前面的可变域会增加一个_OBJECT_HEADER_CREATOR_INFO 结构,该结构中有一个 LIST_ENTRY 域连接在前面的 ObjectType->TypeList 链表上在 Object 之前就是 OBJECT_HEADER 结构,而 OBJECT_HEADER 结构中的几个 Offset的值则表明该对象头前面的可变头部分的信息,为0则表示对应的结构不存在,不为0的则表示该结构存在,这个值也是相应的结构信息距 ObjectHeader 的偏移(在 ObjectHeader 之前)对象头信息如下:lkd> dt _OBJECT_HEADER 871a5b68nt!_OBJECT_HEADER+0x000 PointerCount: 3+0x004 HandleCount: 0+0x004 NextToFree: (null)+0x008 Type: 0x89e60ca0 _OBJECT_TYPE+0x00c NameInfoOffset: 0x10 '' //在对象头之前偏移0x10处,是 NameInfo信息+0x00d HandleInfoOffset : 0 '' //无效+0x00e QuotaInfoOffset: 0 '' //无效设置 Maintain TypeList 标志之后, 因为 OBJECT_HEADER_NAME_INFO 之后增加了一个OBJECT_HEADER_CREATOR_INFO 结构,所以你看到的 NameInfoOffset 将会是0x20.lkd> dt _OBJECT_HEADER_CREATOR_INFO 8995fae8-0x18-0x20+0x10 //可变头之创建信息nt!_OBJECT_HEADER_CREATOR_INFO+0x000 TypeList: _LIST_ENTRY [ 0x89968df8 - 0x8995ff10 ] //这个链要断掉+0x008 CreatorUniqueProcess : 0x00000004 //对象的创建者,对于驱动而言,这里总是 System,抹掉+0x00c CreatorBackTraceIndex : 0+0x00e Reserved: 0如上面所示,8995fae8是 Object,减去0x18得到 ObjectHeader,再减去此时的 NameInfoOffset,也就是0x20,就得到了 OBJECT_HEADER_NAME_INFO 结构,再加上 OBJECT_HEADER_NAME_INFO 结构的大小0x10,就是我们要找的 OBJECT_HEADER_CREATOR_INFO 结构了。
找到目标 DriverObject 的 OBJECT_HEADER_CREATOR_INFO 结构之后, 把这个 TypeList 链断掉,隐藏工作就又前进了一大步了~~基础篇里说的那些东西搞完以后,任何正常的位置都找不。












