﻿<?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>C++博客-free2000fly 的自留地</title><link>http://www.cppblog.com/free2000fly/</link><description>关于 c/c++, asm 等的 dashs </description><language>zh-cn</language><lastBuildDate>Sun, 06 Jul 2008 06:25:46 GMT</lastBuildDate><pubDate>Sun, 06 Jul 2008 06:25:46 GMT</pubDate><ttl>60</ttl><item><title>将 ATL 的一个顽固 Bug 修正了</title><link>http://www.cppblog.com/free2000fly/archive/2008/07/02/55148.html</link><dc:creator>free2000fly</dc:creator><author>free2000fly</author><pubDate>Wed, 02 Jul 2008 07:44:00 GMT</pubDate><guid>http://www.cppblog.com/free2000fly/archive/2008/07/02/55148.html</guid><wfw:comment>http://www.cppblog.com/free2000fly/comments/55148.html</wfw:comment><comments>http://www.cppblog.com/free2000fly/archive/2008/07/02/55148.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/free2000fly/comments/commentRss/55148.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/free2000fly/services/trackbacks/55148.html</trackback:ping><description><![CDATA[用 VC6&nbsp;和 VC71 装载的&nbsp;ATL 开发软件的人都知道, 当我们定义了一个自销毁窗口时, 一般在 ATL 窗口类的 <br><br>virtual void OnFinalMessage(HWND ){...} <br><br>函数内加一句 <br><br>delete this; <br><br>然后就返回了. 但是气人的是, 每次当我们返回后, 总有一个地方断言失败, <br><br>ATLASSERT(pThis-&gt;m_pCurrentMsg == &amp;msg); <br><br>Google 了许久, 没有满意的解决方案, 包括微软的方案<br><br><a href="http://support.microsoft.com/kb/202110">http://support.microsoft.com/kb/202110 </a><br><br>也不好, 自己想尽办法还是 "山重水复疑无路", 后来突然灵光突现, 彻底解决, 就一个函数调用而已: IsWindow(...). 现在, 终极解决方案是这样的:<br>搜索 atlwin.h 文件内的 "ATLASSERT(pThis-&gt;m_pCurrentMsg == &amp;msg);" 字符串 (在文件内有 3 处), 将其原始内容 <br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; PADDING-LEFT: 4px; FONT-SIZE: 13px; BORDER-TOP: #cccccc 1px solid; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;LRESULT&nbsp;lRes;<br>&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;bRet&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;pThis</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">ProcessWindowMessage(pThis</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">m_hWnd,&nbsp;uMsg,&nbsp;wParam,&nbsp;lParam,&nbsp;lRes,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;restore&nbsp;saved&nbsp;value&nbsp;for&nbsp;the&nbsp;current&nbsp;message</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ATLASSERT(pThis</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">m_pCurrentMsg&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">msg);<br>&nbsp;&nbsp;&nbsp;&nbsp;pThis</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">m_pCurrentMsg&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;pOldMsg;<br></span></div>
改成<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; PADDING-LEFT: 4px; FONT-SIZE: 13px; BORDER-TOP: #cccccc 1px solid; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;LRESULT&nbsp;lRes;<br>&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;bRet&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;pThis</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">ProcessWindowMessage(pThis</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">m_hWnd,&nbsp;uMsg,&nbsp;wParam,&nbsp;lParam,&nbsp;lRes,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br><span style="COLOR: #ff0808">&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style="COLOR: #ff0808">if(FALSE&nbsp;==&nbsp;::IsWindow(pThis-&gt;m_hWnd))&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return</span><span style="COLOR: #000000"><span style="COLOR: #ff0808">&nbsp;lRes; // 在 CDialogImplBaseT 类里是 return FALSE;&nbsp; 特此说明 </span><br style="COLOR: #ff0808"><span style="COLOR: #ff0808">&nbsp;&nbsp;&nbsp;&nbsp;}</span><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;restore&nbsp;saved&nbsp;value&nbsp;for&nbsp;the&nbsp;current&nbsp;message</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ATLASSERT(pThis</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">m_pCurrentMsg&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">msg);<br>&nbsp;&nbsp;&nbsp;&nbsp;pThis</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">m_pCurrentMsg&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;pOldMsg;<br></span></div>
其中红色的代码为我们的修正代码. 万事大吉. 再也不会出现断言失败了. <br><br>道理是这样的: 如果 pThis 对象被删除了的话, 那么 pThis 本身和其成员变量 m_hWnd 都将是一个无效值, 那么后续的操作将毫无意义. 因此直接返回, 不用废话. <br><br>真是简单的思路直指问题的核心啊. <br><br>
<img src ="http://www.cppblog.com/free2000fly/aggbug/55148.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/free2000fly/" target="_blank">free2000fly</a> 2008-07-02 15:44 <a href="http://www.cppblog.com/free2000fly/archive/2008/07/02/55148.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to launch a program to the WinSta0\\Winlogon desktop from service (转帖)</title><link>http://www.cppblog.com/free2000fly/archive/2008/06/28/54859.html</link><dc:creator>free2000fly</dc:creator><author>free2000fly</author><pubDate>Sat, 28 Jun 2008 00:22:00 GMT</pubDate><guid>http://www.cppblog.com/free2000fly/archive/2008/06/28/54859.html</guid><wfw:comment>http://www.cppblog.com/free2000fly/comments/54859.html</wfw:comment><comments>http://www.cppblog.com/free2000fly/archive/2008/06/28/54859.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/free2000fly/comments/commentRss/54859.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/free2000fly/services/trackbacks/54859.html</trackback:ping><description><![CDATA[<p>原始链接: <a href="https://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3223434&amp;SiteID=1">https://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3223434&amp;SiteID=1</a> </p>
<p><span>Hi Guys,<br><br>My goal is to run a program before user even log on to system in vista. Here are couple of links i have already went through. These codes are working fine when ever we are dealing with WinSta0\\default desktop when user is log on but my requirements are different.<br><br>http://www.codeproject.com/KB/vista-security/VistaSessions.aspx?fid=406624&amp;sort=Position&amp;noise=3&amp;view=Quick&amp;mpp=50&amp;df=1<br><br>http://www.uvnc.com/vista/<br><br>http://www.codeproject.com/KB/vista-security/VistaSessionsC_.aspx<br><br>Steps that wosks fine<br>-------------------------------<br><span id=intelliTXT>
<ol>
    <li>Get the Active Console SessionId using <code>WTSGetActiveConsoleSessionId</code>
    <li>Since I need to launch the application under a system account, I use the token from Winlogon, since Winlogon runs under the system account. So I obtain the process ID of Winlogon and Duplicate the token.
    <li>Then I make sure I sent the startupinfo parameter <code>lpDesktop </code>to <em>winsta0\Default</em> since I need to launch my process there.
    <li>Then I use <code>CreateProcessAsUser </code>with Winlogon's duplicate token to launch my process into session 1.
    <li>That's all. I am done. </li>
