﻿<?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++博客-紫雨轩 C++</title><link>http://www.cppblog.com/rick/</link><description>技术交流</description><language>zh-cn</language><lastBuildDate>Wed, 08 Apr 2026 11:29:11 GMT</lastBuildDate><pubDate>Wed, 08 Apr 2026 11:29:11 GMT</pubDate><ttl>60</ttl><item><title>ring0检测隐藏进程</title><link>http://www.cppblog.com/rick/archive/2007/08/26/30896.html</link><dc:creator>紫雨轩 C++</dc:creator><author>紫雨轩 C++</author><pubDate>Sun, 26 Aug 2007 15:41:00 GMT</pubDate><guid>http://www.cppblog.com/rick/archive/2007/08/26/30896.html</guid><wfw:comment>http://www.cppblog.com/rick/comments/30896.html</wfw:comment><comments>http://www.cppblog.com/rick/archive/2007/08/26/30896.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/rick/comments/commentRss/30896.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rick/services/trackbacks/30896.html</trackback:ping><description><![CDATA[<div class=bword id=post_message_307421 style="LINE-HEIGHT: 18px"><font color=#333333>标 题:</font><font color=#000000> 【原创】ring0检测隐藏进程</font><font color=#666666><br><font color=#333333>作 者:</font> <font color=#000000>堕落天才</font><br><font color=#333333>时 间:</font> 2007-05-10,13:28<br><font color=#333333>链 接:</font> http://bbs.pediy.com/showthread.php?t=44243<br></font><br>//网上得到一篇好文章&nbsp;<a href="http://www.cnxhacker.net/Article/show/3412.html" target=_blank><font color=#000000>Ring0下搜索内存枚举隐藏进程</font></a>&nbsp;，但是拿里面的代码来使用的时候发现并没有太多效果<br>//于是修改之，终于实现了最初的目标<br>//由于直接搜索内存,跟系统调度没什么关系,所以能够枚举到各种方法隐藏的进程&nbsp;包括断链、抹PspCidTable...&nbsp;<br>//甚至能枚举到已经"死掉"的进程,本程序通过进程的ExitTime来判断进程是不是已经结束<br>//除非能够把EProcess结构修改掉，但这个实现难度可能比较大，不知有没有哪位大侠试过（PID我修改过），欢迎讨论<br>//<br>//作者:堕落天才<br>//时间:2007年5月10日<br>//参考:&nbsp;uty&nbsp;&nbsp;Ring0下搜索内存枚举隐藏进程&nbsp;http://www.cnxhacker.net/Article/show/3412.html<br>//下面代码在XP&nbsp;SP2测试通过<br><br><br>#include&lt;ntddk.h&gt;<br><br>///////////////////////////不同的windows版本下面的偏移值不同<br>#define&nbsp;&nbsp;EPROCESS_SIZE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x25C&nbsp;//EPROCESS结构大小<br><br>#define&nbsp;&nbsp;PEB_OFFSET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x1B0<br>#define&nbsp;&nbsp;FILE_NAME_OFFSET&nbsp;&nbsp;&nbsp;&nbsp;0x174<br>#define&nbsp;&nbsp;PROCESS_LINK_OFFSET&nbsp;0x088<br>#define&nbsp;&nbsp;PROCESS_ID_OFFSET&nbsp;&nbsp;&nbsp;0x084<br>#define&nbsp;&nbsp;EXIT_TIME_OFFSET&nbsp;&nbsp;&nbsp;&nbsp;0x078<br><br>#define&nbsp;&nbsp;OBJECT_HEADER_SIZE&nbsp;&nbsp;0x018<br>#define&nbsp;&nbsp;OBJECT_TYPE_OFFSET&nbsp;&nbsp;0x008<br><br>#define&nbsp;PDE_INVALID&nbsp;2&nbsp;<br>#define&nbsp;PTE_INVALID&nbsp;1&nbsp;<br>#define&nbsp;VALID&nbsp;0&nbsp;<br><br><br>ULONG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pebAddress;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//PEB地址的前半部分<br>PEPROCESS&nbsp;pSystem;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//system进程<br>ULONG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pObjectTypeProcess;&nbsp;//进程对象类型<br><br>ULONG&nbsp;&nbsp;&nbsp;VALIDpage(ULONG&nbsp;addr)&nbsp;;&nbsp;&nbsp;//该函数直接复制自&nbsp;Ring0下搜索内存枚举隐藏进程<br>BOOLEAN&nbsp;IsaRealProcess(ULONG&nbsp;i);&nbsp;//该函数复制自&nbsp;Ring0下搜索内存枚举隐藏进程<br>VOID&nbsp;&nbsp;&nbsp;&nbsp;WorkThread(IN&nbsp;PVOID&nbsp;pContext);<br>ULONG&nbsp;&nbsp;&nbsp;GetPebAddress();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//得到PEB地址前半部分<br>VOID&nbsp;&nbsp;&nbsp;&nbsp;EnumProcess();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//枚举进程<br>VOID&nbsp;&nbsp;&nbsp;&nbsp;ShowProcess(ULONG&nbsp;pEProcess);&nbsp;//显示结果<br><br>VOID&nbsp;&nbsp;&nbsp;&nbsp;OnUnload(IN&nbsp;PDRIVER_OBJECT&nbsp;DriverObject)<br>{<br>}<br>NTSTATUS&nbsp;DriverEntry(IN&nbsp;PDRIVER_OBJECT&nbsp;DriverObject,IN&nbsp;PUNICODE_STRING&nbsp;RegistryPath)<br>{<br>&nbsp;&nbsp;HANDLE&nbsp;hThread;&nbsp;<br><br>&nbsp;&nbsp;DriverObject&nbsp;-&gt;&nbsp;DriverUnload&nbsp;=&nbsp;OnUnload;<br><br>&nbsp;&nbsp;pSystem&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;PsGetCurrentProcess();<br>&nbsp;&nbsp;pebAddress&nbsp;=&nbsp;GetPebAddress();<br>&nbsp;&nbsp;pObjectTypeProcess&nbsp;=&nbsp;*(PULONG)((ULONG)pSystem&nbsp;-&nbsp;OBJECT_HEADER_SIZE&nbsp;+OBJECT_TYPE_OFFSET);&nbsp;&nbsp;<br><br>&nbsp;&nbsp;PsCreateSystemThread(&amp;hThread,&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;(ACCESS_MASK)0,&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;NULL,&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;(HANDLE)0,&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;NULL,&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;WorkThread,&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;NULL&nbsp;);&nbsp;<br><br>&nbsp;&nbsp;return&nbsp;STATUS_SUCCESS;<br>}<br>//////////////////////////////////////////////<br>VOID&nbsp;WorkThread(IN&nbsp;PVOID&nbsp;pContext)&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;EnumProcess();<br>&nbsp;&nbsp;PsTerminateSystemThread(STATUS_SUCCESS);&nbsp;&nbsp;<br>}<br>////////////////////////////////////////////////////////<br>ULONG&nbsp;&nbsp;GetPebAddress()<br>{<br>&nbsp;&nbsp;ULONG&nbsp;Address;<br>&nbsp;&nbsp;PEPROCESS&nbsp;pEProcess;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//由于system进程的peb总是零&nbsp;我们只有到其他进程去找了<br>&nbsp;&nbsp;pEProcess&nbsp;=&nbsp;(PEPROCESS)((ULONG)((PLIST_ENTRY)((ULONG)pSystem&nbsp;+&nbsp;PROCESS_LINK_OFFSET))-&gt;Flink&nbsp;-&nbsp;PROCESS_LINK_OFFSET);<br>&nbsp;&nbsp;Address&nbsp;&nbsp;&nbsp;=&nbsp;*(PULONG)((ULONG)pEProcess&nbsp;+&nbsp;PEB_OFFSET);<br><br>&nbsp;&nbsp;return&nbsp;(Address&nbsp;&amp;&nbsp;0xFFFF0000);&nbsp;&nbsp;<br>}<br>///////////////////////////////////////////////////////<br>VOID&nbsp;EnumProcess()<br>{<br>&nbsp;&nbsp;ULONG&nbsp;&nbsp;uSystemAddress&nbsp;=&nbsp;(ULONG)pSystem;<br>&nbsp;&nbsp;ULONG&nbsp;&nbsp;i;<br>&nbsp;&nbsp;ULONG&nbsp;&nbsp;Address;<br>&nbsp;&nbsp;ULONG&nbsp;&nbsp;ret;<br><br>&nbsp;&nbsp;DbgPrint("-------------------------------------------");<br>&nbsp;&nbsp;DbgPrint("EProcess&nbsp;&nbsp;&nbsp;&nbsp;PID&nbsp;&nbsp;&nbsp;&nbsp;ImageFileName");<br>&nbsp;&nbsp;DbgPrint("---------------------------------");<br>&nbsp;&nbsp;<br><br>&nbsp;&nbsp;for(i&nbsp;=&nbsp;0x80000000;&nbsp;i&nbsp;&lt;&nbsp;uSystemAddress;&nbsp;i&nbsp;+=&nbsp;4){//system进程的EPROCESS地址就是最大值了<br>&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;=&nbsp;VALIDpage(i);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(ret&nbsp;==&nbsp;VALID){&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Address&nbsp;=&nbsp;*(PULONG)i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;((&nbsp;Address&nbsp;&amp;&nbsp;0xFFFF0000)&nbsp;==&nbsp;pebAddress){//每个进程的PEB地址都是在差不多的地方，地址前半部分是相同的&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(IsaRealProcess(i)){&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ShowProcess(i&nbsp;-&nbsp;PEB_OFFSET);&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;+=&nbsp;EPROCESS_SIZE;&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;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}else&nbsp;if(ret&nbsp;==&nbsp;PTE_INVALID){&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;-=4;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;+=&nbsp;0x1000;//4k&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}else{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i-=4;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i+=&nbsp;0x400000;//4mb&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;ShowProcess(uSystemAddress);//system的PEB总是零&nbsp;上面的方法是枚举不到的&nbsp;不过我们用PsGetCurrentProcess就能得到了<br>&nbsp;&nbsp;DbgPrint("-------------------------------------------");<br>&nbsp;&nbsp;<br>}<br>/////////////////////////////////////////////////////////<br>VOID&nbsp;&nbsp;&nbsp;&nbsp;ShowProcess(ULONG&nbsp;pEProcess)<br>{<br>&nbsp;&nbsp;PLARGE_INTEGER&nbsp;ExitTime;<br>&nbsp;&nbsp;ULONG&nbsp;PID;<br>&nbsp;&nbsp;PUCHAR&nbsp;pFileName;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;ExitTime&nbsp;=&nbsp;(PLARGE_INTEGER)(pEProcess&nbsp;+&nbsp;EXIT_TIME_OFFSET);&nbsp;&nbsp;<br>&nbsp;&nbsp;if(ExitTime-&gt;QuadPart&nbsp;!=&nbsp;0)&nbsp;//已经结束的进程的ExitTime为非零<br>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;;<br><br>&nbsp;&nbsp;PID&nbsp;=&nbsp;*(PULONG)(pEProcess&nbsp;+&nbsp;PROCESS_ID_OFFSET);<br>&nbsp;&nbsp;pFileName&nbsp;=&nbsp;(PUCHAR)(pEProcess&nbsp;+&nbsp;FILE_NAME_OFFSET);<br><br>&nbsp;&nbsp;DbgPrint("0x%08X&nbsp;&nbsp;%04d&nbsp;&nbsp;&nbsp;%s",pEProcess,PID,pFileName);<br>}<br>/////////////////////////////////////////////////////////////<br>ULONG&nbsp;VALIDpage(ULONG&nbsp;addr)&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;ULONG&nbsp;pte;&nbsp;<br>&nbsp;&nbsp;ULONG&nbsp;pde;&nbsp;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;pde&nbsp;=&nbsp;0xc0300000&nbsp;+&nbsp;(addr&gt;&gt;22)*4;&nbsp;<br>&nbsp;&nbsp;if((*(PULONG)pde&nbsp;&amp;&nbsp;0x1)&nbsp;!=&nbsp;0){&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;//large&nbsp;page&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;if((*(PULONG)pde&nbsp;&amp;&nbsp;0x80)&nbsp;!=&nbsp;0){&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;VALID;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;pte&nbsp;=&nbsp;0xc0000000&nbsp;+&nbsp;(addr&gt;&gt;12)*4;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;if((*(PULONG)pte&nbsp;&amp;&nbsp;0x1)&nbsp;!=&nbsp;0){&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;VALID;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}else{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;PTE_INVALID;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;return&nbsp;PDE_INVALID;&nbsp;<br>}&nbsp;<br>////////////////////////////////////////////////////////////////<br>BOOLEAN&nbsp;IsaRealProcess(ULONG&nbsp;i)&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;NTSTATUS&nbsp;STATUS;&nbsp;<br>&nbsp;&nbsp;PUNICODE_STRING&nbsp;pUnicode;&nbsp;<br>&nbsp;&nbsp;UNICODE_STRING&nbsp;Process;&nbsp;<br>&nbsp;&nbsp;ULONG&nbsp;pObjectType;&nbsp;<br>&nbsp;&nbsp;ULONG&nbsp;ObjectTypeAddress;&nbsp;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;if&nbsp;(VALIDpage(i-&nbsp;PEB_OFFSET)&nbsp;!=&nbsp;VALID){&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;FALSE;&nbsp;<br>&nbsp;&nbsp;}&nbsp;<br><br>&nbsp;&nbsp;ObjectTypeAddress&nbsp;=&nbsp;i&nbsp;-&nbsp;PEB_OFFSET&nbsp;-&nbsp;OBJECT_HEADER_SIZE&nbsp;+&nbsp;OBJECT_TYPE_OFFSET&nbsp;;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;if&nbsp;(VALIDpage(ObjectTypeAddress)&nbsp;==&nbsp;VALID){&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;pObjectType&nbsp;=&nbsp;*(PULONG)ObjectTypeAddress;&nbsp;<br>&nbsp;&nbsp;}else{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;FALSE;&nbsp;<br>&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;if(pObjectTypeProcess&nbsp;==&nbsp;pObjectType){&nbsp;//确定ObjectType是Process类型<br>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TRUE;&nbsp;<br>&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;return&nbsp;FALSE;&nbsp;<br><br>}&nbsp;<br>////////////////////////////////////////////////////////////////////</div>
<img src ="http://www.cppblog.com/rick/aggbug/30896.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rick/" target="_blank">紫雨轩 C++</a> 2007-08-26 23:41 <a href="http://www.cppblog.com/rick/archive/2007/08/26/30896.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SSDT Hook的妙用－对抗ring0 inline hook</title><link>http://www.cppblog.com/rick/archive/2007/08/26/30895.html</link><dc:creator>紫雨轩 C++</dc:creator><author>紫雨轩 C++</author><pubDate>Sun, 26 Aug 2007 15:39:00 GMT</pubDate><guid>http://www.cppblog.com/rick/archive/2007/08/26/30895.html</guid><wfw:comment>http://www.cppblog.com/rick/comments/30895.html</wfw:comment><comments>http://www.cppblog.com/rick/archive/2007/08/26/30895.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/rick/comments/commentRss/30895.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rick/services/trackbacks/30895.html</trackback:ping><description><![CDATA[<div class=bword id=post_message_285856 style="LINE-HEIGHT: 18px"><font color=#333333>标 题:</font><font color=#000000> 【原创】SSDT Hook的妙用－对抗ring0 inline hook</font><font color=#666666><br><font color=#333333>作 者:</font> <font color=#000000>堕落天才</font><br><font color=#333333>时 间:</font> 2007-03-10,15:18<br><font color=#333333>链 接:</font> http://bbs.pediy.com/showthread.php?t=40832<br></font><br>*******************************************************<br>*标题:【原创】SSDT&nbsp;Hook的妙用－对抗ring0&nbsp;inline&nbsp;hook&nbsp;&nbsp;*<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br>*日期:2007年3月10号&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br>*声明:本文章的目的仅为技术交流讨论&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br>*******************************************************<br><br>1,SSDT<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSDT即系统服务描述符表，它的结构如下(参考《Undocument&nbsp;Windows&nbsp;2000&nbsp;Secretes》第二章):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;struct&nbsp;_SYSTEM_SERVICE_TABLE<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PVOID&nbsp;&nbsp;&nbsp;ServiceTableBase;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//这个指向系统服务函数地址表<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PULONG&nbsp;&nbsp;ServiceCounterTableBase;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;NumberOfService;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//服务函数的个数,NumberOfService*4&nbsp;就是整个地址表的大小<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;ParamTableBase;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;struct&nbsp;_SERVICE_DESCRIPTOR_TABLE<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SYSTEM_SERVICE_TABLE&nbsp;&nbsp;&nbsp;ntoskrnel;&nbsp;&nbsp;//ntoskrnl.exe的服务函数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SYSTEM_SERVICE_TABLE&nbsp;&nbsp;&nbsp;win32k;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//win32k.sys的服务函数,(gdi.dll/user.dll的内核支持)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SYSTEM_SERVICE_TABLE&nbsp;&nbsp;&nbsp;NotUsed1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SYSTEM_SERVICE_TABLE&nbsp;&nbsp;&nbsp;NotUsed2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}SYSTEM_DESCRIPTOR_TABLE,*PSYSTEM_DESCRIPTOR_TABLE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;内核中有两个系统服务描述符表,一个是KeServiceDescriptorTable(由ntoskrnl.exe导出),一个是KeServieDescriptorTableShadow(没有导出)。两者的区别是，KeServiceDescriptorTable仅有ntoskrnel一项，KeServieDescriptorTableShadow包含了ntoskrnel以及win32k。一般的Native&nbsp;API的服务地址由KeServiceDescriptorTable分派，gdi.dll/user.dll的内核API调用服务地址由KeServieDescriptorTableShadow分派。还有要清楚一点的是win32k.sys只有在GUI线程中才加载，一般情况下是不加载的，所以要Hook&nbsp;KeServieDescriptorTableShadow的话，一般是用一个GUI程序通过IoControlCode来触发(想当初不明白这点，蓝屏死机了N次都想不明白是怎么回事)。<br>&nbsp;<br>&nbsp;2，SSDT&nbsp;HOOK&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;SSDT&nbsp;HOOK&nbsp;的原理其实非常简单，我们先实际看看KeServiceDescriptorTable是什么样的。&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;lkd&gt;&nbsp;dd&nbsp;KeServiceDescriptorTable<br>&nbsp;&nbsp;&nbsp;&nbsp;8055ab80&nbsp;&nbsp;804e3d20&nbsp;00000000&nbsp;0000011c&nbsp;804d9f48<br>&nbsp;&nbsp;&nbsp;&nbsp;8055ab90&nbsp;&nbsp;00000000&nbsp;00000000&nbsp;00000000&nbsp;00000000<br>&nbsp;&nbsp;&nbsp;&nbsp;8055aba0&nbsp;&nbsp;00000000&nbsp;00000000&nbsp;00000000&nbsp;00000000<br>&nbsp;&nbsp;&nbsp;&nbsp;8055abb0&nbsp;&nbsp;00000000&nbsp;00000000&nbsp;00000000&nbsp;00000000&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;在windbg.exe中我们就看得比较清楚，KeServiceDescriptorTable中就只有第一项有数据，其他都是0。其中804e3d20就是<br>KeServiceDescriptorTable.ntoskrnel.ServiceTableBase，服务函数个数为0x11c个。我们再看看804e3d20地址里是什么东西：<br>&nbsp;&nbsp;&nbsp;&nbsp;lkd&gt;&nbsp;dd&nbsp;804e3d20<br>&nbsp;&nbsp;&nbsp;&nbsp;804e3d20&nbsp;&nbsp;80587691&nbsp;805716ef&nbsp;8057ab71&nbsp;80581b5c<br>&nbsp;&nbsp;&nbsp;&nbsp;804e3d30&nbsp;&nbsp;80599ff7&nbsp;80637b80&nbsp;80639d05&nbsp;80639d4e<br>&nbsp;&nbsp;&nbsp;&nbsp;804e3d40&nbsp;&nbsp;8057741c&nbsp;8064855b&nbsp;80637347&nbsp;80599539<br>&nbsp;&nbsp;&nbsp;&nbsp;804e3d50&nbsp;&nbsp;8062f4ec&nbsp;8057a98c&nbsp;8059155e&nbsp;8062661f<br>&nbsp;&nbsp;&nbsp;&nbsp;如上,80587691&nbsp;805716ef&nbsp;8057ab71&nbsp;80581b5c&nbsp;这些就是系统服务函数的地址了。比如当我们在ring3调用OpenProcess时，进入sysenter的ID是0x7A(XP&nbsp;SP2)，然后系统查KeServiceDescriptorTable，大概是这样KeServiceDescriptorTable.ntoskrnel.ServiceTableBase(804e3d20)&nbsp;+&nbsp;0x7A&nbsp;*&nbsp;4&nbsp;=&nbsp;804E3F08,然后804E3F08&nbsp;-&gt;8057559e&nbsp;这个就是OpenProcess系统服务函数所在,我们再跟踪看看:<br>&nbsp;&nbsp;&nbsp;&nbsp;lkd&gt;&nbsp;u&nbsp;8057559e<br>&nbsp;&nbsp;&nbsp;&nbsp;nt!NtOpenProcess:<br>&nbsp;&nbsp;&nbsp;&nbsp;8057559e&nbsp;68c4000000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;0C4h<br>&nbsp;&nbsp;&nbsp;&nbsp;805755a3&nbsp;6860b54e80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;nt!ObReferenceObjectByPointer+0x127&nbsp;(804eb560)<br>&nbsp;&nbsp;&nbsp;&nbsp;805755a8&nbsp;e8e5e4f6ff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;nt!InterlockedPushEntrySList+0x79&nbsp;(804e3a92)<br>&nbsp;&nbsp;&nbsp;&nbsp;805755ad&nbsp;33f6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xor&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;esi,esi<br>&nbsp;&nbsp;&nbsp;&nbsp;原来8057559e就是NtOpenProcess函数所在的起始地址。&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;嗯，如果我们把8057559e改为指向我们函数的地址呢？比如&nbsp;MyNtOpenProcess，那么系统就会直接调用MyNtOpenProcess，而不是原来的NtOpenProcess了。这就是SSDT&nbsp;HOOK&nbsp;原理所在。<br><br>&nbsp;&nbsp;3,&nbsp;ring0&nbsp;inline&nbsp;hook<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ring0&nbsp;inline&nbsp;hook&nbsp;跟ring3的没什么区别了，如果硬说有的话，那么就是ring3发生什么差错的话程序会挂掉，ring0发生什么差错的话系统就挂掉，所以一定要很小心。inline&nbsp;hook的基本思想就是在目标函数中JMP到自己的监视函数，做一些判断然后再JMP回去。一般都是修改函数头，不过再其他地方JMP也是可以的。下面我们来点实际的吧:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lkd&gt;&nbsp;u&nbsp;nt!NtOpenProcess<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nt!NtOpenProcess:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8057559e&nbsp;e95d6f4271&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f199c500<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;805755a3&nbsp;e93f953978&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f890eae7<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;805755a8&nbsp;e8e5e4f6ff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;nt!InterlockedPushEntrySList+0x79&nbsp;(804e3a92)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;同时打开&#8220;冰刃&#8221;跟&#8220;Rootkit&nbsp;Unhooker&#8221;我们就能在NtOpenProcess函数头看到这样的&#8220;奇观&#8221;,第一个jmp是&#8220;冰刃&#8221;的，第二个jmp是&#8220;Rootkit&nbsp;Unhooker&#8221;的。他们这样是防止被恶意程序通过TerminateProcess关闭。当然&#8220;冰刃&#8221;还Hook了NtTerminateProcess等函数。<br><br>&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;<br>&nbsp;&nbsp;&nbsp;&nbsp;好了，道理就说完了，下面就进入本文正题。<br>&nbsp;&nbsp;&nbsp;&nbsp;对付ring0&nbsp;inline&nbsp;hook的基本思路是这样的，自己写一个替换的内核函数，以NtOpenProcess为例，就是MyNtOpenProcess。然后修改SSDT表，让系统服务进入自己的函数MyNtOpenProcess。而MyNtOpenProcess要做的事就是，实现NtOpenProcess前10字节指令，然后再JMP到原来的NtOpenProcess的十字节后。这样NtOpenProcess函数头写的JMP都失效了，在ring3直接调用OpenProcess再也毫无影响。<br>***************************************************************************************************************************<br>#include&lt;ntddk.h&gt;<br><br>typedef&nbsp;struct&nbsp;_SERVICE_DESCRIPTOR_TABLE<br>{<br>&nbsp;&nbsp;PVOID&nbsp;&nbsp;&nbsp;ServiceTableBase;<br>&nbsp;&nbsp;PULONG&nbsp;&nbsp;ServiceCounterTableBase;<br>&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;NumberOfService;<br>&nbsp;&nbsp;ULONG&nbsp;&nbsp;&nbsp;ParamTableBase;<br>}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;&nbsp;//由于KeServiceDescriptorTable只有一项,这里就简单点了<br>extern&nbsp;PSERVICE_DESCRIPTOR_TABLE&nbsp;&nbsp;&nbsp;&nbsp;KeServiceDescriptorTable;//KeServiceDescriptorTable为导出函数<br><br>/////////////////////////////////////<br>VOID&nbsp;Hook();<br>VOID&nbsp;Unhook();<br>VOID&nbsp;OnUnload(IN&nbsp;PDRIVER_OBJECT&nbsp;DriverObject);<br>//////////////////////////////////////<br>ULONG&nbsp;JmpAddress;//跳转到NtOpenProcess里的地址<br>ULONG&nbsp;OldServiceAddress;//原来NtOpenProcess的服务地址<br>//////////////////////////////////////<br>__declspec(naked)&nbsp;NTSTATUS&nbsp;__stdcall&nbsp;MyNtOpenProcess(PHANDLE&nbsp;ProcessHandle,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACCESS_MASK&nbsp;DesiredAccess,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;POBJECT_ATTRIBUTES&nbsp;ObjectAttributes,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PCLIENT_ID&nbsp;ClientId)&nbsp;<br>{<br>&nbsp;&nbsp;DbgPrint("NtOpenProcess()&nbsp;called");<br>&nbsp;&nbsp;__asm{<br>&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;0C4h<br>&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;804eb560h&nbsp;&nbsp;//共十个字节<br>&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[JmpAddress]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;}<br>}<br>///////////////////////////////////////////////////<br>NTSTATUS&nbsp;DriverEntry(IN&nbsp;PDRIVER_OBJECT&nbsp;DriverObject,PUNICODE_STRING&nbsp;RegistryPath)<br>{<br>&nbsp;&nbsp;DriverObject-&gt;DriverUnload&nbsp;=&nbsp;OnUnload;<br>&nbsp;&nbsp;DbgPrint("Unhooker&nbsp;load");<br>&nbsp;&nbsp;Hook();<br>&nbsp;&nbsp;return&nbsp;STATUS_SUCCESS;<br>}<br>/////////////////////////////////////////////////////<br>VOID&nbsp;OnUnload(IN&nbsp;PDRIVER_OBJECT&nbsp;DriverObject)<br>{<br>&nbsp;&nbsp;DbgPrint("Unhooker&nbsp;unload!");<br>&nbsp;&nbsp;Unhook();<br>}<br>/////////////////////////////////////////////////////<br>VOID&nbsp;Hook()<br>{<br>&nbsp;&nbsp;ULONG&nbsp;&nbsp;Address;<br>&nbsp;&nbsp;Address&nbsp;=&nbsp;(ULONG)KeServiceDescriptorTable-&gt;ServiceTableBase&nbsp;+&nbsp;0x7A&nbsp;*&nbsp;4;//0x7A为NtOpenProcess服务ID<br>&nbsp;&nbsp;DbgPrint("Address:0x%08X",Address);<br><br>&nbsp;&nbsp;OldServiceAddress&nbsp;=&nbsp;*(ULONG*)Address;//保存原来NtOpenProcess的地址<br>&nbsp;&nbsp;DbgPrint("OldServiceAddress:0x%08X",OldServiceAddress);<br><br>&nbsp;&nbsp;DbgPrint("MyNtOpenProcess:0x%08X",MyNtOpenProcess);<br><br>&nbsp;&nbsp;JmpAddress&nbsp;=&nbsp;(ULONG)NtOpenProcess&nbsp;+&nbsp;10;&nbsp;//跳转到NtOpenProcess函数头＋10的地方，这样在其前面写的JMP都失效了<br>&nbsp;&nbsp;DbgPrint("JmpAddress:0x%08X",JmpAddress);<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;__asm{//去掉内存保护<br>&nbsp;&nbsp;&nbsp;&nbsp;cli<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;eax,cr0<br>&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;&nbsp;eax,not&nbsp;10000h<br>&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;cr0,eax<br>&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;*((ULONG*)Address)&nbsp;=&nbsp;(ULONG)MyNtOpenProcess;//HOOK&nbsp;SSDT<br><br>&nbsp;&nbsp;__asm{//恢复内存保护&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;eax,cr0<br>&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;&nbsp;&nbsp;eax,10000h<br>&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;cr0,eax<br>&nbsp;&nbsp;&nbsp;&nbsp;sti<br>&nbsp;&nbsp;}<br>}<br>//////////////////////////////////////////////////////<br>VOID&nbsp;Unhook()<br>{<br>&nbsp;&nbsp;ULONG&nbsp;&nbsp;Address;<br>&nbsp;&nbsp;Address&nbsp;=&nbsp;(ULONG)KeServiceDescriptorTable-&gt;ServiceTableBase&nbsp;+&nbsp;0x7A&nbsp;*&nbsp;4;//查找SSDT<br><br>&nbsp;&nbsp;__asm{<br>&nbsp;&nbsp;&nbsp;&nbsp;cli<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;eax,cr0<br>&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;&nbsp;eax,not&nbsp;10000h<br>&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;cr0,eax<br>&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;*((ULONG*)Address)&nbsp;=&nbsp;(ULONG)OldServiceAddress;//还原SSDT<br><br>&nbsp;&nbsp;__asm{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;eax,cr0<br>&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;&nbsp;&nbsp;eax,10000h<br>&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;cr0,eax<br>&nbsp;&nbsp;&nbsp;&nbsp;sti<br>&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;DbgPrint("Unhook");<br>}<br>&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;<br>&nbsp;&nbsp;&nbsp;&nbsp;就这么多了，或许有人说，没必要那么复杂，直接恢复NtOpenProcess不就行了吗？对于象&#8220;冰刃&#8221;&#8220;Rookit&nbsp;Unhooker&#8221;这些&#8220;善良&#8221;之辈的话是没问题的，但是象NP这些&#8220;穷凶极恶&#8221;之流的话，它会不断检测NtOpenProcess是不是已经被写回去，是的话，嘿嘿，机器马上重启。这也是这种方法的一点点妙用。</div>
<img src ="http://www.cppblog.com/rick/aggbug/30895.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rick/" target="_blank">紫雨轩 C++</a> 2007-08-26 23:39 <a href="http://www.cppblog.com/rick/archive/2007/08/26/30895.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>权限提升代码</title><link>http://www.cppblog.com/rick/archive/2007/08/22/30539.html</link><dc:creator>紫雨轩 C++</dc:creator><author>紫雨轩 C++</author><pubDate>Tue, 21 Aug 2007 16:04:00 GMT</pubDate><guid>http://www.cppblog.com/rick/archive/2007/08/22/30539.html</guid><wfw:comment>http://www.cppblog.com/rick/comments/30539.html</wfw:comment><comments>http://www.cppblog.com/rick/archive/2007/08/22/30539.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/rick/comments/commentRss/30539.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rick/services/trackbacks/30539.html</trackback:ping><description><![CDATA[void&nbsp;AdjustPrivilege(int&nbsp;pid,&nbsp;BOOL&nbsp;bEnable)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;&nbsp;&nbsp;&nbsp;hProcess;<br>&nbsp;&nbsp;HANDLE&nbsp;&nbsp;&nbsp;&nbsp;hToken=0;<br>&nbsp;&nbsp;&nbsp;&nbsp;TOKEN_PRIVILEGES&nbsp;tkp;<br>&nbsp;&nbsp;tkp.PrivilegeCount&nbsp;=&nbsp;1;&nbsp;&nbsp;<br>&nbsp;&nbsp;tkp.Privileges[0].Attributes&nbsp;=&nbsp;0;<br>&nbsp;&nbsp;if&nbsp;(bEnable)<br>&nbsp;&nbsp;&nbsp;&nbsp;tkp.Privileges[0].Attributes&nbsp;=&nbsp;SE_PRIVILEGE_ENABLED;<br>&nbsp;&nbsp;if&nbsp;(LookupPrivilegeValue(NULL,&nbsp;"SeDebugPrivilege",&nbsp;&amp;tkp.Privileges[0].Luid))<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(hProcess&nbsp;=&nbsp;OpenProcess(PROCESS_ALL_ACCESS,&nbsp;FALSE,&nbsp;pid))<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(OpenProcessToken(hProcess,&nbsp;TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&nbsp;&amp;hToken))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(AdjustTokenPrivileges(hToken,&nbsp;FALSE,&nbsp;&amp;tkp,&nbsp;0,&nbsp;NULL,&nbsp;NULL))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hToken);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hProcess);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>}<br>
<img src ="http://www.cppblog.com/rick/aggbug/30539.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rick/" target="_blank">紫雨轩 C++</a> 2007-08-22 00:04 <a href="http://www.cppblog.com/rick/archive/2007/08/22/30539.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>防止注入的代码</title><link>http://www.cppblog.com/rick/archive/2007/08/22/30538.html</link><dc:creator>紫雨轩 C++</dc:creator><author>紫雨轩 C++</author><pubDate>Tue, 21 Aug 2007 16:03:00 GMT</pubDate><guid>http://www.cppblog.com/rick/archive/2007/08/22/30538.html</guid><wfw:comment>http://www.cppblog.com/rick/comments/30538.html</wfw:comment><comments>http://www.cppblog.com/rick/archive/2007/08/22/30538.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/rick/comments/commentRss/30538.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rick/services/trackbacks/30538.html</trackback:ping><description><![CDATA[#define&nbsp;PROTECTED_DACL_SECURITY_INFORMATION&nbsp;(0x80000000L)<br><br>BOOL&nbsp;Lock_CurrentProcess()<br>{<br>&nbsp;&nbsp;HANDLE&nbsp;hProcess&nbsp;=&nbsp;::GetCurrentProcess();<br>&nbsp;&nbsp;SID_IDENTIFIER_AUTHORITY&nbsp;sia&nbsp;=&nbsp;SECURITY_WORLD_SID_AUTHORITY;<br>&nbsp;&nbsp;PSID&nbsp;pSid;<br>&nbsp;&nbsp;BOOL&nbsp;bSus&nbsp;=&nbsp;FALSE;<br>&nbsp;&nbsp;bSus&nbsp;=&nbsp;::AllocateAndInitializeSid(&amp;sia,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&amp;pSid);<br>&nbsp;&nbsp;if(!bSus)&nbsp;goto&nbsp;Cleanup;<br>&nbsp;&nbsp;HANDLE&nbsp;hToken;<br>&nbsp;&nbsp;bSus&nbsp;=&nbsp;::OpenProcessToken(hProcess,TOKEN_QUERY,&amp;hToken);<br>&nbsp;&nbsp;if(!bSus)&nbsp;goto&nbsp;Cleanup;<br>&nbsp;&nbsp;DWORD&nbsp;dwReturnLength;<br>&nbsp;&nbsp;::GetTokenInformation(hToken,TokenUser,NULL,NULL,&amp;dwReturnLength);<br>&nbsp;&nbsp;if(dwReturnLength&nbsp;&gt;&nbsp;0x400)&nbsp;goto&nbsp;Cleanup;<br>&nbsp;&nbsp;LPVOID&nbsp;TokenInformation;<br>&nbsp;&nbsp;TokenInformation&nbsp;=&nbsp;::LocalAlloc(LPTR,0x400);//这里就引用SDK的函数不引用CRT的了<br>&nbsp;&nbsp;DWORD&nbsp;dw;<br>&nbsp;&nbsp;bSus&nbsp;=&nbsp;::GetTokenInformation(hToken,TokenUser,TokenInformation,0x400,&amp;dw);<br>&nbsp;&nbsp;if(!bSus)&nbsp;goto&nbsp;Cleanup;<br>&nbsp;&nbsp;PTOKEN_USER&nbsp;pTokenUser&nbsp;=&nbsp;(PTOKEN_USER)TokenInformation;<br>&nbsp;&nbsp;BYTE&nbsp;Buf[0x200];<br>&nbsp;&nbsp;PACL&nbsp;pAcl&nbsp;=&nbsp;(PACL)&amp;Buf;<br>&nbsp;&nbsp;bSus&nbsp;=&nbsp;::InitializeAcl(pAcl,1024,ACL_REVISION);<br>&nbsp;&nbsp;if(!bSus)&nbsp;goto&nbsp;Cleanup;<br>&nbsp;&nbsp;bSus&nbsp;=&nbsp;::AddAccessDeniedAce(pAcl,ACL_REVISION,0x000000FA,pSid);<br>&nbsp;&nbsp;if(!bSus)&nbsp;goto&nbsp;Cleanup;<br>&nbsp;&nbsp;bSus&nbsp;=&nbsp;::AddAccessAllowedAce(pAcl,ACL_REVISION,0x00100701,pTokenUser-&gt;User.Sid);<br>&nbsp;&nbsp;if(!bSus)&nbsp;goto&nbsp;Cleanup;<br>&nbsp;&nbsp;if(::SetSecurityInfo(hProcess,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION&nbsp;|&nbsp;PROTECTED_DACL_SECURITY_INFORMATION,NULL,NULL,pAcl,NULL)&nbsp;==&nbsp;0)<br>&nbsp;&nbsp;&nbsp;&nbsp;bSus&nbsp;=&nbsp;TRUE;<br>Cleanup:<br>&nbsp;&nbsp;if(hProcess&nbsp;!=&nbsp;NULL)<br>&nbsp;&nbsp;&nbsp;&nbsp;::CloseHandle(hProcess);<br>&nbsp;&nbsp;if(pSid&nbsp;!=&nbsp;NULL)<br>&nbsp;&nbsp;&nbsp;&nbsp;::FreeSid(pSid);<br>&nbsp;&nbsp;return&nbsp;bSus;<br>}<br><br>这段代码就可以锁住其他进程打开本进程,当然也就防止了注入,和读写内存.<br><br>可以更绝点Denied&nbsp;ALL&nbsp;ACCESS(0xFFFFFFFF)就连结束都不可能了<br><br>::AllocateAndInitializeSid&nbsp;可以换成&nbsp;::&nbsp;InitializeSid&nbsp;.因为我们并不需要初始化子Sid.<br>另外.<br>&nbsp;&nbsp;bSus&nbsp;=&nbsp;::AddAccessDeniedAce(pAcl,ACL_REVISION,0x000000FA,pSid);<br>&nbsp;&nbsp;if(!bSus)&nbsp;goto&nbsp;Cleanup;<br>&nbsp;&nbsp;bSus&nbsp;=&nbsp;::AddAccessAllowedAce(pAcl,ACL_REVISION,0x00100701,pTokenUser-&gt;User.Sid);<br>实际上只需要下面的一句,或者干脆把它去掉,因为如果不添加Ace默认就是没有权限.既然这样上面的那句话AllocateAndInitializeSid&nbsp;也可以省掉,也似乎有些多余 
<img src ="http://www.cppblog.com/rick/aggbug/30538.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rick/" target="_blank">紫雨轩 C++</a> 2007-08-22 00:03 <a href="http://www.cppblog.com/rick/archive/2007/08/22/30538.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解决Vista下文件名中带Update不能通过UAC认证的问题</title><link>http://www.cppblog.com/rick/archive/2007/08/21/30537.html</link><dc:creator>紫雨轩 C++</dc:creator><author>紫雨轩 C++</author><pubDate>Tue, 21 Aug 2007 15:58:00 GMT</pubDate><guid>http://www.cppblog.com/rick/archive/2007/08/21/30537.html</guid><wfw:comment>http://www.cppblog.com/rick/comments/30537.html</wfw:comment><comments>http://www.cppblog.com/rick/archive/2007/08/21/30537.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/rick/comments/commentRss/30537.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rick/services/trackbacks/30537.html</trackback:ping><description><![CDATA[&lt;?xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"&nbsp;standalone="yes"?&gt;<br>&lt;assembly&nbsp;xmlns="urn:schemas-microsoft-com:asm.v1"&nbsp;manifestVersion="1.0"&gt;&nbsp;<br>&nbsp;&nbsp;&lt;assemblyIdentity&nbsp;version="1.0.0.0"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processorArchitecture="X86"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name="IsUserAdmin"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type="win32"/&gt;&nbsp;<br>&nbsp;&nbsp;&lt;description&gt;QQUpdateCenter&lt;/description&gt;&nbsp;<br>&nbsp;&nbsp;&lt;!--&nbsp;Identify&nbsp;the&nbsp;application&nbsp;security&nbsp;requirements.&nbsp;--&gt;<br>&nbsp;&nbsp;&lt;trustInfo&nbsp;xmlns="urn:schemas-microsoft-com:asm.v2"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;security&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;requestedPrivileges&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;requestedExecutionLevel<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;level="asInvoker"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uiAccess="false"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/requestedPrivileges&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/security&gt;<br>&nbsp;&nbsp;&lt;/trustInfo&gt;<br>&lt;/assembly&gt;<br><br>这段代码放到manifest资源中。
<img src ="http://www.cppblog.com/rick/aggbug/30537.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rick/" target="_blank">紫雨轩 C++</a> 2007-08-21 23:58 <a href="http://www.cppblog.com/rick/archive/2007/08/21/30537.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>naked 函数调用 </title><link>http://www.cppblog.com/rick/archive/2006/10/28/14318.html</link><dc:creator>紫雨轩 C++</dc:creator><author>紫雨轩 C++</author><pubDate>Sat, 28 Oct 2006 12:02:00 GMT</pubDate><guid>http://www.cppblog.com/rick/archive/2006/10/28/14318.html</guid><wfw:comment>http://www.cppblog.com/rick/comments/14318.html</wfw:comment><comments>http://www.cppblog.com/rick/archive/2006/10/28/14318.html#Feedback</comments><slash:comments>13</slash:comments><wfw:commentRss>http://www.cppblog.com/rick/comments/commentRss/14318.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rick/services/trackbacks/14318.html</trackback:ping><description><![CDATA[转<br /><div>正常的情况下，我们写一个 C/C++ 函数，即使是一个空函数，编译器也为我们做了不少的工作，生成了一些“必要”的代码。请看下面的函数 (为了说明问题随便写的): <br /></div><br /><br /><div style="COLOR: #2222aa; BACKGROUND-COLOR: #f5f5f0"><pre>int Test()<br /> { <br />     int iReturn;<br />     char szTemp[33];<br />     <br />     szTemp[0] = 'A';<br />     szTemp[1] = '';<br />     iReturn = MessageBox(NULL, szTemp, szTemp, MB_OK);<br />     MessageBeep(iReturn);<br />     return iReturn;<br />  }</pre></div><br /><div>下面是用 VC6 在 Release 方式下编译后的的反汇编代码:</div><br /><br /><div style="COLOR: #2222aa; BACKGROUND-COLOR: #f5f5f0"><pre>00401000   sub         esp,24h     // 增加堆栈空间存放局部变量 (24H = 36D，4 字节对齐，注意这里没有为 iReturn 分配空间)<br /> 00401003   push        esi         // 保存要使用的重要寄存器<br /> 00401004   lea         eax,[esp+4] // 下面是传递 MessageBox() 要使用的参数<br /> 00401008   push        0<br /> 0040100A   lea         ecx,[esp+8] // 编译器愚蠢，根本不用 ECX，两个都是 szTemp，两次 PUSH EAX 不得了<br /> 0040100E   push        eax<br /> 0040100F   push        ecx<br /> 00401010   push        0<br /> 00401012   mov         byte ptr [esp+14h],41h<br /> 00401017   mov         byte ptr [esp+15h],0<br /> 0040101C   call        dword ptr ds:[40509Ch] // 调用 MessageBox()<br /> 00401022   mov         esi,eax     // 保存返回值到变量 iReturn 。靠！变量 iReturn 自动使用 ESI，编译器太聪明了：）<br /> 00401024   push        esi<br /> 00401025   call        dword ptr ds:[4050A0h] // 调用 MessageBeep()<br /> 0040102B   mov         eax,esi     // 把变量 iReturn 交给 EAX 作为返回值<br /> 0040102D   pop         esi         // 恢复要使用的重要寄存器<br /> 0040102E   add         esp,24h     // 减少堆栈空间<br /> 00401031   ret                     // 堆栈长度减 4 并返回<br /></pre></div><br /><div><br />这段代码虽然很精干 (都能自动使用寄存器来保存变量了)，但是有的时候我们并不需要编译器提供这些自作主张的代码 (比如写驱动程序的时候，不过我还没遇到过这种情况，呵呵~~)，我们希望整个全部函数都是自己亲手写进去的 (BT 呀^o^)。好，请出今天的主角 —— “naked”(怎么是裸体呀？)，欢迎！Visual C++ 的扩展关键字 naked 允许我们完全定制一个函数，废话不说了，看例子 (熬夜写的 Zzzzzz~~):</div><br /><br /><div style="COLOR: #2222aa; BACKGROUND-COLOR: #f5f5f0"><pre>__declspec(naked) int Test()<br /> { <br />     __asm<br />     { <br />         SUB         ESP,24H<br />         PUSH        ESI<br />         LEA         EAX,[ESP+4]<br />         PUSH        0                      <br />         PUSH        EAX                    <br />         PUSH        EAX                    <br />         PUSH        0                      <br />         MOV         BYTE PTR [ESP+14H],41H <br />         MOV         BYTE PTR [ESP+15H],0   <br />         CALL        DWORD PTR [MessageBoxA] <br />         MOV         ESI,EAX<br />         PUSH        ESI                    <br />         CALL        DWORD PTR [MessageBeep] <br />         MOV         EAX,ESI<br />         POP         ESI<br />         ADD         ESP,24H<br />         RET<br />      }<br />  }<br /></pre></div><br /><div>上面的代码是使用的 VC 的内联汇编，和 VC 编译后生成的代码完全是一样的 (很有完全控制的成就感吧^_^)。上面我们并没有又节省什么 (节省的 PUSH ECX 并不是 naked 的功劳)，但是有的时候确实需要的 (举不出例子来了，倒！)。最后随便说说注意事项: <br /><br />1.使用 naked 关键字需要自己构建 EBP 参数指针 (如果用到了 EBP 作为参数指针的话)；<br />2.必须自己使用 RET 或 RET n 指令返回 (除非你不返回)。<br /></div><img src ="http://www.cppblog.com/rick/aggbug/14318.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rick/" target="_blank">紫雨轩 C++</a> 2006-10-28 20:02 <a href="http://www.cppblog.com/rick/archive/2006/10/28/14318.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>#pragma 指示符应用举例</title><link>http://www.cppblog.com/rick/archive/2006/10/28/14317.html</link><dc:creator>紫雨轩 C++</dc:creator><author>紫雨轩 C++</author><pubDate>Sat, 28 Oct 2006 12:01:00 GMT</pubDate><guid>http://www.cppblog.com/rick/archive/2006/10/28/14317.html</guid><wfw:comment>http://www.cppblog.com/rick/comments/14317.html</wfw:comment><comments>http://www.cppblog.com/rick/archive/2006/10/28/14317.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/rick/comments/commentRss/14317.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rick/services/trackbacks/14317.html</trackback:ping><description><![CDATA[转<br />尽管 C 和 C++ 都已经有标准，但是几乎每个编译器 (广义，包含连接器等) 扩展一些 C/C++ 关键字。合理地应用这些关键字，有时候能使我们的工作非常方便。下面随便说说 Visual C++ 中 #pragma 指示符的使用。<br /><div><strong><font size="3">一、用#pragma导出DLL函数</font></strong></div><br /><div>传统的到出 DLL 函数的方法是使用模块定义文件 (.def)，Visual C++ 提供了更简洁方便的方法，那就是“__declspec()”关键字后面跟“dllexport”，告诉连接去要导出这个函数，例如：</div><br /><br /><div style="COLOR: #2222aa; BACKGROUND-COLOR: #f5f5f0"><pre>__declspec(dllexport) int __stdcall MyExportFunction(int iTest);</pre></div><br /><div>把“__declspec(dllexport)”放在函数声明的最前面，连接生成的 DLL 就会导出函数“_MyExportFunction@4”。</div><br /><div>上面的导出函数的名称也许不是我的希望的，我们希望导出的是原版的“MyExportFunction”。还好，VC 提供了一个预处理指示符“#pragma”来指定连接选项 (不仅仅是这一个功能，还有很多指示功能) ，如下：</div><br /><br /><div style="COLOR: #2222aa; BACKGROUND-COLOR: #f5f5f0"><pre>#pragma comment(linker,"/EXPORT:MyExportFunction=_MyExportFunction@4")</pre></div><br /><div>这下就天如人愿了：）。如果你想指定导出的顺序，或者只将函数导出为序号，没有 Entryname，这个预处理指示符 (确切地说是连接器) 都能够实现，看看 MSDN 的语法说明：</div><br /><br /><div style="COLOR: #2222aa; BACKGROUND-COLOR: #f5f5f0"><pre>/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]</pre></div><br /><div>@ordinal 指定顺序；NONAME 指定只将函数导出为序号；DATA 关键字指定导出项为数据项。</div><br /><div><font size="3"><strong>二、指示文件只包含一次</strong></font></div><br /><div>在头文件中，一般在整个工程中我们只要包含一次就够了，但是如果我在多个 .c/.cpp 文件中都要包含着个头文件，比如 Windows.h，那很多声明等等岂不是有两次了？解决这个问题的传统的方法是在头文件开始出用 #define 定义一个宏，比如 Windows.h 中:<br /></div><br /><pre><div style="COLOR: #2222aa; BACKGROUND-COLOR: #f5f5f0"><pre>#ifndef _WINDOWS_<br /> #define _WINDOWS_</pre></div><br /><br /><br /><div>   然后在文件结为加上 #endif，这样就可以避免被包含多次。但是这样的后果是代码的可读性较差 (个人观点)，VC 给我们提供了另外一个途径，那就是在文件的前面加上:</div><br /><br /><br /><br /><br /><br /><div style="COLOR: #2222aa; BACKGROUND-COLOR: #f5f5f0"><pre>#pragma once</pre></div><br /><br /><br /><br /><br /><div>    是不是很方便？</div><br /><br /><br /><br /><br /><div><strong><font size="3">三、使警告无效</font></strong></div><br /><div><strong><font size="3"><br /><div><strong><font size="3"><br /><br /><div>    有时候我们不得不对变量进行强制转换，由此引来编译器的一番警告，特别是 C++ 中，类型检查相对于 C 更为严格。这虽然不影响什么，但是看起来多不爽——我是故意要这样的，你警告什么！：）这时候你看到警告类型，比如“warning C4311: “类型转换” : 从“HHOOK”到“BOOL”的指针截断”，在前面加上:</div><br /><br /><br /><br /><br /><br /><div style="COLOR: #2222aa; BACKGROUND-COLOR: #f5f5f0"><pre>#pragma warning(disable: 4311)</pre></div><br /><br /><br /><div>   编译器就没话说了：）。</div><br /><br /><br /><br /><br /><div><font size="3"><strong>四、指定连接要使用的库</strong></font></div><br /><div><strong><font size="3"><br /><div><strong><font size="3"><br /><div><strong><font size="3"><br /><br /><div>    比如我们连接的时候用到了 WSock32.lib，你当然可以不辞辛苦地把它加入到你的工程中。但是我觉得更方便的方法是使用 #pragma 指示符，指定要连接的库:</div><br /><br /><br /><br /><br /><div style="COLOR: #2222aa; BACKGROUND-COLOR: #f5f5f0"><pre>#pragma comment(lib, "WSock32.lib")</pre></div><br /><br /><br /><div><strong><font size="3"><br /><div><strong><font size="3"><br /><div><strong><font size="3">五、显示编译消息</font></strong></div><br /><div><strong><font size="3"><br />     没多少用处，举个例子吧:<br /><br /><br /><br /><br /><br /><div style="COLOR: #2222aa; BACKGROUND-COLOR: #f5f5f0"><pre>#ifdef _DEBUG<br /> #pragma message("编译连接为调试模式...")<br /> #endif // _DEBUG</pre></div><br /><br /><br /></font></strong></div></font></strong></div></font></strong></div></font></strong></div></font></strong></div></font></strong></div></font></strong></div></font></strong></div></pre><img src ="http://www.cppblog.com/rick/aggbug/14317.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rick/" target="_blank">紫雨轩 C++</a> 2006-10-28 20:01 <a href="http://www.cppblog.com/rick/archive/2006/10/28/14317.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Serv-U配置文件用户密码存储算法 </title><link>http://www.cppblog.com/rick/archive/2006/07/15/9927.html</link><dc:creator>紫雨轩 C++</dc:creator><author>紫雨轩 C++</author><pubDate>Fri, 14 Jul 2006 17:14:00 GMT</pubDate><guid>http://www.cppblog.com/rick/archive/2006/07/15/9927.html</guid><wfw:comment>http://www.cppblog.com/rick/comments/9927.html</wfw:comment><comments>http://www.cppblog.com/rick/archive/2006/07/15/9927.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/rick/comments/commentRss/9927.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rick/services/trackbacks/9927.html</trackback:ping><description><![CDATA[算法如下： <br /><br />先随机取两个任意的小写字符接拼密码，然后取这个字符串的MD5，最后密码就为小写字符拼接整个字符串的MD5。示例如下： <br /><br />me(随机的)+netcat(密码)=&gt;menetcat(随机字符拼接密码)=&gt;39e3d88335cedfd488b5ba2e838d9623(menetcat的MD5码)=&gt;me39e3d88335cedfd488b5ba2e838d9623(netcat的最终加密密码) <br /><br />修改好后在INI文件中的GLOBAL下面加一句ReloadSettings=True（修改好INI后这一句是一定要加的，否则Serv-U程序就不会重新加载新的配置文件了）就行了，一会你再打开这个INI会发现这句已经不见了，那是因为Serv-U的程序已经重新加载INI配置文件后并把这句自动删除了，也就说明你以后每做一次修改都要加上这句话，否则系统就不会重新加载配置文件的。 <br /><br />如果谁要做一个Serv-U的Web管理程序，就可以分析一个这个INI的配置文件，分析一下修改配置后的一些变化规则，然后就可以通过Web程序自己去编辑了。<br /><img src ="http://www.cppblog.com/rick/aggbug/9927.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rick/" target="_blank">紫雨轩 C++</a> 2006-07-15 01:14 <a href="http://www.cppblog.com/rick/archive/2006/07/15/9927.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>utf8 编码方式 </title><link>http://www.cppblog.com/rick/archive/2006/07/15/9925.html</link><dc:creator>紫雨轩 C++</dc:creator><author>紫雨轩 C++</author><pubDate>Fri, 14 Jul 2006 17:13:00 GMT</pubDate><guid>http://www.cppblog.com/rick/archive/2006/07/15/9925.html</guid><wfw:comment>http://www.cppblog.com/rick/comments/9925.html</wfw:comment><comments>http://www.cppblog.com/rick/archive/2006/07/15/9925.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/rick/comments/commentRss/9925.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rick/services/trackbacks/9925.html</trackback:ping><description><![CDATA[编码方式<br />编码方式<br />下面的字节串用来表示一个字符。用什么串依照该字符在 UCS 编码中的序号来定： <br />0x00000000 - 0x0000007F:<br />0xxxxxxx <br />0x00000080 - 0x000007FF:<br />110xxxxx 10xxxxxx <br />0x00000800 - 0x0000FFFF:<br />1110xxxx 10xxxxxx 10xxxxxx <br />0x00010000 - 0x001FFFFF:<br />11110xxx 10xxxxxx 10xxxxxx 10xxxxxx <br />0x00200000 - 0x03FFFFFF:<br />111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx <br />0x04000000 - 0x7FFFFFFF:<br />1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx <br />这里 xxx 的位置二进制位形式的字符编码填入。只用最短的那个足够表达一个字符编码数的多字节串。   <br /><br />举例说明<br />Unicode 字符 0xa9 = 1010 1001 (版权所有的符号) 在 UTF-8 中被编码为： <br /><br />11000010 10101001 = 0xc2 0xa9 <br />字符0x2260 = 0010 0010 0110 0000 (“不等于”符号)被编码为： <br /><br /><br />11100010 10001001 10100000 = 0xe2 0x89 0xa0 <br /><br /><br />''encode - 转成16进制符 <br /><br />For i = 1 To Len(strIN) <br />s = CStr(Hex(Asc(Mid(strIN, i, 1)))) ''是不是太~~~快了~~ <br />If Len(s) = 1 Then s = "0" &amp; s ''解出小于F的值就在前面加 0 <br />strOUT = strOUT &amp; "%" &amp; s <br />Next i <br /><br />txtOUT.Text = strOUT ''这里就是输出了 <br />___________________________________________________________ <br /><br />''decode - 解码, 比较麻烦点 <br /><br />For i = 1 To Len(strIN) Step 3 '' Step 3 因为格式是 %XX 三位一个字符 <br />s1 = UCase(Mid(strIN, i + 1, 1)) ''得到第2位的16进制数字 <br />s2 = UCase(Mid(strIN, i + 2, 1)) ''得到第1位的16进制数字 <br /><br />select Case s1 '' 进制转换 <br />Case "A" To "F" <br />n = (10 + 5 - (Asc("F") - Asc(s1))) * 16 <br />Case Else <br />n = Val(s1) * 16 <br />End select <br /><br />select Case s2 <br />Case "A" To "F" <br />n = n + (10 + 5 - (Asc("F") - Asc(s2))) <br />Case Else <br />n = n + Val(s2) <br />End select <br /><br />s = ChrW$(n) '' 转为字符 <br />strOUT = strOUT &amp; s <br />Next i <br />txtOUT.Text = strOUT <br />  <br /><br />怎么把字符串转成UTF-8格式？？？？  <br /> <br />下面的代码不成功：  <br />WCHAR  wstr[10];  <br />char  cstr[20];  <br />memset(  wstr,  0,  sizeof(wstr)  );  <br />MultiByteToWideChar(CP_UTF8,  0,  "我是小于",  -1,  wstr,  sizeof(wstr));  <br />WideCharToMultiByte(CP_ACP,  0,  wstr,  -1,  cstr,  -1,  "",  0);  <br /> <br />求助。。。。  <br />---------------------------------------------------------------  <br /> <br />int    main(void)      <br />{      <br />           char    str    [    256    ]    =    "唐志国"    ;        //一段UTF-8编码      <br />           WCHAR*    strA;      <br />           int    i=    MultiByteToWideChar    (  CP_ACP      ,    0    ,(char*)    str    ,-1    ,NULL,0);      <br />           strA    =    new    WCHAR[i];      <br />           MultiByteToWideChar    (    CP_ACP    ,    0    ,(    char    *    )    str,    -1,    strA    ,    i);      <br />             <br />           i=    WideCharToMultiByte(CP_UTF8,0,strA,-1,NULL,0,NULL,NULL);      <br />           char    *strB=new    char[i];      <br />           WideCharToMultiByte    (CP_UTF8,0,strA,-1,strB,i,NULL,NULL);      <br />           //strB即为所求      <br />           delete    []strA;      <br />           delete    []strB;      <br />           return    0;      <br />}      <br /> <br />---------------------------------------------------------------  <br /> <br />这是转换函数：  <br />           int            CodePageConvert(UINT  SrcCodePage,  LPCTSTR  pBuff,  int  iBuffLen,  UINT  DestCodePage,  char*  &amp;lpCodePage)  <br />           {  <br />                       int  iWideCharCnt  =  ::MultiByteToWideChar(SrcCodePage,  0,  pBuff,  iBuffLen,  NULL,  0);  <br />                       LPWSTR  lpszWideChar  =  new  wchar_t[iWideCharCnt  +  1];  <br />                       memset(lpszWideChar,  0,  (iWideCharCnt  +  1)  *  sizeof(WCHAR));  <br />                       iWideCharCnt  =  MultiByteToWideChar(SrcCodePage,  0,  pBuff,  iBuffLen,  lpszWideChar,  iWideCharCnt);  <br /> <br />                       if(DestCodePage  ==  54936    <br />                                               &amp;&amp;  !IsValidCodePage(54936))  <br />                                   DestCodePage  =  936;  <br /> <br />                       int  iDestCnt  =  WideCharToMultiByte(DestCodePage,  0,  lpszWideChar,  iWideCharCnt,  NULL,  0,  NULL,  NULL);  <br />                       lpCodePage  =  new  char[iDestCnt  +  1];  <br />                       memset(lpCodePage,  0,  iDestCnt  +  1);  <br />                       iDestCnt  =  WideCharToMultiByte(DestCodePage,  0,  lpszWideChar,  iWideCharCnt,  lpCodePage,  iDestCnt,  NULL,  NULL);  <br /> <br />                       delete  []lpszWideChar;              <br />                       return  iDestCnt;  <br />           }  <br />下面是调用方法：  <br />     utf-8  到  gbk  <br />           int  nLen  =  CodePageConvertUnix("UTF-8",_T("标准"),2,"GBK",lpOut);  <br />     gbk  到utf-8  <br />int  nLen  =  CodePageConvertUnix("UTF-8",_T("标准"),2,"GBK",lpOut);  <br /> <br /><img src ="http://www.cppblog.com/rick/aggbug/9925.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rick/" target="_blank">紫雨轩 C++</a> 2006-07-15 01:13 <a href="http://www.cppblog.com/rick/archive/2006/07/15/9925.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MSN 登录时出现80048820错误的解决方法 </title><link>http://www.cppblog.com/rick/archive/2006/07/15/9922.html</link><dc:creator>紫雨轩 C++</dc:creator><author>紫雨轩 C++</author><pubDate>Fri, 14 Jul 2006 17:09:00 GMT</pubDate><guid>http://www.cppblog.com/rick/archive/2006/07/15/9922.html</guid><wfw:comment>http://www.cppblog.com/rick/comments/9922.html</wfw:comment><comments>http://www.cppblog.com/rick/archive/2006/07/15/9922.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/rick/comments/commentRss/9922.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rick/services/trackbacks/9922.html</trackback:ping><description><![CDATA[早上到公司msn死活登录不上去，报错信息就是80048820错误，狗狗了一下，<br /><br />有一种情况就是是由于你的系统时间不对，先校准系统时间，如果仍然无法登录，可能是由于DLL文件注册信息丢失，下载这个批处理文件 <br /><a href="http://www.msn-problems.com/downloads/register-messenger-dll-files.bat " target="_blank">http://www.msn-problems.com/downloads/ ... ger-dll-files.bat </a>运行一下，问题也可以解决.<br />该bat内容如下.<br />请复制,粘贴到记事本,然后另存为msn.bat或作msn.cmd运行一次就可以了<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">@ECHO OFF<br />ECHO.如果你msn中修复不了就运行吧.<br />ECHO </span><span style="COLOR: #000000">*****************************************************************</span><span style="COLOR: #000000"><br />ECHO </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> This file </span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000"> provided by msn</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">problems.com </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"><br />ECHO </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> Copyright (C) </span><span style="COLOR: #000000">2004</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">2005</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"><br />ECHO </span><span style="COLOR: #000000">*****************************************************************</span><span style="COLOR: #000000"><br />ECHO.<br />ECHO 等一下.<br /><br />REM Following files only needed </span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000"> windows XP<br />IF NOT </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%os%</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Windows_NT</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> GOTO WIN9X<br />regsvr32 Dssenh.dll </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">s<br />regsvr32 Gpkcsp.dll </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">s<br />regsvr32 Slbcsp.dll </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">s<br />regsvr32 Sccbase.dll </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">s<br /><br />:WIN9X<br />IF NOT </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%os%</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Windows_NT</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> CD </span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">windir</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">\System\<br />REM Needed by both XP and 9X<br />regsvr32 Softpub.dll </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">s<br />regsvr32 Wintrust.dll </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">s<br />regsvr32 Initpki.dll </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">s<br />regsvr32 Rsaenh.dll </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">s<br />regsvr32 Mssip32.dll </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">s<br />regsvr32 Cryptdlg.dll </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">s<br />regsvr32 Msxml3.dll </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">s<br />ECHO.<br />ECHO 搞定,还不可以到这网站的论坛询问 www.msn</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">problems.com<br />ECHO.<br />pause<br /></span></div>我用系统的时间同步自动校对时间，下了那个批处理的文件执行，还是不好。<br />不小心把 那个时间同步的勾给去掉了，msn一下就登录上去了。<br />我把msn退出。把时间同步的勾打上。msn还是登录成功了。<br />有点莫名其妙，不过能登陆就算好了。:P<br /><br />在网上还看到两个个性的解决方法，他们都是修改时间，和执行批处理后仍然无法登录的。<br />一个是改 机器 IP后就能登录了。 <img src="http://www.redcheek.net/images/smilies/icon_idea.gif" align="absMiddle" border="0" /><br /><br />另一个是卡巴斯基地病毒库被破坏了，卸载了卡巴斯基换上了最新版本，再次登录MSN发现问题解决了。<br /><br /><strong>今天又遇到这个问题:</strong><br />怎么都登录不上去，<br />后来下载了安装了 msn 8 ，然后运行那个 bat ，就可以登录了。<br /><img src ="http://www.cppblog.com/rick/aggbug/9922.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rick/" target="_blank">紫雨轩 C++</a> 2006-07-15 01:09 <a href="http://www.cppblog.com/rick/archive/2006/07/15/9922.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>