隐藏驱动完整攻略(基础篇)
来源:互联网 发布:钉钉办公软件 编辑:程序博客网 时间:2024/06/02 14:38
完整介绍隐藏驱动的方法,部分内容属于冷饭热炒,炒一炒比较好消化~~
先说一下,以下数据和结构信息来自Windbg+WinXP SP2
一、从PsLoadedModuleList消失
PsLoadedModuleList是系统中一个用于连接所有已加载驱动的双向链表(LIST_ENTRY结构)。每一个驱动的DriverObject->DriverSection其实是一个指向LDR_DATA_TABLE_ENTRY结构的指针,以Beep为例,如下:
lkd> dt _DRIVER_OBJECT 871a5b80
nt!_DRIVER_OBJECT
+0x000 Type : 4
...
+0x014 DriverSection : 0x897a0458
lkd> dt _LDR_DATA_TABLE_ENTRY 0x897a0458
nt!_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 "\SystemRoot\System32\Drivers\Beep.SYS"
+0x02c BaseDllName : _UNICODE_STRING"Beep.SYS"
这个结构和PEB->Ldr中用于记录进程已加载DLL的结构是一样的,不过驱动中仅InLoadOrderLinks有效,把这个结点从双链表中移除就可以了。
此方法仅对ZwQuerySystemInformation(SystemModuleInformation)有效
二、从\Driver对象目录消失
从PsLoadedModuleList消失以后,我们用WinObj或类似的工具仍然可以看到\Driver\DriverName这样一个对象,要隐藏自身也必须从这里消失,这里需要一些Windows对象管理的知识,关于Windows对象管理的知识请参考《Windows内核的分析(对象管理器)译自gloomy的文章,由董岩 译》等等,这里不多说。\Driver是一个对象目录,所有的DriverObject都放在此目录下面。要操作该目录,首先我们要得到"\Driver"这个对象目录的地址,可以用ObOpenObjectByName直接打开得到,或者以如下方式取到:
lkd> dt _OBJECT_HEADER 871a5b68
nt!_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 0xe156e030
nt!_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算法如下:
//计算对象名的Hash
ULONG GetObjectHashByName(PWCHAR ObjectName)
{
ULONG HashIndex=0;
ULONG WcharLength;
ULONG Wchar;
WcharLength=wcslen(ObjectName);
while (WcharLength--) {
Wchar = *ObjectName++;
HashIndex += (HashIndex << 1) + (HashIndex >> 1);
if (Wchar < 'a') {
HashIndex += Wchar;
} else if (Wchar > 'z') {
HashIndex += RtlUpcaseUnicodeChar( (WCHAR)Wchar );
} else {
HashIndex += (Wchar - ('a'-'A'));
}
}
HashIndex %= NUMBER_HASH_BUCKETS; //NUMBER_HASH_BUCKETS是个宏,值为37
return HashIndex;
}
Hash表中的每一个结点都是一个OBJECT_DIRECTORY_ENTRY结构,该结构的ChainLink域链向下一个Hash值相同的结点,构成了单链表,链表头就是ObjectDirectory.HashBuckets[对象的Hash值],而对象则保存在Object域中。
lkd> dt _OBJECT_DIRECTORY_ENTRY 0xe169b7c8
nt!_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为好~~
三、从TypeList消失
TypeList也是一个双向链表(LIST_ENTRY)结构,这个链表的头在哪儿呢?在OBJECT_TYPE的TypeList域:
lkd> dt _OBJECT_TYPE 89e60ca0
nt!_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 871a5b68
nt!_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链断掉,隐藏工作就又前进了一大步了~~
- 隐藏驱动完整攻略(基础篇)
- 隐藏驱动完整攻略(基础篇)
- 隐藏驱动完整攻略(猥琐篇)
- 隐藏驱动完整攻略(猥琐篇)
- Asp学习者完整攻略之三:操作SQL:SQL基础:
- 金庸群侠传之武林浩荡1.7全隐藏完整攻略流程(图文)
- C# Datagridview完整攻略
- C# Datagridview完整攻略
- C# Datagridview完整攻略
- 驱动隐藏
- 金庸群侠转2完整攻略(Flash)
- J2EE中文乱码完整攻略
- 买台式整机完整攻略
- 完整海购攻略教程
- CentOS 安装mediawiki完整攻略
- Pomelo环境搭建完整攻略
- BOOST 线程完全攻略 - 基础篇
- BOOST 线程完全攻略 - 基础篇
- tree控件----展开树item的函数----CTreeCtrl::Expand
- JAVA自动生成sql结果到excel,并以附件方式发送到指定邮箱
- NHibernate学习资源
- python 基于XML生成静态网页的简单实现
- MeeGo开发中一些小技巧
- 隐藏驱动完整攻略(基础篇)
- PHP5最新中文版CHM手册
- Microsoft Word Documents from ASP.NET
- 常见调试器
- shell字符串操作方法,以及实例
- WGET的使用方法与技巧
- 隐藏驱动完整攻略(猥琐篇)
- 从log文件看MeeGo播放器性能
- 用户投资SOA四大顾虑