</ol>
</span>I got this working on Vista but I would like to launch a progrma to the WinSta0\\Winlogon desktop. Anyone have any ideas? When I change the desktop to WinSta0\\Winlogon the application does not appear on the logon screen. However, when I run the program on XP it works.<br><br>Vista must have the Winlogon Desktop permissions set differently, I added "SeTcbPrivilege" but that did no good. Also, if I look at taskmgr I see the program started along with CreateProcessAsUser not returning any errors. It appears to work, just cannot see the application on the WinSta0\\Winlogon desktop. Anyone have any ideas?</span>
<p>&nbsp;</p>
<p>==================================================================================================</p>
<p><span>It works! with vista !! <br><br>
<div style="MARGIN-LEFT: 40px">1. WTSGetActiveConsoleSessionId(); <br>2. WTSQueryUserToken() for winlogon.exe winlogon pid<br>3. DuplicateTokenEx ()<br>4. AdjustTokenPrivileges ()<br>5. CreateProcessAsUser () <span id=_ctl0_MainContent_PostFlatView><span><span><span id=intelliTXT><code>lpDesktop </code>to <em>Winsta0\Winlogon</em> <br></span></span></span></span><br>Fire the executable via taskscheduler (schtasks.exe) with SYSTEM priveleges.<br><br><br>Muhahahaha <img src="http://forums.microsoft.com/MSDN/WebResource.axd?d=NySzF1eivP_rMoc50GQJzcvS4MHMOEKwYrCIgDtzuzlw7GsNki3H_INlfYaLgkxF2WImMhtQIz9Re7PuctA64ZVF_xzUNgBmL8gde9iPLu41&amp;amp;t=633337194230757564">, and then if you dont see youre app in the winlogon desktop, try hitting ALT+TAB .... in the winlogon desktop.<br><br>I hope microsoft keeps this entry point for showing things on the secure desktop, cause we use it to show the unattended installation progress, I think the secure desktop should stay accessible in future releases.<br><br>(btw, I did not test it with FUS Fast User Switching, It worked with a domain account setting, this means Fast User Switching is not enabled).<br><br><br>Much appreciated,<br><br>&nbsp;mon11.</div>
</span>
<p>&nbsp;</p>
<p>==================================================================================================</p>
<p>Fast User Switching is enabled for domain accounts in Vista by default, so that's not necessarily true.<br><br>================================================================================================== </p>
<p><span>
<p align=left>AndyCadley,<br>You are right, I tested it,&nbsp;it&nbsp;works also with FUS. </p>
</span>
<p>&nbsp;</p>
<p>&nbsp;其他连接: <br></p>
<p>[1]&nbsp; <a href="http://blogs.msdn.com/ntdebugging/archive/2007/01/04/desktop-heap-overview.aspx">http://blogs.msdn.com/ntdebugging/archive/2007/01/04/desktop-heap-overview.aspx</a> <br></p>
<p>[2]&nbsp; <a href="http://blogs.technet.com/askperf/archive/2007/07/24/sessions-desktops-and-windows-stations.aspx">http://blogs.technet.com/askperf/archive/2007/07/24/sessions-desktops-and-windows-stations.aspx</a> <br><br></p><img src ="http://www.cppblog.com/free2000fly/aggbug/54859.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/free2000fly/" target="_blank">free2000fly</a> 2008-06-28 08:22 <a href="http://www.cppblog.com/free2000fly/archive/2008/06/28/54859.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>也写了一个自删除程序, 采用远程线程注入技术. </title><link>http://www.cppblog.com/free2000fly/archive/2008/06/21/54247.html</link><dc:creator>free2000fly</dc:creator><author>free2000fly</author><pubDate>Sat, 21 Jun 2008 14:24:00 GMT</pubDate><guid>http://www.cppblog.com/free2000fly/archive/2008/06/21/54247.html</guid><wfw:comment>http://www.cppblog.com/free2000fly/comments/54247.html</wfw:comment><comments>http://www.cppblog.com/free2000fly/archive/2008/06/21/54247.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/free2000fly/comments/commentRss/54247.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/free2000fly/services/trackbacks/54247.html</trackback:ping><description><![CDATA[有点新意的就是, 在线程函数里调用 VirtualFree
函数时, 不是用 call 指令, 而是 jmp, 这样, 当 VirtualFree 函数返回后, <br>就会直接进入到 ExitThread 函数, 因为此前已经将这个函数的地址压入栈了. <br><br>我们知道, call 指令其实就是两个操作: <br>&nbsp; 1. 将 call 指令返回后的紧接着的下一条指令的地址压栈, <br>&nbsp; 2. 跳转到 call 指令代表的函数的首地址. <br><br>函数执行完毕后, <br>&nbsp; 1. ret 指令就将从栈上读取返回地址, <br>&nbsp; 2. 跳转到那个地址继续执行, <br><br>我们其实是在这里人为的将其执行流程给改了. 我们这么做的意图很负责任: 释放这块指令所处的内存, 避免内存泄漏, <br>因为注入代码的进程已经退出, 没有机会清理这块内存, 咱们就自力更生了. <br>这么干也很安全, 因为  ExitThread
不会返回了, EIP 就不会跑飞了(也就是说, 换成别的函数会造成目标进程崩溃的, 特此说明.). <br>线程函数的最后的平衡堆栈的指令和返回指令是没有意义的, 放这里是为了让反汇编器不会少见多怪.&nbsp; <br>
<br>接下来废话少说, 贴代码: <br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">windows.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">tchar.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TLHELP32.H</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stddef.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;EnablePrivilege(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hToken;<br>&nbsp;&nbsp;&nbsp;&nbsp;TOKEN_PRIVILEGES&nbsp;tp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;};<br><br>&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hProcess&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;GetCurrentProcess();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">!</span><span style="color: #000000;">OpenProcessToken(hProcess,&nbsp;TOKEN_ADJUST_PRIVILEGES&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">&nbsp;TOKEN_QUERY,<br>&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 style="color: #000000;">&amp;</span><span style="color: #000000;">hToken))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">!</span><span style="color: #000000;">LookupPrivilegeValue(NULL,&nbsp;SE_DEBUG_NAME,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">tp.Privileges[</span><span style="color: #000000;">0</span><span style="color: #000000;">].Luid))<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hToken);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;tp.PrivilegeCount&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;tp.Privileges[</span><span style="color: #000000;">0</span><span style="color: #000000;">].Attributes&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;SE_PRIVILEGE_ENABLED;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;AdjustTokenPrivileges(hToken,&nbsp;FALSE,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">tp,&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(TOKEN_PRIVILEGES),<br>&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;NULL,&nbsp;NULL);<br>&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hToken);<br>}<br><br>DWORD&nbsp;FindTarget(LPCTSTR&nbsp;lpszProcess)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;dwRet&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;PROCESSENTRY32&nbsp;pe32&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(&nbsp;PROCESSENTRY32&nbsp;)&nbsp;};<br>&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hSnapshot&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;hSnapshot&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;Process32First(hSnapshot,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">pe32);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">do</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;lstrcmpi(pe32.szExeFile,&nbsp;lpszProcess))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwRet&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pe32.th32ProcessID;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(Process32Next(hSnapshot,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">pe32));<br>&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hSnapshot);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;dwRet;<br>}<br><br></span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;DWORD&nbsp;WINAPI&nbsp;DelProc(LPVOID&nbsp;lpParam)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="color: #000000;">50</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;DeleteFileA((LPCSTR)lpParam);<br>&nbsp;&nbsp;&nbsp;&nbsp;VirtualFree((PVOID)</span><span style="color: #000000;">0x10000000</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;MEM_RELEASE);<br>&nbsp;&nbsp;&nbsp;&nbsp;ExitThread(</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>}<br><br></span><span style="color: #008000;">//</span><span style="color: #008000;">==============================================================================</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>PUCHAR&nbsp;FindDWordFromBuffer(PUCHAR&nbsp;lpBuffer,&nbsp;UINT&nbsp;cchMax,&nbsp;DWORD&nbsp;dwValue)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;PUCHAR&nbsp;pResult&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;UINT&nbsp;nIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(nIter</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;nIter</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">cchMax;&nbsp;nIter</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">(DWORD&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)(lpBuffer&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;nIter)&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;dwValue&nbsp;)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pResult&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;lpBuffer&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;nIter;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;pResult;<br>}<br><br></span><span style="color: #008000;">//</span><span style="color: #008000;">==============================================================================</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;Sleep_addr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xBBBBBBBB</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;DeleteFileA_addr&nbsp;&nbsp;&nbsp;&nbsp;0xDDDDDDDD</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;ExitThread_addr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xFFFFFFFF</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;VirtualFree_addr&nbsp;&nbsp;&nbsp;&nbsp;0xEEEEEEEE</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;_DelProc_addr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xCCCCCCCC</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;__declspec(naked)&nbsp;DWORD&nbsp;WINAPI&nbsp;_DelProc(LPVOID&nbsp;lpParam)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;__asm&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;__this_addr:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;ebp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ebp,&nbsp;esp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">0x32</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;dwMilliseconds</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,&nbsp;Sleep_addr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;ds:__imp__Sleep@4&nbsp;;&nbsp;Sleep(x)</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,&nbsp;[ebp</span><span style="color: #000000;">+</span><span style="color: #000000;">8</span><span style="color: #000000;">]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;lpFileName</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,&nbsp;DeleteFileA_addr&nbsp;&nbsp;&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;ds:__imp__DeleteFileA@4&nbsp;;&nbsp;DeleteFileA(x)</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;dwExitCode</span><span style="color: #008000;">, ExitThread 函数的参数
<br></span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;8000h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;dwFreeType</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&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 style="color: #008000;">//</span><span style="color: #008000;">&nbsp;dwSize</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,&nbsp;_DelProc_addr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;__this_addr</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;lpAddress</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,&nbsp;ExitThread_addr&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;ds:ExitThread</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; // 将 ExitThread
函数的地址压栈, 这样, </span><span style="color: #008000;">VirtualFree</span><span style="color: #000000;"> 函数返回后就会马上执行 ExitThread
函数 <br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,&nbsp;VirtualFree_addr&nbsp;&nbsp;&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;ds:__imp__VirtualFree@12&nbsp;; VirtualFree(x,x,x)</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;esp,&nbsp;ebp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; // 以下 3 条指令不会被执行的. <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ebp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">4</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br><br><br></span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;__declspec(naked)&nbsp;DWORD&nbsp;WINAPI&nbsp;_DelProc_end(LPVOID&nbsp;lpParam)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;__asm&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">4</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br><br>BOOL&nbsp;BuildRemoteThreadCode(OUT&nbsp;PUCHAR&nbsp;lpCode,&nbsp;UINT&nbsp;cchMax,&nbsp;DWORD&nbsp;dwRemoteBegin)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;UINT&nbsp;nCodeLen&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;PUCHAR&nbsp;pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwFnAddr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL</span><span style="color: #000000;">==</span><span style="color: #000000;">lpCode&nbsp;</span><span style="color: #000000;">||</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">==</span><span style="color: #000000;">cchMax)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;nCodeLen&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(PUCHAR)&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">_DelProc_end&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;(PUCHAR)&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">_DelProc;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(nCodeLen&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;cchMax)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;memcpy((</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)lpCode,&nbsp;(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">_DelProc,&nbsp;nCodeLen);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;FindDWordFromBuffer(lpCode,&nbsp;nCodeLen,&nbsp;Sleep_addr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;pIter)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwFnAddr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(DWORD)&nbsp;GetProcAddress(GetModuleHandle(_T(</span><span style="color: #000000;">"</span><span style="color: #000000;">kernel32.dll</span><span style="color: #000000;">"</span><span style="color: #000000;">)),&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Sleep</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;dwFnAddr)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">(DWORD&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;dwFnAddr;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;FindDWordFromBuffer(lpCode,&nbsp;nCodeLen,&nbsp;DeleteFileA_addr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;pIter)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwFnAddr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(DWORD)&nbsp;GetProcAddress(GetModuleHandle(_T(</span><span style="color: #000000;">"</span><span style="color: #000000;">kernel32.dll</span><span style="color: #000000;">"</span><span style="color: #000000;">)),&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">DeleteFileA</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;dwFnAddr)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">(DWORD&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;dwFnAddr;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;FindDWordFromBuffer(lpCode,&nbsp;nCodeLen,&nbsp;ExitThread_addr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;pIter)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwFnAddr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(DWORD)&nbsp;GetProcAddress(GetModuleHandle(_T(</span><span style="color: #000000;">"</span><span style="color: #000000;">kernel32.dll</span><span style="color: #000000;">"</span><span style="color: #000000;">)),&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">ExitThread</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;dwFnAddr)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">(DWORD&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;dwFnAddr;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;FindDWordFromBuffer(lpCode,&nbsp;nCodeLen,&nbsp;VirtualFree_addr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;pIter)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwFnAddr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(DWORD)&nbsp;GetProcAddress(GetModuleHandle(_T(</span><span style="color: #000000;">"</span><span style="color: #000000;">kernel32.dll</span><span style="color: #000000;">"</span><span style="color: #000000;">)),&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">VirtualFree</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;dwFnAddr)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">(DWORD&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;dwFnAddr;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;FindDWordFromBuffer(lpCode,&nbsp;nCodeLen,&nbsp;_DelProc_addr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;pIter)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwFnAddr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(DWORD)&nbsp;dwRemoteBegin;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;dwFnAddr)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">(DWORD&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;dwFnAddr;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;TRUE;<br>}<br><br><br>BOOL&nbsp;RemoteDel(DWORD&nbsp;dwProcessID,&nbsp;LPCSTR&nbsp;lpszFileName,&nbsp;DWORD&nbsp;dwTime)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;CHAR&nbsp;szFileName[MAX_PATH]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;};<br>&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hProcess&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwCodeLen&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwSize&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;LPVOID&nbsp;lpRemoteBuf&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;PUCHAR&nbsp;pBuff&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwWritten&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwID&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hThread&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;打开目标进程</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;hProcess&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;OpenProcess(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROCESS_CREATE_THREAD&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">&nbsp;PROCESS_VM_OPERATION&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">&nbsp;PROCESS_VM_WRITE,&nbsp;FALSE,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwProcessID);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;hProcess)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;GetModuleFileNameA(NULL,&nbsp;szFileName,&nbsp;MAX_PATH);<br>&nbsp;&nbsp;&nbsp;&nbsp;dwCodeLen&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(DWORD)</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">_DelProc_end&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;(DWORD)</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">_DelProc;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;dwSize&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;dwCodeLen&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(szFileName);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;lpRemoteBuf&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;VirtualAllocEx(hProcess,&nbsp;NULL,&nbsp;dwSize,&nbsp;MEM_COMMIT,&nbsp;PAGE_EXECUTE_READWRITE);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;lpRemoteBuf)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hProcess);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;pBuff&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;VirtualAlloc(NULL,&nbsp;dwSize,&nbsp;MEM_COMMIT,&nbsp;PAGE_EXECUTE_READWRITE);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;memcpy(pBuff,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">_DelProc,&nbsp;dwSize);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;BuildRemoteThreadCode(pBuff,&nbsp;dwCodeLen,&nbsp;(DWORD)lpRemoteBuf);<br>&nbsp;&nbsp;&nbsp;&nbsp;memcpy(pBuff</span><span style="color: #000000;">+</span><span style="color: #000000;">dwCodeLen,&nbsp;szFileName,&nbsp;strlen(szFileName)&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;WriteProcessMemory(hProcess,&nbsp;lpRemoteBuf,&nbsp;(LPVOID)pBuff,&nbsp;dwSize,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">dwWritten);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;hThread&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateRemoteThread(hProcess,&nbsp;NULL,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,<br>&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;(LPTHREAD_START_ROUTINE)lpRemoteBuf,<br>&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;(LPVOID)((DWORD)lpRemoteBuf&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;dwCodeLen),&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">dwID);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hThread);<br>&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hProcess);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;VirtualFree(pBuff,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;MEM_RELEASE);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;TRUE;<br>}<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;WINAPI&nbsp;_tWinMain(HINSTANCE&nbsp;hInstance,&nbsp;HINSTANCE&nbsp;hPrev,&nbsp;LPTSTR&nbsp;lpCmdLine,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nShowCmd)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;CHAR&nbsp;szMe[MAX_PATH]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;};<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwId&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;EnablePrivilege();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;GetModuleFileNameA(NULL,&nbsp;szMe,&nbsp;MAX_PATH);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;dwId&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;FindTarget(_T(</span><span style="color: #000000;">"</span><span style="color: #000000;">explorer.exe</span><span style="color: #000000;">"</span><span style="color: #000000;">));<br>&nbsp;&nbsp;&nbsp;&nbsp;RemoteDel(dwId,&nbsp;szMe,&nbsp;</span><span style="color: #000000;">50</span><span style="color: #000000;">);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>}<br></span></div>
<br>    <img src ="http://www.cppblog.com/free2000fly/aggbug/54247.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/free2000fly/" target="_blank">free2000fly</a> 2008-06-21 22:24 <a href="http://www.cppblog.com/free2000fly/archive/2008/06/21/54247.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>完成 windows nt 系列的 DLL injection 功能的开发 </title><link>http://www.cppblog.com/free2000fly/archive/2008/06/20/54095.html</link><dc:creator>free2000fly</dc:creator><author>free2000fly</author><pubDate>Fri, 20 Jun 2008 03:24:00 GMT</pubDate><guid>http://www.cppblog.com/free2000fly/archive/2008/06/20/54095.html</guid><wfw:comment>http://www.cppblog.com/free2000fly/comments/54095.html</wfw:comment><comments>http://www.cppblog.com/free2000fly/archive/2008/06/20/54095.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/free2000fly/comments/commentRss/54095.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/free2000fly/services/trackbacks/54095.html</trackback:ping><description><![CDATA[今天终于完成了往 vista 内所有 ring 3 进程的注入. 包括 csrss.exe 进程. <br><br>
主要的中心思想就是, <br>
&nbsp; &nbsp; 1. 提升本进程访问令牌, 使其有调试权限. <br>
&nbsp; &nbsp; 2. 获得本进程的当前线程的内核对象的安全描述符, 将其复制出来备用. <br>
&nbsp; &nbsp; 3. 准备远程线程的执行代码以及执行参数. 其中包括 loadlibrarya 和 RtlExitUserThread 调用, 例子嘛, 本来前一篇文章里有, 再次贴在这里方便各位看官.<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;LoadLibraryA_ADDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xDDDDDDDD&nbsp;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;RtlExitUserThread_ADDR&nbsp;&nbsp;0xEEEEEEEE&nbsp;</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;__declspec(naked)&nbsp;DWORD&nbsp;WINAPI&nbsp;ThreadDummy(LPVOID&nbsp;lpParam)&nbsp;<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;__asm&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;dword&nbsp;ptr&nbsp;[esp</span><span style="color: #000000;">+</span><span style="color: #000000;">4</span><span style="color: #000000;">]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;将传进来的线程函数的参数压栈&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,&nbsp;LoadLibraryA_ADDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;LoadLibraryA&nbsp;或&nbsp;FreeLibrary&nbsp;函数的地址&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;eax&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 style="color: #008000;">//</span><span style="color: #008000;">&nbsp;调用&nbsp;LoadLibraryA&nbsp;函数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;eax&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 style="color: #008000;">//</span><span style="color: #008000;">&nbsp;将&nbsp;RtlExitUserThread&nbsp;函数的参数压栈</span><span style="color: #008000;"><br></span><span style="color: #000000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,&nbsp;RtlExitUserThread_ADDR&nbsp;;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;RtlExitUserThread&nbsp;函数的地址&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp; eax&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 style="color: #008000;">//</span><span style="color: #008000;"> 调用 RtlExitUserThread&nbsp;函数 </span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">4</span><span style="color: #000000;">&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 style="color: #008000;">// 返回</span><span style="color: #008000;">&nbsp; </span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>}</span></div>
<br>
&nbsp; &nbsp; 4. 以第 2 步获取的安全描述符以及第 3 步准备的代码和数据作为参数调用 RtlCreateUserThread 函数, 在目标进程创建远线程. 等待执行完毕. <br>
&nbsp; &nbsp; 5. 清理第 2 步和第 3 步分配的内存. 整个过程完毕.<br><br>总结: 整个 dll injection 的探索开发历时月余, 开始看似顺利, 后期艰难困苦. 特别是那个超级变态要求: 必须注入到
csrss.exe 进程里去. 从普通的 SetWindowHookEx 和 known dll, 到 CreateRemoteThread,
最后到 NtCreateThread 以及 NtCreateThreadEx, 最后回归到 RtlCreateUserThread 函数.
中间夹杂了 DPC, APC, 以及在内核修改 knowndlls\\kernel32.dll 可执行映像 inline hook
CreateThread 函数等等等等. 从应用层到内核, 再回归应用层, 搞了个遍.<br><br>现在我可以牛逼哄哄的说一句了, Injection DLL? Just so so!!!<br><br>顺便 BS 一下 Rising, 这个宝贝杀软竟然直接 kill 掉了所有远程线程函数, 不对用户做任何通知和给用户选择的机会. 但我在内核修改任何可执行映像时, 这个宝贝却愉快的告诉我, 我的系统很安全. 再次 BS 一下. <br><br>一个小小的测试程序, 在<a href="http://www.cppblog.com/Files/free2000fly/rmtrun.zip">这里</a>下载<a>
<br><br>          </a>   <img src ="http://www.cppblog.com/free2000fly/aggbug/54095.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/free2000fly/" target="_blank">free2000fly</a> 2008-06-20 11:24 <a href="http://www.cppblog.com/free2000fly/archive/2008/06/20/54095.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Injecting Code Into Privileged Win32 Processes (转帖)</title><link>http://www.cppblog.com/free2000fly/archive/2008/06/18/53910.html</link><dc:creator>free2000fly</dc:creator><author>free2000fly</author><pubDate>Wed, 18 Jun 2008 09:31:00 GMT</pubDate><guid>http://www.cppblog.com/free2000fly/archive/2008/06/18/53910.html</guid><wfw:comment>http://www.cppblog.com/free2000fly/comments/53910.html</wfw:comment><comments>http://www.cppblog.com/free2000fly/archive/2008/06/18/53910.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/free2000fly/comments/commentRss/53910.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/free2000fly/services/trackbacks/53910.html</trackback:ping><description><![CDATA[<p>说明: 前段时间找关于向系统进程注入链接库的文章, 找到这篇, 加入收藏夹, 但后来这个连接死活打不开了. 就用 google 的 cache 功能将文章 A 在这里. 查阅方便.<br></p>
<p>For a while now, I've been searching for the optimal way to inject code into privileged Win32 processes like lsass.exe, csrss.exe, and winlogon.exe. </p>
<p>There are many functions such as the LSA and SAM exports that even users logged in with full administrative rights cannot execute <br>unless they do so under the context of one of these privileged processes. </p>
<p>There are a few tricks that I learned along the way. <br><br>First, it is necessary to adjust the token privileges of your program so that debugging (SE_PRIVILEGE_ENABLED) is allowed. </p>
<p>If you are injecting code into a lower privileged process, then this will not be needed. <br><br>Also, the target process will need to be opened with PROCESS_ALL_ACCESS rights. <br><br>Its all pretty easy on Windows 2000 and XP Service Pack 0 and 1. <br>On these systems, you can use the documented CreateRemoteThread() function, but first the code you want <br>to run in the security context of the remote process needs to exist in that process' virtual memory space. <br>You can put it there by using VirtualAllocEx() and WriteProcessMemory().</p>
<p>With XP SP2 and later (2003, Vista) some new security measures prevent the traditional CreateRemoteThread() function from working properly. <br>You should be able to open the process, allocate memory on its heap, and write data to the allocated region, <br>but when trying to invoke the remote thread, it will fail with ERROR_NOT_ENOUGH_MEMORY.</p>
<p>On Vista, I found that an author can substitute the CreateRemoteThread() call with NtCreateThreadEx() export from ntdll.dll <br>and it will allow for the thread to execute properly. This requires you to auto-detect the version of the operating system and <br>branch to this different call if on Vista. </p>
<p>Also, this is isn't really a universal solution, because NtCreateThreadEx() doesn't exist on pre-Vista sytsems. <br>So now we're stuck with using CreateRemoteThread() on 2000 and XP SP 0,1 and NtCreateThreadEx() on Vista. <br>This is already getting messy, and we still don't have a solution for XP SP2.</p>
<p>Also, the NtCreateThreadEx() function takes an undocumented structure, whose members can be initialized appropriately <br>by reversing other binaries that use the function, but it looks really ugly in source code since I don't really know what the members are for, <br>or why particular values are significant.</p>
<p>For XP SP2 I did a little debugging and found that inside CreateRemoteThread(), there is a call to ZwCreateThread() which is an export <br>from ntdll.dll. The call is made while specifying that the thread should start suspended, which it does properly, <br>however down the road still inside CreateRemoteThread() before ZwResumeThread() is called, there is a call to CsrClientCallServer() <br>which fails and eventually leads to the error message.</p>
<p>This behavior makes you wonder, if you can just call ZwCreateThread() directly, then the call to CsrClientCallServer() will be avoided <br>and the thread will execute. The problem is that ZwCreateThread() doesn't allow one to set the thread start address easily <br>(you have to configure the INITIAL_TEB members to set EIP to your start address using mostly undocumented structures and functions).</p>
<p>However, this all can be avoided by using the RtlCreateUserThread() function instead, <br>which configures and calls all the undocumented functions for you, and eventually invokes ZwCreateThread() with the result. <br>Although RtlCreateUserThread() is undocumented also, its hardly as complex as the rest and is pretty simple to use.</p>
<p>At this point, we can successfully execute remote threads into privileged processes across all target platforms, <br>but as mentioned before, its pretty messy. </p>
<p>We're using three different, largely undocumented functions and auto-detecting which one to use based on the OS version.</p>
<p>The better solution is to create a secondary program that adds a service object (your injector program) <br>to the service control manager database on the target system. Since you're administrator, which is required anyway, <br>you'll be able to add these entries and start the service. This will enable the injector program <br>to run with different access rights than normal code, and the traditional CreateRemoteThread() <br>will work properly on Windows 2000, all of XP, and 2003/Vista. </p>
<p>The API functions for adding and controlling the service are documented by MSDN and remain consistent across all of the platforms.</p>
<p>So, what is learned is that we can use a number of different functions to inject code into privileged remote processes, <br>including RtlCreateUserThread() on XP SP2, and NtCreateThreadEx() on Vista, but the optimal way is to install a temporary service <br>and allow CreateRemoteThread() to be the single API that accomplishes the task for all platforms.</p>
<p><br></p>
<p>PS: <br></p>
<p>Basically the needed access rights are identical to XP: In both OSs you need admin rights for system wide injection. However, in Vista when UAC is enabled even admin users don't have admin rights by default. So you need to right click your exe and choose "run as administrator" (as LeVuHoang has already said). Alternatively you can add a manifest to your exe which will tell Vista that your app needs admin rights. If you do that, you don't need to do the "run as admin" step, anymore. However, the end user will still have to confirm the operation. If you don't like all this you need to inject from a service (see HookProcessTermination demo).<br><br>One other thing to look for is that the hook dll needs enough NTFS rights or else it might not be injected into all processes successfully. Vista is a bit more strict there than XP was.<br><br>
</p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Inject(HWND&nbsp;hWnd,&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;strDll)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;GetWindowThreadProcessId(hWnd,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">pId);<br>&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hProcess&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;OpenProcess(PROCESS_ALL_ACCESS,&nbsp;FALSE,&nbsp;pId);<br>&nbsp;&nbsp;&nbsp;&nbsp;LPVOID&nbsp;lpRemoteAddress&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;VirtualAllocEx(hProcess,&nbsp;NULL,&nbsp;strlen(strDll),&nbsp;MEM_RESERVE</span><span style="color: #000000;">|</span><span style="color: #000000;">MEM_COMMIT,&nbsp;PAGE_READWRITE);<br>&nbsp;&nbsp;&nbsp;&nbsp;WriteProcessMemory(hProcess,&nbsp;lpRemoteAddress,&nbsp;(LPVOID)strDll,&nbsp;strlen(strDll),&nbsp;NULL);<br>&nbsp;&nbsp;&nbsp;&nbsp;CreateRemoteThread(hProcess,&nbsp;NULL,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">, <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(</span><span style="color: #000000;">"</span><span style="color: #000000;">Kernel32</span><span style="color: #000000;">"</span><span style="color: #000000;">),&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">LoadLibraryA</span><span style="color: #000000;">"</span><span style="color: #000000;">), <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lpRemoteAddress,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;NULL);<br>}&nbsp;</span></div>
<br><br>The API does not create threads in other sessions (this behavior is documented in MSDN).<br><br>One way to load a library into a process of another session is: Create a suspended thread (ntdll!RtlCreateUserThread) at kernel32!ExitThread, schedule an asynchronous procedure call (ntdll!NtQueueApcThread) at kernel32!LoadLibraryEx, resume the thread (kernel32!ResumeThread - this executes the pending APC), and wait for the end of the thread (kernel32!WaitForSingleObject). APCs do not return a value - therefore the return value of kernel32!LoadLibraryEx is lost. There is much more work required to use this method in the exact same manner as CreateRemoteThread(LoadLibrary) (includes reading the PEB&#8217;s loader structures).<br><br>Other hints:<br><br>&nbsp;&nbsp;&nbsp; * Never ever use CreateRemoteThread on a target process that differs in 'bitness' (kernel32!IsWow64Process). On some Windows versions this freezes your calling thread.<br>&nbsp;&nbsp;&nbsp; * Dynamically determine the kernel32&#8217;s image base (might not be loaded at all).
<p>&nbsp;</p>
<br>对于 RtlCreateUserThread 函数的线程函数, 以下是个示例: <br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;LoadLibraryA_ADDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xDDDDDDDD&nbsp;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;RtlExitUserThread_ADDR&nbsp;&nbsp;0xEEEEEEEE&nbsp;</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;"></span>static&nbsp;__declspec(naked)&nbsp;DWORD&nbsp;WINAPI&nbsp;ThreadDummy(LPVOID&nbsp;lpParam)&nbsp;<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;__asm&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;dword&nbsp;ptr&nbsp;[esp+4]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;//&nbsp;将传进来的线程函数的参数压栈&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,&nbsp;LoadLibraryA_ADDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;//&nbsp;LoadLibraryA&nbsp;或&nbsp;FreeLibrary&nbsp;函数的地址&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;eax&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;LoadLibraryA&nbsp;函数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;eax&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;RtlExitUserThread&nbsp;函数的参数压栈<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,&nbsp;RtlExitUserThread_ADDR&nbsp;;&nbsp;//&nbsp;RtlExitUserThread&nbsp;函数的地址&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp; eax&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;// 调用 RtlExitUserThread&nbsp;函数 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4&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; <br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>}
<span style="color: #000000;"><br><br></span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;__declspec(naked)&nbsp;DWORD&nbsp;WINAPI&nbsp;ThreadDummy_end(LPVOID&nbsp;lpParam)&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;__asm&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret &nbsp;&nbsp;&nbsp; 4 &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;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>}<br><br>PUCHAR&nbsp;FindDWordFromBuffer(PUCHAR&nbsp;lpBuffer,&nbsp;UINT&nbsp;cchMax,&nbsp;DWORD&nbsp;dwValue)&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;PUCHAR&nbsp;pResult&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;UINT&nbsp;nIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(nIter</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;nIter</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">cchMax;&nbsp;nIter</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">(DWORD&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)(lpBuffer&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;nIter)&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;dwValue&nbsp;)&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pResult&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;lpBuffer&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;nIter;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;pResult;&nbsp;<br>}&nbsp;<br><br>BOOL&nbsp;BuildRemoteThreadCode(OUT&nbsp;PUCHAR&nbsp;lpCode,&nbsp;UINT&nbsp;cchMax,&nbsp;BOOL&nbsp;bInject)&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;UINT&nbsp;nCodeLen&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;PUCHAR&nbsp;pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwFnAddr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL</span><span style="color: #000000;">==</span><span style="color: #000000;">lpCode&nbsp;</span><span style="color: #000000;">||</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">==</span><span style="color: #000000;">cchMax)&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;nCodeLen&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(PUCHAR)&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">ThreadDummy_end&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;(PUCHAR)&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">ThreadDummy;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(nCodeLen&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;cchMax)&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;memcpy((</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)lpCode,&nbsp;(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">ThreadDummy,&nbsp;nCodeLen);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;FindDWordFromBuffer(lpCode,&nbsp;nCodeLen,&nbsp;LoadLibraryA_ADDR);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;pIter)&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(bInject)&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwFnAddr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(DWORD)&nbsp;GetProcAddress(GetModuleHandle(_T(</span><span style="color: #000000;">"</span><span style="color: #000000;">kernel32.dll</span><span style="color: #000000;">"</span><span style="color: #000000;">)),&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">LoadLibraryA</span><span style="color: #000000;">"</span><span style="color: #000000;">);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwFnAddr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(DWORD)&nbsp;GetProcAddress(GetModuleHandle(_T(</span><span style="color: #000000;">"</span><span style="color: #000000;">kernel32.dll</span><span style="color: #000000;">"</span><span style="color: #000000;">)),&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">FreeLibrary</span><span style="color: #000000;">"</span><span style="color: #000000;">);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;dwFnAddr)&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">(DWORD&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;dwFnAddr;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;FindDWordFromBuffer(lpCode,&nbsp;nCodeLen,&nbsp;RtlExitUserThread_ADDR);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;pIter)&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwFnAddr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(DWORD)&nbsp;GetProcAddress(GetModuleHandle(_T(</span><span style="color: #000000;">"</span><span style="color: #000000;">ntdll.dll</span><span style="color: #000000;">"</span><span style="color: #000000;">)),&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">RtlExitUserThread</span><span style="color: #000000;">"</span><span style="color: #000000;">);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;dwFnAddr)&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;FALSE;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">(DWORD&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)pIter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;dwFnAddr;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;TRUE;&nbsp;<br>}</span></div>
<br>
<p>自己分配一块足够大的内存, 以这块内存的指针作为参数调用 BuildRemoteThreadCode
函数后, 这块内存就可以写到目标进程里面, 并作为 RtlCreateUserThread
函数的线程函数执行了.<br></p>
<p>当然, 线程函数的参数, 还是得自己准备了, 也就是一个字符串指针或一个模块的 HMODULE. 相信大家都会, 不用我废话了.</p><img src ="http://www.cppblog.com/free2000fly/aggbug/53910.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/free2000fly/" target="_blank">free2000fly</a> 2008-06-18 17:31 <a href="http://www.cppblog.com/free2000fly/archive/2008/06/18/53910.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>完成 madchook 库驱动的逆向工程</title><link>http://www.cppblog.com/free2000fly/archive/2008/06/11/52813.html</link><dc:creator>free2000fly</dc:creator><author>free2000fly</author><pubDate>Tue, 10 Jun 2008 16:06:00 GMT</pubDate><guid>http://www.cppblog.com/free2000fly/archive/2008/06/11/52813.html</guid><wfw:comment>http://www.cppblog.com/free2000fly/comments/52813.html</wfw:comment><comments>http://www.cppblog.com/free2000fly/archive/2008/06/11/52813.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/free2000fly/comments/commentRss/52813.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/free2000fly/services/trackbacks/52813.html</trackback:ping><description><![CDATA[完成 madchook 库驱动的逆向工程, 驱动内的逻辑是这样的: <br><br>用 PsSetCreateProcessNotifyRoutine 函数挂接一个 "进程创建回调", 当有进程创建时, 针对目标进程, 这个回调函数里干了这些事情: <br>[list=1]<br>[*] 查看驱动有无创建一块内存, 没有则打开名为 "\\BaseNamedObjects\\mchInjDrvMap" 的文件映射, 如果打开成功后, 则创建一块分页内存, 并将文件映射读出来, 读取的长度在文件映射的第一个 DWORD 里保存着, 读出的数据写到新创建的内存里. 我读出的内容是: <br><br>kd&gt; dd e145f688<br>e145f688&nbsp; 00000971 00000089 000000ba 00000115<br>e145f698&nbsp; 0000002c 00000000 00000000 00000000<br>e145f6a8&nbsp; 7c92e8b8 000103b8 0300ba00 000000e8<br>e145f6b8&nbsp; 00255800 e8fffff0 0000010d 53e58955<br>e145f6c8&nbsp; 000000e8 e3815b00 fffff000 0875ff53<br>e145f6d8&nbsp; 0005e8e8 00f88300 75ff0b74 ed93ff08<br>e145f6e8&nbsp; eb000000 0022b805 5d5bc000 ca0004c2<br>e145f6f8&nbsp; 867c9361 007c9365 867c8000 487c92d5<br><br>经过分析, <br>第 1 个 DWORD 代表了这块数据本身的长度, <br>第 2, 3, 4 个 DWORD 代表了在 ntdll.dll 里导出的 ring 3 函数 <br>ZwProtectVirtualMemory, <br>NtReadVirtualMemory, <br>NtWriteVirtualMemory <br>的系统调用号, 因为 ntoskrnl.exe 里并没有导出这三个函数, 因此采用这种晦涩的方式以便可以在内核里调用它们.<br>第 5 个 DWORD 好像是可执行代码的偏移量, <br>第 6, 7, 8 三个 DWORD 好像没有使用, <br>第 9 个 DWORD 保存的是目标进程的 ntdll.dll 导出的函数 ZwTestAlert 的基址. <br>第 10, 11 两个 DWORD 共 8 个字节, 用于存储 ntdll.ZwTestAlert 函数的原始头 8 个字节. <br>第 12 个 DWORD, 从此开始, 就是可执行代码了, 此后用字节计数了, 一直到第 0x971 字节结束这段 shellcode <br><br><br>[*] 针对目标进程, 在其内部分配一块内存, 指定固定基址是 0x71700000 (我不知道是为什么), 将步骤 1 读出的所有内容写到这块内存里. <br>[*] 读取步骤 1 里创建的内存里的数据偏移的第 9 个 DWORD 的值, 我得到的是 ox7c92e8b8, 读取目标进程的以这个值作为偏移量的内存里的 8 个字节 (有点绕), 我对这些字节的反汇编如下: <br>0:001&gt; u 7c92e8b8<br>ntdll!ZwTestAlert:<br>7c92e8b8 b803010000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp; eax,103h<br>7c92e8bd ba0003fe7f&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp; edx,offset SharedUserData!SystemCallStub (7ffe0300)<br>7c92e8c2 ff12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp; dword ptr [edx]<br>7c92e8c4 c3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret<br><br>查看 [url]http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/APC/NtTestAlert.html[/url] 网页, 说: <br>You can use NtTestAlert to empty APC queue for current thread. If APC queue was empty before call, NtTestAlert has no efect.<br>NtTestAlert is typical ntcall kernel routine, accessable via int 2Eh. It check thread APC queue, and call KiUserApcDispatcher. <br><br>看来还是与 APC 有关, 牛皮糖一样, 扯都扯不脱.<br><br>[*] 将步骤 3 里读到的 8 个字节写到步骤 2 里分配到目标进程的内存的可执行代码起始偏移之前的 8 个字节处 (还是有点绕). <br><br>[*] 装配汇编代码, 共 8 个字节: <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push eax;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push eax;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push eax;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jmp [xxxxxxx];<br>其中 [xxxxxxx] 代表从 (ZwTestAlert + 8) 跳转到我们的代码的偏移量(带符号数) <br>&nbsp;&nbsp; &nbsp;<br>[*] 将装配好的汇编代码 8 个字节写入 ZwTestAlert 函数的开头. <br><br>[/list]<br><br><br>到了这里, 我们可以总结一下了, 在 win2000/xp 下, 往目标进程的内存写入我们的 shellcode 代码, 修改 Ntdll.NtTestAlert 的头 8 个字节让程序跳到我们的 shellcode 处执行, 在执行的过程中恢复 Ntdll.NtTestAlert 函数头部被改了的代码, 同时加载我们自己注入的链接库. 本质上还是一个 detours. <br><br>下面的任务, 就是逆向这段运行于 ring 3 下的 shellcode 了. <br><br> <img src ="http://www.cppblog.com/free2000fly/aggbug/52813.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/free2000fly/" target="_blank">free2000fly</a> 2008-06-11 00:06 <a href="http://www.cppblog.com/free2000fly/archive/2008/06/11/52813.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常去之地</title><link>http://www.cppblog.com/free2000fly/archive/2008/05/04/48812.html</link><dc:creator>free2000fly</dc:creator><author>free2000fly</author><pubDate>Sun, 04 May 2008 10:52:00 GMT</pubDate><guid>http://www.cppblog.com/free2000fly/archive/2008/05/04/48812.html</guid><wfw:comment>http://www.cppblog.com/free2000fly/comments/48812.html</wfw:comment><comments>http://www.cppblog.com/free2000fly/archive/2008/05/04/48812.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/free2000fly/comments/commentRss/48812.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/free2000fly/services/trackbacks/48812.html</trackback:ping><description><![CDATA[<li><a href="http://blogs.technet.com/markrussinovich/">Mark Russinovich's technical blog</a>
<li><a href="http://en.wikipedia.org/wiki/Windows_NT">NtBuildNumber</a>
<li><a href="http://blog.csdn.net/galihoo/">galihoo的专栏</a>
<li><a href="http://www.antiprotect.com/default.asp">Anti proect forums</a>
<li><a href="http://bt2.btchina.net/">btchina</a>
<li><a href="http://www.catch22.net/">catch22</a>
<li><a href="http://www.codeguru.com/">codeguru</a>
<li><a href="http://www.codeproject.com/index.asp?cat=2">codeproject</a>
<li><a href="http://www.codeproject.com/script/Articles/list_articles.asp?userid=88625">COM in plain C</a>
<li><a href="http://www.codeproject.com/script/Articles/list_articles.asp?userid=349853">Jeffrey Walton -- About Crypto++</a>
<li><a href="http://hi.baidu.com/Kruglinski">Kruglinski's blog</a>
<li><a href="http://www.codeproject.com/script/Articles/list_articles.asp?userid=152">Michael Dunn</a>
<li><a href="http://15038084.qzone.qq.com/">NAT Stuff</a>
<li><a href="http://www.ppcn.net/c2.aspx">P2P 技术</a>
<li><a href="http://sql.1keydata.com/cn/">SQL语句教程</a>
<li><a href="http://blog.csdn.net/visualfc/">visualfc</a>
<li><a href="http://greatdong.blog.edu.cn/">董岩的博客</a>
<li><a href="http://borland.mblogger.cn/doublefisher/">懒人日记</a>
<li><a href="http://www.titilima.cn/">李马的主页</a>
<li><a href="http://www.cppblog.com/sandy/">小明的思考</a>
<li><a href="http://blog.csdn.net/nixun/">倪勋的专栏</a>
<li><a href="http://www.microsoft.com/msj/0199/windowsdriver/windowsdriver.aspx">The Windows Driver Model Simplifies Management ofDevice Driver I/O Requests</a>
<li><a href="http://www.codeproject.com/KB/system/driveguicomm.aspx">Communication between GUI Application and Device Driver</a>
<li><a href="http://www.codeproject.com/kb/system/">Hardware and System</a>
<li><a href="http://hi.baidu.com/combojiang">一切从 C 开始</a>
<li><a href="http://www.acejoy.com/space/html/2/category-catid-2.html">Win2000 服务端</a>
<li><a href="http://blog.vckbase.com/windowssky/">垃圾堆 -- windowssky </a>
<li><a href="http://hi.baidu.com/6121017">Don`t Sleep!</a>
<li><a href="http://hi.baidu.com/ciw_blue">CIW_BLUE</a>
<li><a href="http://hi.baidu.com/justin_wu2010">无本之木</a>
<li><a href="http://hi.baidu.com/musehero">狙剑</a>
<li><a href="http://www.xfocus.net/articles/200601/846.html">Kernel Mode Sockets Library </a>
<li><a href="http://www.xfocus.net/index.html">安全焦点</a>
<li><a href="http://blog.csdn.net/liond8/">LionD8' Blog</a>
<li><a href="http://bbs.pediy.com/showthread.php?t=56230">Windows Internals---Processes,Threads,Jobs</a>
<li><a href="http://bbs.pediy.com/index.php">看雪软件安全论坛</a>
<li><a href="http://www.metasploit.com/users/opcode/syscalls.html">Windows System Call Table</a>
<li><a href="http://research.microsoft.com/invisible/default.asp?PP=/toc-4.xml&amp;tocPath=toc-4&amp;URL=files.htm">XML Web Services on a Chip</a>
<li><a href="http://hi.baidu.com/robinh00d">罗宾，汗-_-!</a>
<li><a href="http://www.iamdcboy.com/">Dcb0y [A.D.K] - I am dcboy</a>
<li><a href="http://hi.baidu.com/sudami">sudami</a>
<li><a href="http://blog.csdn.net/timixu/">TimiXu的专栏</a>
<li><a href="http://www.geocities.jp/webcrazyjp">webcrazy</a>
<li><a href="http://www.nsfocus.net/index.php?act=magazine&amp;do=search&amp;kind_id=4&amp;periodical=">绿盟安全月刊</a>
<li><a href="http://www.nsfocus.net/index.php?act=magazine&amp;do=view&amp;mid=2002">通过TEB/PEB枚举当前进程空间中用户模块列表</a>
<li><a href="http://www.cnblogs.com/dflying/archive/2007/03/14/673795.html">《Windows Vista for Developers》系列</a>
<li><a href="http://www.zhongts.net/">一块三毛钱</a>
<li><a href="http://www.0wei.com/thread-24260-1-3.html">内核态进程管理器Intercessor和实现细节</a>
<li><a href="http://blog.donews.com/zwell/">ZwelL'Blog 一些内核相关的文章</a>
<li><a href="http://mnin.blogspot.com/2007/05/injecting-code-into-privileged-win32.html">Injecting Code Into Privileged Win32 Processes</a>
<li><a href="http://oxid.netsons.org/phpBB2/viewtopic.php?t=964">NtCreateThreadEx usage for Injection on Vista (DONE)</a>
<li><a href="http://www.cnhacker.com/bbs/read.php?tid=167995">操作被占用的文件-unlocker机理分析</a>
<li><a href="http://hi.baidu.com/spirith/blog/item/e4689b2f231b1e3b1f30894a.html">PEB结构----枚举用户模块列表</a>
<li><a href="http://www.nynaeve.net/">http://www.nynaeve.net/</a>
<li><a href="http://www.butian.com.cn/knowledge/develop/index.htm">补天科技_知识库_高级编程</a>
<li><a href="http://www.cppblog.com/alantop/">http://alantop.5166.info</a> <br></li>
<img src ="http://www.cppblog.com/free2000fly/aggbug/48812.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/free2000fly/" target="_blank">free2000fly</a> 2008-05-04 18:52 <a href="http://www.cppblog.com/free2000fly/archive/2008/05/04/48812.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>屏幕保护: 用现成的 flash 动画作为内容</title><link>http://www.cppblog.com/free2000fly/archive/2008/05/02/48634.html</link><dc:creator>free2000fly</dc:creator><author>free2000fly</author><pubDate>Fri, 02 May 2008 05:51:00 GMT</pubDate><guid>http://www.cppblog.com/free2000fly/archive/2008/05/02/48634.html</guid><wfw:comment>http://www.cppblog.com/free2000fly/comments/48634.html</wfw:comment><comments>http://www.cppblog.com/free2000fly/archive/2008/05/02/48634.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/free2000fly/comments/commentRss/48634.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/free2000fly/services/trackbacks/48634.html</trackback:ping><description><![CDATA[用 mfc 开发的屏幕保护程序, 有个配置对话框可以添加自己喜欢的 flash&nbsp; 动画, 希望大家喜欢. <br><br>至于安装,使用方法, 相信大家都知道: 将 *.scr 文件复制到 c:\windows\system32 目录内, 然后在桌面上空白处右击鼠标, 选中 "属性" 菜单项. <br>在随后出现的 "显示 属性" 对话框内, 选择 "屏幕保护程序" 选项卡. 在 "屏幕保护程序" 下拉选择框里, 将会出现 Flash2ScreenSaver 选择项, <br>选择它, 然后点击 "设置" 按钮, 在随后蹦出的对话框内, 就可以添加或者删除你喜欢的 flash&nbsp;
动画了. Enjoy it!&nbsp;	<br><br>P.S. 早在 2003 年编写的, 代码不好, 现在也提不起兴趣再折腾了. 有哪位愿意改改, 弄完后 email 我一声. 先谢过了. <br><br>下载地址为: &nbsp;<a href="http://www.cppblog.com/Files/free2000fly/Flash2ScreenSaver03_F.zip">http://www.cppblog.com/Files/free2000fly/Flash2ScreenSaver03_F.zip</a>&nbsp;&nbsp;  <br><br><br>   <img src ="http://www.cppblog.com/free2000fly/aggbug/48634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/free2000fly/" target="_blank">free2000fly</a> 2008-05-02 13:51 <a href="http://www.cppblog.com/free2000fly/archive/2008/05/02/48634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多年前翻译的一个 ASM 教程, 包含一个拼图游戏</title><link>http://www.cppblog.com/free2000fly/archive/2008/04/05/46327.html</link><dc:creator>free2000fly</dc:creator><author>free2000fly</author><pubDate>Sat, 05 Apr 2008 12:41:00 GMT</pubDate><guid>http://www.cppblog.com/free2000fly/archive/2008/04/05/46327.html</guid><wfw:comment>http://www.cppblog.com/free2000fly/comments/46327.html</wfw:comment><comments>http://www.cppblog.com/free2000fly/archive/2008/04/05/46327.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/free2000fly/comments/commentRss/46327.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/free2000fly/services/trackbacks/46327.html</trackback:ping><description><![CDATA[如题, 多年前翻译的一个 ASM 教程, 包含一个拼图游戏. <br><br>俺认为这个教程写的是极具亲和力, 当年俺就是从这个和这个系列的前一系列进入 Win32 汇编编程的大门的, 希望它还能对现在的 GGJJDDMM 有所裨益. <br><br>俺的中文翻译在 <a href="http://www.cppblog.com/Files/free2000fly/mosaic_chinese.zip">这里</a> 下载 <br><br>前一系列的汇编入门教程在 <a href="http://www.cnblogs.com/taowen/articles/11237.html">这里</a>, 由陶文翻译<br><br>原教程的网址在 <a href="http://www.madwizard.org/programming/tutorials/">这里</a>. <br><br>可以在 <a href="http://www.masm32.com/masmdl.htm">这里</a> 下载 MASM32 汇编语言开发包, 在 <a href="http://www.radasm.com/">这里</a> 下载汇编语言集成开发环境(IDE), 在 <a href="http://www.resedit.net/">这里</a> 下载资源编辑器, 在 <a href="http://www.ollydbg.de/">这里</a> 下载调试器, 都是免费软件. <br><br>
<img src ="http://www.cppblog.com/free2000fly/aggbug/46327.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/free2000fly/" target="_blank">free2000fly</a> 2008-04-05 20:41 <a href="http://www.cppblog.com/free2000fly/archive/2008/04/05/46327.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>中文版 ASM KMD tut</title><link>http://www.cppblog.com/free2000fly/archive/2008/04/05/46297.html</link><dc:creator>free2000fly</dc:creator><author>free2000fly</author><pubDate>Sat, 05 Apr 2008 03:48:00 GMT</pubDate><guid>http://www.cppblog.com/free2000fly/archive/2008/04/05/46297.html</guid><wfw:comment>http://www.cppblog.com/free2000fly/comments/46297.html</wfw:comment><comments>http://www.cppblog.com/free2000fly/archive/2008/04/05/46297.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/free2000fly/comments/commentRss/46297.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/free2000fly/services/trackbacks/46297.html</trackback:ping><description><![CDATA[网上收集的关于用汇编语言编写 Windows 环境下的 KMD 驱动程序的教程, 由俄国人编写, 由罗云彬, 松松, 董岩翻译, 感谢所有这些人的辛勤劳动, 俺将这些散落在网络上的文章收集整理出来, 我想这些教程不止对使用汇编语言的人有帮助. <br><br>教程中文版的下载地址是&nbsp; <a href="http://www.cppblog.com/Files/free2000fly/KmdTutCn.zip">这里</a>&nbsp; <br><br>搭个顺风车, 将修改版的 QuickSys 程序放在 <a href="http://www.cppblog.com/Files/free2000fly/QuickSYS.zip">这里</a> <br><br>
<img src ="http://www.cppblog.com/free2000fly/aggbug/46297.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/free2000fly/" target="_blank">free2000fly</a> 2008-04-05 11:48 <a href="http://www.cppblog.com/free2000fly/archive/2008/04/05/46297.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>