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

<channel>
	<title>Computer, Electron and Technology &#187; lua</title>
	<atom:link href="http://www.donevii.com/post/tag/lua/feed" rel="self" type="application/rss+xml" />
	<link>http://www.donevii.com</link>
	<description>关注技术、移动互联网以及一切 GEEK &#38; NERD 的事情</description>
	<lastBuildDate>Wed, 21 Dec 2011 10:49:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>xcode 中使用 lua 的方法</title>
		<link>http://www.donevii.com/post/912.html</link>
		<comments>http://www.donevii.com/post/912.html#comments</comments>
		<pubDate>Tue, 28 Jul 2009 07:50:31 +0000</pubDate>
		<dc:creator>dengwei</dc:creator>
				<category><![CDATA[software & hardware]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[lua]]></category>

		<guid isPermaLink="false">http://www.donevii.com/post/912.html</guid>
		<description><![CDATA[在 lua maillist 中看到 Hans van der meer 发的一个安装方法。View luaxcode3syntaxcolor-zi... ]]></description>
			<content:encoded><![CDATA[<p>在 <a href="http://www.donevii.com/post/tag/lua" class="st_tag internal_tag" rel="tag" title="Posts tagged with lua">lua</a> maillist 中看到 Hans van der meer 发的一个安装方法。<a href="http://drop.io/v47uqar/asset/luaxcode3syntaxcolor-zip" title="luaxcode3syntaxcolor-zip">View luaxcode3syntaxcolor-zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/912.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一对普通夫妻的欲望人生！</title>
		<link>http://www.donevii.com/post/551.html</link>
		<comments>http://www.donevii.com/post/551.html#comments</comments>
		<pubDate>Wed, 08 Oct 2008 03:11:25 +0000</pubDate>
		<dc:creator>dengwei</dc:creator>
				<category><![CDATA[life]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[女人]]></category>
		<category><![CDATA[女生]]></category>
		<category><![CDATA[生活]]></category>
		<category><![CDATA[男人]]></category>
		<category><![CDATA[男生]]></category>
		<category><![CDATA[类]]></category>

		<guid isPermaLink="false">http://www.donevii.com/post/551.html</guid>
		<description><![CDATA[两人欲望的一生开始了~ 出娘胎 我是BABY我怕谁？ 奇怪的声音 男人是个坏小孩 我爱幼儿园 父母总是唧唧歪歪 我心跳的像鼓 漂亮的胸衣 放学路上的初吻 单车上的爱情 原来你也是个流氓 我的阳... ]]></description>
			<content:encoded><![CDATA[<p>两人欲望的一生开始了~<br />
<font color="#00319c"><br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145190.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
</font><br />
出娘胎<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145189.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我是BABY我怕谁？<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145185.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
奇怪的声音<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145182.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
男人是个坏小孩<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145180.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我爱幼儿园<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145214.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
父母总是唧唧歪歪<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145215.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我心跳的像鼓<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145216.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
漂亮的胸衣<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145217.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
放学路上的初吻<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145218.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
单车上的爱情<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145326.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
原来你也是个流氓<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145327.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我的阳光在别处<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145328.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
冬夜冰凉的梦<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145329.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
礼物<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145330.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
象牙塔里的渴望<br />
被窝里的秘密<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145347.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
<font color="#cccccc"><br />
他的手伸进我上衣里 </font><br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145356.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
<font color="black">人见人爱的大贼船</font><br />
<font color="#00319c"><br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145359.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
</font><br />
<font color="black">爱上我的老师</font></p>
<p><img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145360.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
初夜<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145362.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我怀念和你的初吻，以及那第一夜的秋凉。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145606.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
终于要毕业了，大家每天都沉浸在饭局和泪水之中。借着酒力，我和每一个曾经有过好感的男生拥抱，仿佛他们今生不会再出现在我的生活。马上要离开这个给了我欢喜和忧愁的校园，未知的世界在等着我，未知的男人也在等着我。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145611.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我在北方，你在南方，你说我们的日子还很长，我们读着彼此想念的信，却在别处上着别人的床。人在江湖，蛋不由己，我学会了千奇百怪的姿势，一到晚上就鸡巴瞎忙，谁知道明天会遇到什么姑娘。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145616.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我们从这时开始建立起一种以快乐为宗旨的关系。我们像所有的情人一样，相互交换和分享着快乐、痛苦、失望和期望。谁也没有想过将来要怎么样。我的身体很<br />
好，可是我很喜欢笑着谈论“死”的话题。有一天我说，如果我死了，我只要你一滴眼泪。他笑着捏我的鼻子，说，和我在一起，你怎么会死呢？然后吻我，不让我<br />
说下去。这段关系以我的意外怀孕而告终。当我躺在手术台上结束孩子的生命时，对自己说：“别怕，他会站在手术室外拥抱我的。”但是，他没有出现。我删掉了<br />
他的电话号码，他没必要再出现。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145620.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
<font face="Verdana ">我参加了众多朋友的婚礼，有男有女，每个人脸上都画着希望，据说大学6班的那个荡妇嫁给了一个荣誉军人，而我上铺的兄弟逢人便说娶了一个黄花姑娘。还有几个不断离婚不断再婚的酒友，一边比着谁的年轻老婆更为败家，一边打着没有输赢的上楼麻将。 </font><br />
<font color="#00319c"><font face="Verdana "><br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145624.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
</font><br />
</font><br />
<font face="Verdana ">有一天，我喝了不少酒，打开家门口时已经头疼欲裂，突然有个人在身后出现，一把搂住了我，然后是令我喘不过<br />
气来的强吻。……醉酒之后的**恍如梦中进行的一般，你知道对方在干什么，但是感受是那么的不真实，他进入的时候，我只有被动地接受，一下，两下，三<br />
下……他的动作干脆利落，使我有种被猎获的耻辱感，但是我没法动弹，我不能再给他一个耳光……最后，当克制不住的快感使我颤抖之时，当我忍无可忍终于叫出<br />
声的时候，他狠狠地咬了我一口，然后我听到他说了句：“我爱你。” </font></p>
<p><img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145881.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我只想说：偷来的性高潮，尤其快乐。但是快乐过后的空虚，让我忽然很想念和男人过去的时光。我抽了好几只烟，才放任自己给男人打了一个电话——我说：“我要回到你身旁……”。他竟然答应了，电话那边的声音有点模糊，是他哭了么？<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145884.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
于是，我们走入婚姻的殿堂，父母的笑容，丈母娘的眼泪，同学的唏嘘，前女友的漠然，一切都进行的顺理成章。婚礼上的你我衣冠楚楚，婚纱照上的你我一脸迷茫。那个晚上我们做了很久，我问你是哪里来的人鱼，于是那个夜晚就像童话一样漫长。<br />
　　我们结婚了，所有的婚姻的开始都简单而俗气，嗯，就是这样。只有那个夜晚让我铭记。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145889.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
黎明时传来噩耗，我们结婚时，上铺的兄弟死于布达拉宫边上的澡堂，他死在拉萨的一个姑娘身上，全身赤裸，五指伸长，据说他的灵魂可以得到宽恕，因为他在高潮中离去的时候，双眼正仰望着那湛蓝的天堂。<br />
　　男人的好哥们儿伴着快感死去，或许他是幸福的，我望着身边的这个男人，会不会有一天他也这样离去？<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145903.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
好景不长，一个叫儿子的东西钻出了女人的身体，六斤七两，蛋黑把长，你说这是我们爱的结晶，我想这或许又是噩梦一场，我的父母把弄着孙子的命根，抹着眼泪说咱家从今以后子孙满堂。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145926.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
<font face="Verdana ">我美丽苗条的女人成了宽宽胖胖的孩儿他娘，每天防着儿子在房里叮当乱撞，工作和家庭让我筋疲力尽，每天只想赖在舒服的床。这孩子聪明得像是妖精，刚学会说话就看着电视上一张大脸喊出了张朝阳。<br />
</font><br />
<font color="#00319c"><font face="Verdana "><br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145944.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
</font><br />
</font><br />
<font face="Verdana ">俗话说，女人三十如狼四十如虎，我的女人却像只猛犸象，她不再保持身材，却有着更辣更久的欲望，每当孩子入睡，她就把俺拽向炕角，夜幕下，那是一张略带恐怖的脸庞，只是兄弟我日渐萎靡，不惑之年，胯下已经不再是一杆神枪。<br />
</font><br />
<font color="#00319c"><font face="Verdana "><br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006145948.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
</font><br />
</font><br />
<font face="Verdana ">但随着孩子慢慢长大，我发现欲望就像蛇又回到我的身体，也许是因为孩子在身边，那件事显得有种隐蔽的刺激。我在无限的缠绵中体会婚姻最初的热情，却发现男人的热情好像在渐渐的溜走。是孩子改变了我的身体，或者，是岁月改变了一切？<br />
</font><br />
<font color="#00319c"><font face="Verdana "><br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006146246.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
</font><br />
</font><br />
<font face="Verdana ">上帝保佑，一度皱眉的女人开始再度温柔，因为她的儿子才上小学，那玩意就长得比iphone还长。家长会上，老师说你们的儿子越来越喜欢进女厕所，我亲爱的女人便怒斥他是个文盲。她把我晾在一边，越来越关心儿子在屋里的样子，因此隔三差五才能想起来让我交出公粮。<br />
</font><br />
<font color="#00319c"><font face="Verdana "><br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006146251.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
</font><br />
</font><br />
<font face="Verdana ">残阳如血的某个时刻，我冷冷地笑着，手里有一支抽了一半的香烟。墙上有一个巨大的吊钟，沉默地走着。我觉得有点冷，把男人的毛衣披到了身上。那曾经让我呛的快死过去的烟现在乖乖地呆在我的指尖。<br />
</font><br />
<font color="#00319c"><font face="Verdana "><br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006146254.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
</font><br />
</font><br />
<font face="Verdana ">收拾残躯，重整旗鼓，我所谓的事业突飞猛进，上班大奔，周末公羊，我剥削着500多个城市的白领民工，我买<br />
的中石油终于勃起得硬硬邦邦。我的女人说老公不错，而后把我的钱全存进了她的私人银行。办公室招来了新的小蜜，名叫Janny，前凸后撅，很像我老婆当年<br />
的长相，只是这狐狸精太过放肆，开着董事会都是一副怀春模样。我说着企业战略公司管理，可脑子里禁不住想着她的裙下春光，我像小学生那样坐立不安，我的心<br />
像和女人的第一次那样莺飞草长。<br />
</font><br />
<font color="#00319c"><font face="Verdana "><br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006146267.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
</font></font><br />
电话铃声突然响了起来，一声声如同催命的丧钟。<br />
　　 “对不起，我今天很忙。”他在电话里说，然后是沉默。<br />
　　 “那你忙吧……”挂了电话。我失声痛哭，瘫倒在地毯上。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006146276.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
那天傍晚外边打雷，我在办公室看着云外的夕阳，对天发誓这绝不是预谋，因为今晚还要和老婆去逛商场。Janny不知何时走了进来，说要向我汇报情况，我问<br />
为什么你还不回家，她说回了家也是一个人独守空房。古人云啥也别说了，我们在宽大的办公桌上开辟了战场，奔五张的我竟然梅花三弄金枪不倒，这20岁的姑都<br />
说超爽超爽。<br /><img src="http://img3.pcpop.com/upimg3/2008/10/3/0006146289.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我开始爱上了洗衣服，我想洗去男人衬衫上的陌生香水味，使劲地洗，可总是洗不干净。我把它们放在夏天很刺眼的阳光下晒，可是最后还是会有香水的味道。你的<br />
毛衣，我亲手织的毛衣啊，它们也沾上了永远洗不干净的口红印。这是什么牌子的口红？我想去买一管，因为它是如此的持久。而我的口红却总是在热吻之后消失。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006146653.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
镜子里我的头发仍然乌黑，可那地方的毛却变得花白，女人说显然小头比大头还要操劳，你在外边肯定是男盗女娼。过了60你就一只脚进了棺材，看哪天一条狐狸<br />
把你拉进坟场。对毛主席发誓，我只有那一次意外的疯狂，那狐狸精早已被我赶到深圳，去当了一个做假证老板的新娘。我的前列腺开始出现毛病，看见美女再不会<br />
心荆荡漾。那曾经困惑的欲望终于莫名衰退，估计一年也弄不出精液半两。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006147016.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
除了丈夫和儿子，我有了第3个男人，一个有艺术气质的男人。我们每周约会，然后在潮湿的拥抱中小睡，然后回家。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/3/0006147029.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我的儿子在重复着我的故事，只是他比我当年要厉害百倍，才干工作两年就换了七八个姑娘。他娘说小流氓随了老流氓，我说和谐社会年轻人都在成长。儿子不愿听我们老掉牙的故事，他说这年头女人只认钱，其他的都是逢场作戏嘿咻一场。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/4/0006149135.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我56岁，丈夫开始变乖，除了应酬之外，不再有风花雪月的风流韵事。与此同时，19儿子也有了女朋友和性的秘密。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/4/0006149136.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
那天夜里，我的前列腺疼得要死，我无助地望着透入窗帘的月光，我的眼泪洒在我满是皱纹的手，我的女人却打着呼噜睡在梦乡。我的事业已经让我感到乏味，工商<br />
税务天天把我折腾的神经紧张，我怀念和上铺的兄弟在街边啃煎饼的岁月，我怀念在女生宿舍前哭泣的时光。那一晚我带着眼泪入睡，黑白色的梦里，一树梨花正盛<br />
开在无边的海棠上。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/4/0006149144.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我经常在下午心跳加速，脸上燥热。我知道，自己即将告别卵子这个老朋友。这事儿悄悄来临，就像当年的月经初潮。我无法抗拒，不由得感到一些伤感。丈夫给我买了一些药。随着衰老的到来，他对我的体贴增加。遗憾的是，我们再也无法回到当年的激情。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/4/0006149146.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我老了，不可思议地老了，很多人管我叫大爷，我再也不认为是在骂人。女护士在我身上绑了一个起搏器，我说能否给我下半身也装一个电香肠，小护士说老大爷你<br />
色性难改，我那在轮椅上的老婆说他也就是说说装相。每一个夜晚我都怀疑明天能否醒来，每一个早晨女人都要伏在我的胸膛，他说你可不能走在我的前面，否则夜<br />
里这张床上就会太过冰凉。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/4/0006149206.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
他会在我睡着的午后，静静地看着我，然后在阳光下读一本书。而我则经常在他睡着之后，用手抚摸他的额头。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/4/0006149370.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
<font face="&quot;Verdana ">我的朋友们接二连三地死去，我的儿子仍然在隔三差五地换着姑娘。那一天我看见女人银色的发，在昏黄的灯下<br />
发着晶莹的光，我突然发现我是如此爱着这个女人，我突然后悔没有把所有的激情都留给她的欲望。如今我只能每天抚摸着她干枯的手和银色的发，问她是否喜欢那<br />
风雨后宁静的阳光。 </font></p>
<p><img src="http://img3.pcpop.com/upimg3/2008/10/4/0006149371.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
19岁的儿子去大学住校前，我最后一次给儿子洗内裤。阳光下，上面的存留物质闪闪发亮。那东西有着特殊的气味，在每个人的鼻子下，是不一样的。这是我的告别礼。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/4/0006149373.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
儿子终于有了他的合法配偶，她长得像卖人肉包子的孙二，女人整天在偷偷哭泣，说她心疼咱们的儿子，怎么他就取回来这么个蛮横糟糠。我倒不觉得儿子是吃错了药，那女人一定在床上特别擅长，他们的生活犹如黄钟大吕，整天把席梦思整的兵兵邦邦。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/4/0006149374.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
62岁，儿子结婚了，而我开始信仰宗教。《圣经》是一本有趣的书。因为它不仅仅是关于神的，其实，也是关于性的。性让亚当和夏娃繁衍了人类；淫亵的性让上<br />
帝毁灭了人类；luanlun的性让罗得的女儿们延续了人类……只要有人的地方，有男女的地方，必然有性。我虽然已经逐渐告别性生活，但我却发现了有趣的<br />
性理论。尤其当我从《圣经》感受到宗教对于性的神秘诠释之后，觉得无比欢喜。我要赞美主，赞美神，赞美生活，赞美……性。也许这就是人生，当你告别一件东<br />
西，才越发觉出它的美好。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/5/0006153661.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
好在这媳妇还算踏实，很快就生出一个孩子，女人上前翻了半天，脸色阴沉，跟我说她的心拔凉拔凉。这孩子再不会蛋黑把长，因为她根本就没长出那么个鸟样。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/5/0006153676.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
<font face="&quot;Verdana ">68岁的我，当了祖母。那个时候我正在家里煮着鸡汤，丈夫在客厅接了电话，儿子告诉他，我们刚刚有了第三<br />
代。我迫不及待地赶去医院，满心欢喜地要看看他的把儿有多长，可事实却让我那么的失望，虽然她也长得像天使一样可爱。然而，这孩子却不再蛋黒把长，真的，<br />
别怪我重男轻女，那是不一样的滋味。 </font></p>
<p><img src="http://img3.pcpop.com/upimg3/2008/10/5/0006153680.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
经常路过我家门口的那只老猫再没出现，想必是不知老死在哪个垃圾场。我连下床都变得艰难，可我亲爱的女人竟然又能下地，她说她梦见了少年时的我，拉着她跑过一片片红色的高粱。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/5/0006153683.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我们都老了，我明显地觉得腿脚不如从前，爬楼的时候是那么的吃力，而我的男人连下床都很困难。我爱上了回忆，无论是白天还是梦里，我想着男人，也想着记忆中曾经说过爱我的那些男人，偶尔竟然会有想要的欲望。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/5/0006153687.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
那天她帮我洗澡，在温暖的浴缸里，她的手温柔地抚过我的身体，我惊讶地发现那个东西竟然翘起，我浑身都有要飞的轻畅。女人说你个老鬼还不正经，当心摧毁你<br />
那脆弱的心脏。我笑着答看来杨振宁也不过如此，没准我是比他还要好使的一把老枪。女人爱抚地摸着那个东西，眼角竟有了淡淡的泪光，她说如果你愿意，我们就<br />
玩儿命再干上最后一场。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/6/0006158903.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
男人已经一周没有洗澡，我搀扶他坐进浴缸，摸着他依然厚实的肩膀，内心里多了些许的感伤，这是我守了大半辈子的男人，可总有一天我们要各自奔天堂。男人不顾死活地要重拾起他那把老枪，而这一次也成就了我们一生的最难忘。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/6/0006158918.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
那最后一次的激情险些要了我的老命，可我们的行为却遭到了儿女的强烈表扬，儿子说老爸你真了不起，都站不起来了竟还能跃马拧枪。媳妇说你们真是夫妻楷模，<br />
应该上CCTV说一下事后感想。这疯狂的代价是在医院半年的休养，等出院时，我已经离不开手上那根难看的拐杖。女人问我后不后悔，我说这是我一辈子最高兴<br />
的时光，如果那一天我真的去了，我也会笑着走进满是美女的天堂。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/6/0006158944.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
男人住院了，毕竟已是70几岁的人，哪经得住那样的疯狂。儿孙每日奔波于医院和家，而我也会为他煲上一锅汤。我依然终日沉浸在回忆之中，不久于世的伤感让<br />
我渴望听到那些曾经跟我耳鬓厮磨过的声音。颤抖地拿起电话，一通、两通、三通…那些给过我高潮的男人们却都已经离开了这个美丽的人间。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/6/0006158964.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我终于彻底死心，全心全意地迎接我出院归来的男人。我们又仿佛回到少年时的模样，每天拉着手慢慢地走在路上，说着只有我俩才懂的情伤。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/6/0006160363.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
从此我们再无遗憾，我们每天拉着手，满意地坐在门口的摇椅上，门口来了新的小猫，它喜欢抱着我们的腿，舔着我们的手，扑着天空里飞舞的豆娘。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/6/0006160328.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
不知不觉我们的孙女又生了一个大胖小子，我们家竟然已经四世同堂。已经要瞎眼的女人大声说赶紧看看那玩意儿究竟什么成色，孙女婿说是白花花的一串，有点像<br />
老头花生的怪样。女人嘟囔着说这小子不是男人，将来很可能窝窝囊囊。我说你干吗操这一百年后的心，眼都瞎了还惦记着那玩意多黑多长。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/6/0006160370.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
92岁，我有了重孙子，我们家竟然已经四世同堂。但是我已经看不清那孩子什么模样。孩子刚学会走路不久，男人在一次踏青中脑溢血住进了重症病房。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/6/0006160374.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
那天我们依然在一起晒着太阳，刚会走路的重孙子向我伸出小手，我猜是他想让我帮他撒尿，就挣扎起来要把他抱上。我的眼前突然发黑，然后跟着掠起一片白光。醒来时我已经躺倒在地，孩子的温暖的尿正呲在我的脸上，我想喊我的女人，可却不忍打搅她的梦乡。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/6/0006160385.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
我知道这颗心脏就要停止跳动，可我宁愿如此，默默地去寻找传说中的天堂。那孩子哭着叫着，我只微笑着看着他颤巍巍的小鸡鸡，轻声说孩子别怕，老爷爷就此去了，你的路还有很长，很长……<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/6/0006160826.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
男人终于弃我而去。作为一个女人，我的一生如此丰富。有激情，有痛苦，有欢乐，有眼泪。作为一个女人，我也许不是规矩和忠诚的。但我忠于自己的身体，和自<br />
己的欲望；我对得起自己，也不想伤害别人。如果我做的不够好，请原谅。我，只是个最普通不过的女人而已。说不定，如我这样的女人，应该也可以上天堂。<br />
<img src="http://img3.pcpop.com/upimg3/2008/10/6/0006160844.jpg" onclick="zoom(this)" onload="attachimg(this, 'load')" alt="" border="0" /><br />
这是一个美好的春天，但我想我该走了——病房里洁白安静，空气里有消毒水的芬芳。我翻阅着记忆的相册，想起，想起我的男人，想起经济系男生、艺术史老师、想起我的那个他不曾知道，而且永远也不会知道了的情人……</p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/551.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GTA:SA 全部秘籍收藏</title>
		<link>http://www.donevii.com/post/331.html</link>
		<comments>http://www.donevii.com/post/331.html#comments</comments>
		<pubDate>Thu, 24 May 2007 12:19:51 +0000</pubDate>
		<dc:creator>dengwei</dc:creator>
				<category><![CDATA[life]]></category>
		<category><![CDATA[gta]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[收藏]]></category>
		<category><![CDATA[秘籍]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=331</guid>
		<description><![CDATA[LXGIWYL = 暴徒武器KJKSZPJ = 专业武器UZUMYMW = 疯狂武器HESOYAM = 生命、护甲满，加25万美圆OSRBLHH = 增加两星通缉度ASNAEB = 清除通缉程度AFZLLQLL = 万里无云ICIKPYH = 阳光明媚ALNSFMZO = 阴云密布AUIFRVQS = 阴雨... ]]></description>
			<content:encoded><![CDATA[<p>LXGIWYL = 暴徒武器<br />KJKSZPJ = 专业武器<br />UZUMYMW = 疯狂武器<br />HESOYAM = 生命、护甲满，加25万美圆<br />OSRBLHH = 增加两星通缉度<br />ASNAEB = 清除通缉程度<br />AFZLLQLL = 万里无云<br />ICIKPYH = 阳光明媚<br />ALNSFMZO = 阴云密布<br />AUIFRVQS = 阴雨绵绵<br />CFVFGMJ = 大雾弥漫<br />YSOHNUL = 时钟加快<br />PPGWJHT = 操控加快<br />LIYOAAY = 操控减慢<br />AJLOJYQY = 行人互相攻击，得到高尔夫球杆<br />BAGOWPG = 得到一大笔奖励<br />FOOOXFT = 行人全副武装<br />AIWPRTON = 刷新一辆坦克<br />CQZIJMB = 刷新一辆Bloodring Banger<br />JQNTDMH = 刷新一辆Rancher<br />PDNEJOH = 刷新一辆Racecar<br />VPJTQWV = 刷新一辆Racecar<br />AQTBCODX = 刷新一辆Romero<br />KRIJEBR = 刷新一辆Stretch<br />UBHYZHQ = 刷新一辆Trashmaster<br />RZHSUEW = 刷新一辆Caddy<br />CPKTNWT = Cars所有车辆爆炸<br />XICWMD = 隐行车辆<br />PGGOMOY = 完美操控<br />SZCMAWO = 自杀<br />ZEIIVG = 交通信号灯变绿<br />YLTEICZ = 司机有攻击性<br />LLQPFBN = 所有车辆变粉色<br />IOWDLAC = 所有车辆变黑色<br />AFSNMSMW = 船只飞行<br />BTCDBCB = 主角变胖<br />JYSDSOD = 主角肌肉值最大<br />KVGYZQK = 主角变得皮包骨<br />ASBHGRB = 行人变成猫王<br />BGLUAWML = 行人用武器攻击你，得到火箭发射器<br />CIKGCGX = 海滩聚会<br />MROEMZH = 到处都是黑帮<br />BIFBUZZ = 黑帮控制街道<br />AFPHULTL = 忍者模式<br />BEKKNQV = 吸引女<br />BGKGTJH = 通工具慢速<br />GUSNHDE = 交通工具快速<br />RIPAZHA = 汽车飞行<br />JHJOECW = 超级兔子跳<br />JUMPJET = 刷新一辆Hydra<br />KGGGDKP = 刷新一辆Vortex Hovercraft<br />JCNRUAD = 汽车一击必炸<br />COXEFGU = 所有车辆得到一氧化二氮加速剂<br />BSXSGGC = 车辆被撞击时会漂浮<br />XJVSNAJ = 永远是午夜<br />OFVIAC = 永远是晚上9点<br />MGHXYRM = 雷暴天气<br />CWJXUOC = 沙尘暴天气<br />LFGMHAL = 超级跳跃<br />BAGUVIX = 无限生命<br />CVWKXAM = 无限氧气<br />AIYPWZQP = 得到降落伞<br />BAGUVIX = 无限生命<br />AEZAKMI = 永远不会被通缉<br />WANRLTW = 无限弹药，不用换弹夹<br />IAVENJQ = 超级攻击<br />JCNRUAD = 汽车一击必炸 </p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/331.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[超长篇] Inject Your Code to a Portable Executable File</title>
		<link>http://www.donevii.com/post/330.html</link>
		<comments>http://www.donevii.com/post/330.html#comments</comments>
		<pubDate>Thu, 24 May 2007 07:50:01 +0000</pubDate>
		<dc:creator>dengwei</dc:creator>
				<category><![CDATA[doc]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ror]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=330</guid>
		<description><![CDATA[转至: http://www.codeguru.com/cpp/w-p/system/misc/article.php/c11393 Downloads pemaker1.zip &#8211; pemaker2.zip &#8211; pemaker3.zip &#8211; pemaker4.zip &#8211; pemaker5.zip &#8211; peviewer.zip &#8211; test1.zip &#8211; Windows NT 3.51 (I mean, Win3... ]]></description>
			<content:encoded><![CDATA[<p>转至: <a href="http://www.codeguru.com/cpp/w-p/system/misc/article.php/c11393">http://www.codeguru.com/cpp/w-p/system/misc/article.php/c11393</a></p>
<p><strong>Downloads</strong></p>
<li><a href="http://www.codeguru.com/dbfiles/get_file/pemaker1.zip?id=11393&amp;lbl=PEMAKER1_ZIP&amp;ds=20060302">pemaker1.zip</a> &#8211; </li>
<li><a href="http://www.codeguru.com/dbfiles/get_file/pemaker2.zip?id=11393&amp;lbl=PEMAKER2_ZIP&amp;ds=20060302">pemaker2.zip</a> &#8211; </li>
<li><a href="http://www.codeguru.com/dbfiles/get_file/pemaker3.zip?id=11393&amp;lbl=PEMAKER3_ZIP&amp;ds=20060302">pemaker3.zip</a> &#8211; </li>
<li><a href="http://www.codeguru.com/dbfiles/get_file/pemaker4.zip?id=11393&amp;lbl=PEMAKER4_ZIP&amp;ds=20060302">pemaker4.zip</a> &#8211; </li>
<li><a href="http://www.codeguru.com/dbfiles/get_file/pemaker5.zip?id=11393&amp;lbl=PEMAKER5_ZIP&amp;ds=20060302">pemaker5.zip</a> &#8211; </li>
<li><a href="http://www.codeguru.com/dbfiles/get_file/peviewer.zip?id=11393&amp;lbl=PEVIEWER_ZIP&amp;ds=20060302">peviewer.zip</a> &#8211; </li>
<li><a href="http://www.codeguru.com/dbfiles/get_file/test1.zip?id=11393&amp;lbl=TEST1_ZIP&amp;ds=20060302">test1.zip</a> &#8211; </li>
<p><a name="more"><font color="#000000"></font></a><a href="http://en.wikipedia.org/wiki/Windows_NT_3.51" target="new">Windows NT 3.51</a> (I mean, <a href="http://en.wikipedia.org/wiki/Windows_3.1" target="new">Win3.1</a>, <a href="http://en.wikipedia.org/wiki/Windows_95" target="new">Win95</a>, <a href="http://en.wikipedia.org/wiki/Windows_98" target="new">Win98</a> were not perfect <a href="http://en.wikipedia.org/wiki/Operating_System" target="new">OS</a>s). The MS-DOS data causes that your executable file to have the performance inside MS-DOS and <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_core_.2f.stub.asp" target="new">the MS-DOS Stub program</a> lets it display: <strong>&quot;This program can not be run in MS-DOS mode&quot;</strong> or <strong>&quot;This program can be run only in <a href="http://www.donevii.com/post/tag/windows" class="st_tag internal_tag" rel="tag" title="Posts tagged with windows">Windows</a> mode&quot;</strong>, or some things like these comments when you try to run a Windows EXE file inside <a href="http://en.wikipedia.org/wiki/MS-DOS" target="new">MS-DOS 6.0</a>, where there is no footstep of Windows. Thus, this data is reserved for the code to indicate these comments in the <a href="http://en.wikipedia.org/wiki/MS-DOS" target="new">MS-DOS</a> <a href="http://en.wikipedia.org/wiki/Operating_System" target="new">operating system</a>. The most interesting part of the <a href="http://en.wikipedia.org/wiki/MS-DOS" target="new">MS-DOS</a> data is &quot;<strong>MZ</strong>&quot;! Can you believe, it refers to the name of &quot;<a href="http://en.wikipedia.org/wiki/Mark_Zbikowski" target="new">Mark Zbikowski</a>&quot;, one of the first Microsoft programmers?</p>
<p><font color="#000000"><img height="175" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=PEMAKER_GIF&amp;ds=20060302" width="452" alt="" /></font></p>
<h3>0 Preface</h3>
<p>You might demand to comprehend the ways a virus program injects its procedure into the interior of a portable executable file and corrupts it, or you are interested in implementing a packer or a protector to encrypt the data of your portable executable (PE) file. This article is committed to represent a brief discussion to realize the performance that is accomplished by EXE tools or some kinds of mal-ware.</p>
<p>You can employ this article&#8217;s source code to create your custom EXE builder. It could be used to make an EXE protector in the right way, or with the wrong intention, to spread a virus. However, my purpose of writing this article has been the first application, so I will not be responsible for the immoral usage of these methods.</p>
<h3>1 Prerequisites</h3>
<p>There are no specific mandatory prerequisites to follow the topics in this article. If you are familiar with a debugger and also the portable file format, I suggest you to drop to Sections 2 and 3; the whole of these sections has been made for people who don&#8217;t have any knowledge regarding the EXE file format or debuggers.</p>
<h3>2 Portable Executable File Format</h3>
<p>The Portable Executable file format was defined to provide the best way for the Windows Operating System to execute code and also to store the essential data that is needed to run a program&mdash;for example constant data, variable data, import library links, and resource data. It consists of MS-DOS file information, Windows NT file information, Section Headers, and Section images, as shown in Table 1.</p>
<h4>2.1 The MS-DOS data</h4>
<p>These data let you remember the first days of developing the Windows Operating System. You were at the beginning of a way to achieve a complete Operating System such as </p>
<p>To me, only the offset of the PE signature in the <a href="http://en.wikipedia.org/wiki/MS-DOS" target="new">MS-DOS</a> data is important, so I can use it to find the position of the <a href="http://en.wikipedia.org/wiki/Windows_NT" target="new">Windows NT</a> data. I just recommend that you take a look at Table 1, and then observe the structure of <tt>IMAGE_DOS_HEADER</tt> in the <em>&lt;winnt.h&gt;</em> header in the <em>&lt;Microsoft Visual Studio .net path&gt;\VC7\PlatformSDK\include\</em> folder or the <em>&lt;Microsoft Visual Studio 6.0 path&gt;\VC98\include\</em> folder. I do not know why the Microsoft team has forgotten to provide some comment about this structure in the <a href="http://msdn.microsoft.com/" target="new">MSDN</a> library!</p>
<pre><span class="codeKeyword">typedef</span> <span class="codeKeyword">struct</span> _IMAGE_DOS_HEADER { <span class="codeComment">// DOS .EXE header &quot;MZ&quot;</span>    WORD   e_magic;                <span class="codeComment">// Magic number</span>    WORD   e_cblp;                 <span class="codeComment">// Bytes on last page of file</span>    WORD   e_cp;                   <span class="codeComment">// Pages in file</span>    WORD   e_crlc;                 <span class="codeComment">// Relocations</span>    WORD   e_cparhdr;              <span class="codeComment">// Size of header in</span>                                   <span class="codeComment">// paragraphs</span>    WORD   e_minalloc;             <span class="codeComment">// Minimum extra paragraphs</span>                                   <span class="codeComment">// needed</span>    WORD   e_maxalloc;             <span class="codeComment">// Maximum extra paragraphs</span>                                   <span class="codeComment">// needed</span>    WORD   e_ss;                   <span class="codeComment">// Initial (relative) SS</span>                                   <span class="codeComment">// value</span>    WORD   e_sp;                   <span class="codeComment">// Initial SP value</span>    WORD   e_csum;                 <span class="codeComment">// Checksum</span>    WORD   e_ip;                   <span class="codeComment">// Initial IP value</span>    WORD   e_cs;                   <span class="codeComment">// Initial (relative) CS</span>                                   <span class="codeComment">// value</span>    WORD   e_lfarlc;               <span class="codeComment">// File address of relocation</span>                                   <span class="codeComment">// table</span>    WORD   e_ovno;                 <span class="codeComment">// Overlay number</span>    WORD   e_res[4];               <span class="codeComment">// Reserved words</span>    WORD   e_oemid;                <span class="codeComment">// OEM identifier</span>                                   <span class="codeComment">// (for e_oeminfo)</span>    WORD   e_oeminfo;              <span class="codeComment">// OEM information;</span>                                   <span class="codeComment">// e_oemid specific</span>    WORD   e_res2[10];             <span class="codeComment">// Reserved words</span>    LONG   <font color="#ff0000">e_lfanew</font>;               <span class="codeComment">// File address of the new</span>                                   <span class="codeComment">// exe header</span>  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;</pre>
<p><tt>e_lfanew</tt> is the offset that refers to the position of the Windows NT data. I have provided a program to obtain the header information from an EXE file and to display it to you. To use the program, just try:</p>
<h4>PE Viewer</h4>
<p><img height="314" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=PEVIEWER1_GIF&amp;ds=20060302" width="491" alt="" /></p>
<p><img height="363" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=PEVIEWER2_GIF&amp;ds=20060302" width="500" alt="" /><br />(<a href="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=PEVIEWER2_GIF&amp;ds=20060302" target="_blank">Full Size Image</a>)</p>
<p><img height="313" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=PEVIEWER3_GIF&amp;ds=20060302" width="500" alt="" /><br />(<a href="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=PEVIEWER3_GIF&amp;ds=20060302" target="_blank">Full Size Image</a>)</p>
<p>This sample is useful for the whole of this article.</p>
<p><strong>Table 1:</strong> Portable Executable file format structure</p>
<p>
<table cellspacing="2" cellpadding="2" border="2">
<tbody>
<tr valign="top">
<td rowspan="17">MS-DOS <br />            information</td>
<td rowspan="16"><tt>IMAGE_DOS_<br />            HEADER</tt></td>
<td>DOS EXE Signature</td>
<td rowspan="16">
<pre lang="text">00000000  ASCII <font color="#008000">&quot;MZ&quot;</font>00000002  DW 009000000004  DW 000300000006  DW 000000000008  DW 00040000000A  DW 00000000000C  DW FFFF0000000E  DW 000000000010  DW 00B800000012  DW 000000000014  DW 000000000016  DW 000000000018  DW 00400000001A  DW 00000000001C  DB 00b&amp;b&amp;0000003B  DB 000000003C  DD <font color="#ff0000">000000F0</font></pre>
</td>
</tr>
<tr valign="top">
<td><tt>DOS_PartPag</tt></td>
</tr>
<tr valign="top">
<td><tt>DOS_PageCnt</tt></td>
</tr>
<tr valign="top">
<td><tt>DOS_ReloCnt</tt></td>
</tr>
<tr valign="top">
<td><tt>DOS_HdrSize</tt></td>
</tr>
<tr valign="top">
<td><tt>DOS_MinMem</tt></td>
</tr>
<tr valign="top">
<td><tt>DOS_MaxMem</tt></td>
</tr>
<tr valign="top">
<td><tt>DOS_ReloSS</tt></td>
</tr>
<tr valign="top">
<td><tt>DOS_ExeSP</tt></td>
</tr>
<tr valign="top">
<td><tt>DOS_ChkSum</tt></td>
</tr>
<tr valign="top">
<td><tt>DOS_ExeIPP</tt></td>
</tr>
<tr valign="top">
<td><tt>DOS_ReloCS</tt></td>
</tr>
<tr valign="top">
<td><tt>DOS_TablOff</tt></td>
</tr>
<tr valign="top">
<td><tt>DOS_Overlay</tt></td>
</tr>
<tr valign="top">
<td><tt>b&amp;<br />            </tt>Reserved words<tt><br />            b&amp;</tt></td>
</tr>
<tr valign="top">
<td>Offset to PE signature</td>
</tr>
<tr valign="top">
<td>MS-DOS Stub <br />            Program</td>
<td colspan="2">
<pre lang="text">00000040  ..B:..B4.C!B8\LC!<font color="#008000">This program canno</font>00000060  <font color="#008000">t be run in DOS mode.</font>...$.......</pre>
</td>
</tr>
<tr valign="top">
<td rowspan="54">Windows NT <br />            information
<p><tt>IMAGE_<br />            NT_HEADERS</tt></p>
</td>
<td>Signature</td>
<td>PE signature (PE)</td>
<td>
<pre lang="text"><font color="#ff0000">000000F0</font>  ASCII <font color="#008000">&quot;PE&quot;</font></pre>
</td>
</tr>
<tr valign="top">
<td rowspan="7"><tt>IMAGE_<br />            FILE_HEADER</tt></td>
<td><tt>Machine</tt></td>
<td rowspan="7">
<pre lang="text">000000F4  DW 014C000000F6  DW 0003000000F8  DD 3B7D8410000000FC  DD 0000000000000100  DD 0000000000000104  DW 00E000000106  DW 010F</pre>
</td>
</tr>
<tr valign="top">
<td><tt>NumberOfSections</tt></td>
</tr>
<tr valign="top">
<td><tt>TimeDateStamp</tt></td>
</tr>
<tr valign="top">
<td><tt>PointerToSymbolTable</tt></td>
</tr>
<tr valign="top">
<td><tt>NumberOfSymbols</tt></td>
</tr>
<tr valign="top">
<td><tt>SizeOfOptionalHeader</tt></td>
</tr>
<tr valign="top">
<td><tt>Characteristics</tt></td>
</tr>
<tr valign="top">
<td rowspan="46"><tt>IMAGE_<br />            OPTIONAL_<br />            HEADER32</tt></td>
<td><tt>MagicNumber</tt></td>
<td rowspan="30">
<pre lang="text">00000108  DW 010B0000010A  DB 070000010B  DB 000000010C  DD 0001280000000110  DD 00009C0000000114  DD 0000000000000118  DD 000124750000011C  DD 0000100000000120  DD 0001400000000124  DD 0100000000000128  DD 000010000000012C  DD 0000020000000130  DW 000500000132  DW 000100000134  DW 000500000136  DW 000100000138  DW 00040000013A  DW 00000000013C  DD 0000000000000140  DD 0001F00000000144  DD 0000040000000148  DD 0001D7FC0000014C  DW 00020000014E  DW 800000000150  DD 0004000000000154  DD 0000100000000158  DD 001000000000015C  DD 0000100000000160  DD 0000000000000164  DD 00000010</pre>
</td>
</tr>
<tr valign="top">
<td><tt>MajorLinkerVersion</tt></td>
</tr>
<tr valign="top">
<td><tt>MinorLinkerVersion</tt></td>
</tr>
<tr valign="top">
<td><tt>SizeOfCode</tt></td>
</tr>
<tr valign="top">
<td><tt>SizeOfInitializedData</tt></td>
</tr>
<tr valign="top">
<td><tt>SizeOfUninitializedData</tt></td>
</tr>
<tr valign="top">
<td><tt>AddressOfEntryPoint</tt></td>
</tr>
<tr valign="top">
<td><tt>BaseOfCode</tt></td>
</tr>
<tr valign="top">
<td><tt>BaseOfData</tt></td>
</tr>
<tr valign="top">
<td><tt>ImageBase</tt></td>
</tr>
<tr valign="top">
<td><tt>SectionAlignment</tt></td>
</tr>
<tr valign="top">
<td><tt>FileAlignment</tt></td>
</tr>
<tr valign="top">
<td><tt>MajorOSVersion</tt></td>
</tr>
<tr valign="top">
<td><tt>MinorOSVersion</tt></td>
</tr>
<tr valign="top">
<td><tt>MajorImageVersion</tt></td>
</tr>
<tr valign="top">
<td><tt>MinorImageVersion</tt></td>
</tr>
<tr valign="top">
<td><tt>MajorSubsystemVersion</tt></td>
</tr>
<tr valign="top">
<td><tt>MinorSubsystemVersion</tt></td>
</tr>
<tr valign="top">
<td><tt>Reserved</tt></td>
</tr>
<tr valign="top">
<td><tt>SizeOfImage</tt></td>
</tr>
<tr valign="top">
<td><tt>SizeOfHeaders</tt></td>
</tr>
<tr valign="top">
<td><tt>CheckSum</tt></td>
</tr>
<tr valign="top">
<td><tt>Subsystem</tt></td>
</tr>
<tr valign="top">
<td><tt>DLLCharacteristics</tt></td>
</tr>
<tr valign="top">
<td><tt>SizeOfStackReserve</tt></td>
</tr>
<tr valign="top">
<td><tt>SizeOfStackCommit</tt></td>
</tr>
<tr valign="top">
<td><tt>SizeOfHeapReserve</tt></td>
</tr>
<tr valign="top">
<td><tt>SizeOfHeapCommit</tt></td>
</tr>
<tr valign="top">
<td><tt>LoaderFlags</tt></td>
</tr>
<tr valign="top">
<td><tt>NumberOfRvaAndSizes</tt></td>
</tr>
<tr valign="top">
<td rowspan="16"><tt>IMAGE_<br />            DATA_DIRECTORY[16]</tt></td>
<td>Export Table</td>
</tr>
<tr valign="top">
<td>Import Table</td>
</tr>
<tr valign="top">
<td>Resource Table</td>
</tr>
<tr valign="top">
<td>Exception Table</td>
</tr>
<tr valign="top">
<td>Certificate File</td>
</tr>
<tr valign="top">
<td>Relocation Table</td>
</tr>
<tr valign="top">
<td><a href="http://www.donevii.com/post/tag/debug" class="st_tag internal_tag" rel="tag" title="Posts tagged with debug">Debug</a> Data</td>
</tr>
<tr valign="top">
<td>Architecture Data</td>
</tr>
<tr valign="top">
<td>Global Ptr</td>
</tr>
<tr valign="top">
<td>TLS Table</td>
</tr>
<tr valign="top">
<td>Load Config Table</td>
</tr>
<tr valign="top">
<td>Bound Import Table</td>
</tr>
<tr valign="top">
<td>Import Address Table</td>
</tr>
<tr valign="top">
<td>Delay Import Descriptor</td>
</tr>
<tr valign="top">
<td>COM+ Runtime Header</td>
</tr>
<tr valign="top">
<td>Reserved</td>
</tr>
<tr valign="top">
<td rowspan="13">Sections <br />            information</td>
<td rowspan="10"><tt>IMAGE_<br />            SECTION_<br />            HEADER[0]</tt></td>
<td><tt>Name[8]</tt></td>
<td rowspan="10">
<pre lang="text">000001E8  ASCII<font color="#008000">&quot;.text&quot;</font>000001F0  DD 000126B0000001F4  DD 00001000000001F8  DD 00012800000001FC  DD 0000040000000200  DD 0000000000000204  DD 0000000000000208  DW 00000000020A  DW 00000000020C  DD 60000020    CODE|EXECUTE|READ</pre>
</td>
</tr>
<tr valign="top">
<td><tt>VirtualSize</tt></td>
</tr>
<tr valign="top">
<td><tt>VirtualAddress</tt></td>
</tr>
<tr valign="top">
<td><tt>SizeOfRawData</tt></td>
</tr>
<tr valign="top">
<td><tt>PointerToRawData</tt></td>
</tr>
<tr valign="top">
<td><tt>PointerToRelocations</tt></td>
</tr>
<tr valign="top">
<td><tt>PointerToLineNumbers</tt></td>
</tr>
<tr valign="top">
<td><tt>NumberOfRelocations</tt></td>
</tr>
<tr valign="top">
<td><tt>NumberOfLineNumbers</tt></td>
</tr>
<tr valign="top">
<td><tt>Characteristics</tt></td>
</tr>
<tr valign="top">
<td><tt>b&amp;<br />            b&amp;<br />            b&amp;<br />            IMAGE_<br />            SECTION_<br />            HEADER[n]</tt></td>
<td colspan="2">
<pre lang="text">00000210  ASCII<font color="#008000">&quot;.data&quot;</font>; SECTION00000218  DD 0000101C ; VirtualSize = 0x101C0000021C  DD 00014000 ; VirtualAddress = 0x1400000000220  DD 00000A00 ; SizeOfRawData = 0xA0000000224  DD 00012C00 ; PointerToRawData = 0x12C0000000228  DD 00000000 ; PointerToRelocations = 0x00000022C  DD 00000000 ; PointerToLineNumbers = 0x000000230  DW 0000     ; NumberOfRelocations = 0x000000232  DW 0000     ; NumberOfLineNumbers = 0x000000234  DD C0000040 ; Characteristics =                        INITIALIZED_DATA|READ|WRITE00000238  ASCII<font color="#008000">&quot;.rsrc&quot;</font>; SECTION00000240  DD 00008960 ; VirtualSize = 0x896000000244  DD 00016000 ; VirtualAddress = 0x1600000000248  DD 00008A00 ; SizeOfRawData = 0x8A000000024C  DD 00013600 ; PointerToRawData = 0x1360000000250  DD 00000000 ; PointerToRelocations = 0x000000254  DD 00000000 ; PointerToLineNumbers = 0x000000258  DW 0000     ; NumberOfRelocations = 0x00000025A  DW 0000     ; NumberOfLineNumbers = 0x00000025C  DD 40000040 ; Characteristics =                        INITIALIZED_DATA|READ</pre>
</td>
</tr>
<tr valign="top">
<td><tt>SECTION[0]</tt></td>
<td colspan="2">
<pre lang="text">00000400  EA 22 DD 77 D7 23 DD 77  C*&quot;C.wC.#C.w00000408  9A 18 DD 77 00 00 00 00  E!.C.w....00000410  2E 1E C7 77 83 1D C7 77  ..C.wF..C.w00000418  FF 1E C7 77 00 00 00 00  C?.C.w....00000420  93 9F E7 77 D8 05 E8 77  b.E8C'wC..C(w00000428  FD A5 E7 77 AD A9 E9 77  C=B%C'w&amp;shy;B)C)w00000430  A3 36 E7 77 03 38 E7 77  B#6C'w.8C'w00000438  41 E3 E6 77 60 8D E7 77  AC#C&amp;w`BC'w00000440  E6 1B E6 77 2B 2A E7 77  C&amp;.C&amp;w+*C'w00000448  7A 17 E6 77 79 C8 E6 77  z.C&amp;wyC.C&amp;w00000450  14 1B E7 77 C1 30 E7 77  ..C'wC.0C'wb&amp;</pre>
</td>
</tr>
<tr valign="top">
<td><tt>b&amp;<br />            b&amp;<br />            b&amp;<br />            SECTION[n]</tt></td>
<td colspan="2">
<pre lang="text">b&amp;0001BF00  63 00 2E 00 63 00 68 00  c...c.h.0001BF08  6D 00 0A 00 43 00 61 00  m...C.a.0001BF10  6C 00 63 00 75 00 6C 00  l.c.u.l.0001BF18  61 00 74 00 6F 00 72 00  a.t.o.r.0001BF20  11 00 4E 00 6F 00 74 00  ..N.o.t.0001BF28  20 00 45 00 6E 00 6F 00   .E.n.o.0001BF30  75 00 67 00 68 00 20 00  u.g.h. .0001BF38  4D 00 65 00 6D 00 6F 00  M.e.m.o.0001BF40  72 00 79 00 00 00 00 00  r.y.....0001BF48  00 00 00 00 00 00 00 00  ........0001BF50  00 00 00 00 00 00 00 00  ........0001BF58  00 00 00 00 00 00 00 00  ........0001BF60  00 00 00 00 00 00 00 00  ........0001BF68  00 00 00 00 00 00 00 00  ........0001BF70  00 00 00 00 00 00 00 00  ........0001BF78  00 00 00 00 00 00 00 00  ........</pre>
</td>
</tr>
</tbody>
</table>
<h4>2.2 The Windows NT data</h4>
<p>As mentioned in the preceding section, <tt>e_lfanew</tt> storage in the MS-DOS data structure refers to the location of the Windows NT information. Hence, if you assume that the <tt>pMem</tt> pointer relates the start point of the memory space for a selected portable executable file, you can retrieve the MS-DOS header and also the Windows NT headers by the following lines, which you also can perceive in the PE viewer sample (<em>pelib.cpp</em>, <tt>PEStructure::OpenFileName()</tt>):</p>
<pre>IMAGE_DOS_HEADER        image_dos_header;IMAGE_NT_HEADERS        image_nt_headers;PCHAR pMem;b&amp;memcpy(&amp;image_dos_header, pMem,       <span class="codeKeyword">sizeof</span>(IMAGE_DOS_HEADER));memcpy(&amp;image_nt_headers,       pMem+image_dos_header.e_lfanew,       <span class="codeKeyword">sizeof</span>(IMAGE_NT_HEADERS));</pre>
<p><a name="more"><font color="#000000"></font></a><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_nt_headers_str.asp" target="new"><tt>IMAGE_NT_HEADERS</tt></a> structure definition. It makes it possible to grasp what the image NT header maintains to execute a code inside the Windows NT OS. Now, you are conversant with the Windows NT structure; it consists of the <font color="#008000">&quot;PE&quot;</font> Signature, the <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_file_header_str.asp" target="new">File Header</a>, and the <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_optional_header_str.asp" target="new">Optional Header</a>. Do not forget to take a glimpse at their comments in the <a href="http://msdn.microsoft.com/" target="new">MSDN</a> Library and in Table 1.</p>
<p>It seems to be very simple, the retrieval of the headers information. I recommend inspecting the MSDN library regarding the </p>
<p>One the whole, I consider merely, in most circumstances, the following cells of the <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_nt_headers_str.asp" target="new"><tt>IMAGE_NT_HEADERS</tt></a> structure:</p>
<pre>FileHeader-&gt;NumberOfSectionsOptionalHeader-&gt;AddressOfEntryPointOptionalHeader-&gt;ImageBaseOptionalHeader-&gt;SectionAlignmentOptionalHeader-&gt;FileAlignmentOptionalHeader-&gt;SizeOfImageOptionalHeader-&gt;DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]              -&gt;VirtualAddressOptionalHeader-&gt;DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]              -&gt;Size</pre>
<p>You can observe the main purpose of these values clearly, and their role when the internal virtual memory space allocated for an EXE file by the Windows task manager if you pay attention to their explanations in <a href="http://msdn.microsoft.com/" target="new">MSDN</a> library, so I am not going to repeat the MSDN annotations here.</p>
<p>I should make a brief comment regarding the PE data directories, or <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_optional_header_str.asp" target="new"><tt>OptionalHeader</tt></a>-&gt; <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_data_directory_str.asp" target="new"><tt>DataDirectory[]</tt></a>, because I think there are a few aspects of interest concerning them. When you come to survey the Optional header through the Windows NT information, you will find that there are <em>16</em> directories at the end of the Optional Header, where you can find the consecutive directories, including their Relative Virtual Address and Size. I just mention here the notes from <em>&lt;winnt.h&gt;</em> to clarify these information:</p>
<pre><span class="codeComment">// Export Directory</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_EXPORT          0<span class="codeComment">// Import Directory</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_IMPORT          1<span class="codeComment">// Resource Directory</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_RESOURCE        2<span class="codeComment">// Exception Directory</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_EXCEPTION       3<span class="codeComment">// Security Directory</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_SECURITY        4<span class="codeComment">// Base Relocation Table</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_BASERELOC       5<span class="codeComment">// Debug Directory</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_DEBUG           6<span class="codeComment">// Architecture Specific Data</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7<span class="codeComment">// RVA of GP</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8<span class="codeComment">// TLS Directory</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_TLS             9<span class="codeComment">// Load Configuration Directory</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10<span class="codeComment">// Bound Import Directory in headers</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11<span class="codeComment">// Import Address Table</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_IAT            12<span class="codeComment">// Delay Load Import Descriptors</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13<span class="codeComment">// COM Runtime descriptor</span><span class="codeKeyword">#define</span> IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14</pre>
<p>The last one (15) was reserved for use in the future; I have not yet seen any purpose for it, even in PE64.</p>
<p>For instance, if you want to perceive the relative virtual address (RVA) and the size of the resource data, it is enough to retrieve them by:</p>
<pre>DWORD dwRVA  = image_nt_headers.OptionalHeader-&gt;   DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]-&gt;VirtualAddress;DWORD dwSize = image_nt_headers.OptionalHeader-&gt;   DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]-&gt;Size;</pre>
<p>To comprehend more regarding the significance of data directories, I forward you to Section 3.4.3 of the <a href="http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx" target="new">Microsoft Portable Executable and the Common Object File Format Specification</a> document by Microsoft, and furthermore Section 6 of this document, where you discern the various types of sections and their applications. You will see the section&#8217;s advantage subsequently.</p>
<h4>2.3 The Section Headers and Sections</h4>
<p>You currently observe how the portable executable files declare the location and the size of a section on a disk storage file and inside the virtual memory space allocated for the program with <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_nt_headers_str.asp" target="new"><tt>IMAGE_NT_HEADERS</tt></a>-&gt; <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_optional_header_str.asp" target="new"><tt>OptionalHeader</tt></a>-&gt;<tt>SizeOfImage</tt> by the Windows task manager, as well the characteristics to demonstrate the type of the section. To better understand the Section header as my previous declaration, I suggest having a brief look at the <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_section_header_str.asp" target="new"><tt>IMAGE_SECTION_HEADER</tt></a> structure definition in the MSDN library. For an EXE packer developer, <tt>VirtualSize</tt>, <tt>VirtualAddress</tt>, <tt>SizeOfRawData</tt>, <tt>PointerToRawData</tt>, and <tt>Characteristics</tt> cells have significant rules. When developing an EXE packer, you should be clever enough to play with them. There are somet hings to note when you modify them; you should take care to align the <tt>VirtualSize</tt> and <tt>VirtualAddress</tt> according to <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_optional_header_str.asp" target="new"><tt>OptionalHeader</tt></a>-&gt;<tt>SectionAlignment</tt>, as well as <tt>SizeOfRawData</tt> and <tt>PointerToRawData</tt> in line with <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_optional_header_str.asp" target="new"><tt>OptionalHeader</tt></a>-&gt;<tt>FileAlignment</tt>. Otherwise, you will corrupt your target EXE file and it will never run. Regarding <tt>Characteristics</tt>, I pay attention mostly to establish a section by <tt>IMAGE_SCN_MEM_READ</tt> | <tt>IMAGE_SCN_MEM_WRITE</tt> | <tt>IMAGE_SCN_CNT_INITIALIZED_DATA</tt>, I prefer that my new section has the ability to initialize such data during the running process, such as import table; besides, I need it to be able to modify itself by the loader with my settings in the section characteristics to read- and writeable.</p>
<p>Moreover, you should pay attention to the section names; you can know the purpose of each section by its name. I will just forward you to Section 6 of the <a href="http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx" target="new">Microsoft Portable Executable and the Common Object File Format Specification</a> documents. I believe it represents the totality of sections by their names; this is also included in Table 2.</p>
<p><strong>Table 2:</strong> Section names</p>
<p>
<table cellspacing="2" cellpadding="2" border="2">
<tbody>
<tr>
<td><font color="#008000">&quot;.text&quot;</font></td>
<td>Code Section</td>
</tr>
<tr>
<td><font color="#008000">&quot;CODE&quot;</font></td>
<td>Code Section of file linked by Borland Delphi or Borland Pascal</td>
</tr>
<tr>
<td><font color="#008000">&quot;.data&quot;</font></td>
<td>Data Section</td>
</tr>
<tr>
<td><font color="#008000">&quot;DATA&quot;</font></td>
<td>Data Section of file linked by Borland Delphi or Borland Pascal</td>
</tr>
<tr>
<td><font color="#008000">&quot;.rdata&quot;</font></td>
<td>Section for Constant Data </td>
</tr>
<tr>
<td><font color="#008000">&quot;.idata&quot;</font></td>
<td>Import Table</td>
</tr>
<tr>
<td><font color="#008000">&quot;.edata&quot; </font></td>
<td>Export Table</td>
</tr>
<tr>
<td><font color="#008000">&quot;.tls&quot;</font></td>
<td>TLS Table</td>
</tr>
<tr>
<td><font color="#008000">&quot;.reloc&quot;</font></td>
<td>Relocation Information</td>
</tr>
<tr>
<td><font color="#008000">&quot;.rsrc&quot;</font></td>
<td>Resource Information</td>
</tr>
</tbody>
</table>
<p>To comprehend the section headers and also the sections, you can run the sample PE viewer. With this PE viewer, you can realize only the application of the section headers in a file image, so to observe the main significance in the Virtual Memory, you should try to load a PE file by a debugger. The next section represents the main idea of using the virtual address and size in the virtual memory by using a debugger. The last note is about <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_nt_headers_str.asp" target="new"><tt>IMAGE_NT_HEADERS</tt></a>-&gt; <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/image_file_header_str.asp" target="new"><tt>FileHeader</tt></a>-&gt;<tt>NumberOfSections</tt>, that provides a number of sections in a PE file. Do not forget to adjust it whenever you remove or add some sections to a PE file. I am talking about section injection!</p>
<h3>3 Debugger, Disassembler and some Useful Tools</h3>
<p>In this part, you will become familiar with the necessary and essential equipment to develop your PE tools.</p>
<h4>3.1 Debuggers</h4>
<p>The first essential prerequisite to become a PE tools developer is to have enough experience with bug tracer tools. Furthermore, you should know most of the assembly instructions. To me, the Intel documents are the best references. You can obtain them from the Intel site for IA-32, and on top of that IA-64; the future belongs to IA-64 CPUs, Windows XP 64-bit, and also PE64!</p>
<ul>
<li><a href="http://www.intel.com/design/pentium4/manuals/index_new.htm#1" target="new">IA-32 Intel Architecture Software Developer&#8217;s Manuals</a> </li>
<li><a href="http://www.intel.com/software/products/compilers/docs/linux/ref/asm_lan_lx.htm#cover.htm" target="new">Intel Itanium Architecture Assembly Language Reference Guide</a> </li>
<li><a href="http://www.intel.com/cd/ids/developer/asmo-na/eng/19415.htm" target="new">The Intel Itanium Processor Developer Resource Guide</a> </li>
</ul>
<p>To trace a PE file, <a href="http://en.wikipedia.org/wiki/SoftICE" target="new">SoftICE</a> by <a href="http://www.compuware.com/" target="new">Compuware Corporation</a>, I knew it also as named <a href="http://en.wikipedia.org/wiki/Numega" target="new">NuMega</a> when I was at high school, is the best <a href="http://en.wikipedia.org/wiki/Debugger" target="new">debugger</a> in the world. It implements process tracing by using the <a href="http://en.wikipedia.org/wiki/Kernel_mode" target="new">kernel mode</a> method debugging without applying Windows debugging <a href="http://en.wikipedia.org/wiki/Application_programming_interface" target="new">application programming interface</a> (API) functions. In addition, I will introduce one perfect debugger in <a href="http://en.wikipedia.org/wiki/User_mode" target="new">user mode</a> level. It utilizes the <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/debugging_reference.asp" target="new">Windows debugging API</a> to trace a PE file and also attaches itself to an active <a href="http://en.wikipedia.org/wiki/Computer_process" target="new">process</a>. These <a href="http://en.wikipedia.org/wiki/Application_programming_interface" target="new">API</a> functions have been provided by Microsoft teams, inside the Windows Kernel32 library, to trace a specific process, by using Microsoft tools, or perhaps, to make your own debugger! Some of those <a href="http://en.wikipedia.org/wiki/Application_programming_interface" target="new">API</a> functions inlude:</p>
<ul><tt>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/createthread.asp" target="new">CreateThread()</a> </li>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/createprocess.asp" target="new">CreateProcess()</a> </li>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/openprocess.asp" target="new">OpenProcess()</a> </li>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/debugactiveprocess.asp" target="new">DebugActiveProcess()</a> </li>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/getthreadcontext.asp" target="new">GetThreadContext()</a> </li>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/setthreadcontext.asp" target="new">SetThreadContext()</a> </li>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/continuedebugevent.asp" target="new">ContinueDebugEvent()</a> </li>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/debugbreak.asp" target="new">DebugBreak()</a> </li>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/readprocessmemory.asp" target="new">ReadProcessMemory()</a> </li>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/writeprocessmemory.asp" target="new">WriteProcessMemory()</a> </li>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/suspendthread.asp" target="new">SuspendThread()</a> </li>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/resumethread.asp" target="new">ResumeThread()</a> </li>
<p>    </tt></ul>
<h5>3.1.1 SoftICE</h5>
<p>It was in 1987; Frank Grossman and Jim Moskun decided to establish a company called <a href="http://en.wikipedia.org/wiki/Numega" target="new">NuMega Technologies</a> in Nashua, NH, to develop some equipment to trace and test the reliability of Microsoft Windows software programs. Now, it is a part of <a href="http://en.wikipedia.org/wiki/Compuware" target="new">Compuware Corporation</a> and its product has participated to accelerate the reliability in Windows software, and additionally in Windows driver developments. Currently, everyone knows the Compuware DriverStudio that is used to establish an environment for implementing the elaboration of a kernel driver or a system file by aiding the <a href="http://www.microsoft.com/whdc/ddk/winddk.mspx" target="new">Windows Driver Development Kit (DDK)</a>. It bypasses the involvement of DDK to implement a portable executable file of kernel level for a Windows system software developer. For us, only one instrument of DriverStudio is important, <a href="http://en.wikipedia.org/wiki/SoftICE" target="new">SoftICE</a>; this debugger can be used to trace every portable executable file, a PE file for user mode level or a PE file for kernel mode level.</p>
<p><strong>Figure 1:</strong> SoftICE Window</p>
<p>
<table cellspacing="0" cellpadding="0" border="1">
<tbody bgcolor="#000000" color="gray">
<tr>
<td><font color="#808080"><font color="#00ccff">EAX=00000000</font>EBX=7FFDD000<font color="#00ccff"> ECX=0007FFB0 EDX=7C90EB94</font> ESI=FFFFFFFF EDI=7C919738 <font color="#00ccff">EBP=0007FFF0 ESP=0007FFC4 EIP=010119E0</font> o d i s <font color="#00ccff">z </font>a <font color="#00ccff">p</font> c<br />                CS=0008 DS=0023 SS=0010 ES=0023 FS=0030 GS=0000</font> <font color="#00ccff">SS:0007FFC4=87C816D4F</font></td>
</tr>
<tr>
<td><font color="#808080">0023:01013000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 &#8230;&#8230;&#8230;&#8230;&#8230;. 0023:01013010 01 00 00 00 20 00 00 00-0A 00 00 00 0A 00 00 00 &#8230;&#8230;&#8230;&#8230;&#8230;. 0023:01013020 20 00 00 00 00 00 00 00-53 63 69 43 61 6C 63 00 &#8230;&#8230;..SciCalc. 0023:01013030 00 00 00 00 00 00 00 00-62 61 63 6B 67 72 6F 75 &#8230;&#8230;..backgrou 0023:01013040 6E 64 00 00 00 00 00 00-2E 00 00 00 00 00 00 00 nd&#8230;&#8230;&#8230;&#8230;..</font></td>
</tr>
<tr>
<td><font color="#808080">0010:0007FFC4 4F 6D 81 7C 38 07 91 7C-FF FF FF FF 00 90 FD 7F Om |8 b.| . 0010:0007FFD4 ED A6 54 80 C8 FF 07 00-E8 B4 F5 81 FF FF FF FF T . 0010:0007FFE4 F3 99 83 7C 58 6D 81 7C-00 00 00 00 00 00 00 00 Xm |&#8230;&#8230;.. 0010:0007FFF4 00 00 00 00 E0 19 01 01-00 00 00 00 00 00 00 00 &#8230;. &#8230;.</font></td>
</tr>
<tr>
<td><font color="#808080"><font color="#00ccff">010119E0 PUSH EBP</font> 010119E1 MOV EBP,ESP 010119E3 PUSH -1 010119E5 PUSH 01001570 010119EA PUSH 01011D60 010119EF MOV EAX,DWORD PTR FS:[0] 010119F5 PUSH EAX 010119F6 MOV DWORD PTR FS:[0],ESP 010119FD ADD ESP,-68 01011A00 PUSH EBX 01011A01 PUSH ESI 01011A02 PUSH EDI 01011A03 MOV DWORD PTR SS:[EBP-18],ESP 01011A06 MOV DWORD PTR SS:[EBP-4],0</font></td>
</tr>
<tr>
<td><font color="#808080">:_</font><font color="#808080"></p>
<p>                </font></td>
</tr>
</tbody>
</table>
<h5>3.1.2 OllyDbg</h5>
<p>It was about four years ago that I first saw this debugger by chance. For me, it was the best choice; I was not wealthy enough to purchase SoftICE, and at that time, SoftICE only had good functions for <a href="http://en.wikipedia.org/wiki/DOS" target="new">DOS</a>, <a href="http://en.wikipedia.org/wiki/Windows_98" target="new">Windows 98</a>, and <a href="http://en.wikipedia.org/wiki/Windows_2000" target="new">Windows 2000</a>. I found that this debugger supported all kinds of Windows versions. Therefore, I started to learn it very fast, and now it is my favorite debugger for the Windows OS. It is a debugger that can be used to trace all kinds of portable executable files except a <a href="http://en.wikipedia.org/wiki/Common_Language_Infrastructure" target="new">Common Language Infrastructure (CLI)</a> file format in user mode level, by using the <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/debugging_reference.asp" target="new">Windows debugging API</a>. <strong>Oleh Yuschuk</strong>, the author, is one of worthiest software developers I have seen in my life. He is a Ukrainian who now lives in Germany. I should mention here that his debugger is the best choice for hacker and cracker parties around the world! It is freeware! You can try it from the <a href="http://www.ollydbg.de/" target="new">OllyDbg Homepage</a>.</p>
<p>    <a name="more"><font color="#000000">&nbsp;</font>
<p><strong>Figure 2:</strong> OllyDbg CPU Window</p>
<p><img height="452" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=SCREENSHOT_JPG&amp;ds=20060302" width="500" alt="" /><br />    (</p>
<h5>3.1.3 Which parts are important in a debugger interface?</h5>
<p>I have introduced two debuggers without talking about how you can employ them, and also which parts you should pay attention to. Regarding using debuggers, I refer you to their instructions in help documents. However, I want to explain briefly the important parts of a debugger; of course, I am talking about low-level debuggers, or in other words, machine-language debuggers of the x86 CPU families.</p>
<p>All of low-level debuggers consist of the following subdivisions:</p>
<ol>
<li>Registers viewer.<br />
<table cellspacing="2" cellpadding="2" border="2">
<tbody>
<tr>
<td align="center"><font color="#808080">EAX</font></td>
</tr>
<tr>
<td align="center"><font color="#808080">ECX</font></td>
</tr>
<tr>
<td align="center"><font color="#808080">EDX</font></td>
</tr>
<tr>
<td align="center"><font color="#808080">EBX</font></td>
</tr>
<tr>
<td align="center"><font color="#808080">ESP</font></td>
</tr>
<tr>
<td align="center"><font color="#808080">EBP</font></td>
</tr>
<tr>
<td align="center"><font color="#808080">ESI</font></td>
</tr>
<tr>
<td align="center"><font color="#808080">EDI</font></td>
</tr>
<tr>
<td align="center"><font color="#808080">EIP</font></td>
</tr>
<tr>
<td>
<p align="center"><font color="#808080">o</font><font color="#808080"> d t s z a p c</font></p>
</td>
</tr>
</tbody>
</table>
</li>
<li>Disassembler or Code viewer.<br />
<table cellspacing="2" cellpadding="2" border="2">
<tbody>
<tr>
<td>
<pre>010119E0 PUSH EBP010119E1 MOV EBP,ESP010119E3 PUSH -1010119E5 PUSH 01001570010119EA PUSH 01011D60010119EF MOV EAX,DWORD PTR FS:[0]010119F5 PUSH EAX010119F6 MOV DWORD PTR FS:[0],ESP010119FD ADD ESP,-6801011A00 PUSH EBX01011A01 PUSH ESI01011A02 PUSH EDI01011A03 MOV DWORD PTR SS:[EBP-18],ESP01011A06 MOV DWORD PTR SS:[EBP-4],0</pre>
</td>
</tr>
</tbody>
</table>
</li>
<li>Memory watcher.<br />
<table cellspacing="0" cellpadding="0" width="560" border="1">
<tbody>
<tr>
<td><font color="#808080">0023:01013000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 &#8230;&#8230;&#8230;&#8230;&#8230;. 0023:01013010 01 00 00 00 20 00 00 00-0A 00 00 00 0A 00 00 00 &#8230;&#8230;&#8230;&#8230;&#8230;. 0023:01013020 20 00 00 00 00 00 00 00-53 63 69 43 61 6C 63 00 &#8230;&#8230;..SciCalc. 0023:01013030 00 00 00 00 00 00 00 00-62 61 63 6B 67 72 6F 75 &#8230;&#8230;..backgrou 0023:01013040 6E 64 00 00 00 00 00 00-2E 00 00 00 00 00 00 00 nd&#8230;&#8230;&#8230;&#8230;..</font></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
</li>
<li>Stack viewer.<br />
<table cellspacing="0" cellpadding="0" width="560" border="1">
<tbody>
<tr>
<td><font color="#808080">0010:0007FFC4 4F 6D 81 7C 38 07 91 7C-FF FF FF FF 00 90 FD 7F Om |8 b.| . 0010:0007FFD4 ED A6 54 80 C8 FF 07 00-E8 B4 F5 81 FF FF FF FF T . 0010:0007FFE4 F3 99 83 7C 58 6D 81 7C-00 00 00 00 00 00 00 00 Xm |&#8230;&#8230;.. 0010:0007FFF4 00 00 00 00 E0 19 01 01-00 00 00 00 00 00 00 00 &#8230;. &#8230;.</font></td>
</tr>
</tbody>
</table>
</li>
<li>Command line, command buttons, or shortcut keys to follow the debugging process.<br />
<table cellspacing="0" cellpadding="0" width="560" border="1">
<tbody>
<tr>
<td align="center">Command</td>
<td align="center">SoftICE</td>
<td align="center">OllyDbg</td>
</tr>
<tr>
<td align="center">Run</td>
<td align="center">F5</td>
<td align="center">F9</td>
</tr>
<tr>
<td align="center">Step Into</td>
<td align="center">F11</td>
<td align="center">F7</td>
</tr>
<tr>
<td align="center">Step Over</td>
<td align="center">F10</td>
<td align="center">F8</td>
</tr>
<tr>
<td align="center">Set Break Point</td>
<td align="center">F8</td>
<td align="center">F2</td>
</tr>
</tbody>
</table>
</li>
</ol>
<p>You can compare Figures 1 and 2 to distinguish the difference between SoftICE and OllyDbg. When you want to trace a PE file, you should mostly consider these five subdivisions. Furthermore, every debugger comprises of some other useful parts; you should discover them by yourself.</p>
<h4>3.2 Disassembler</h4>
<p>You can consider OllyDbg and SoftICE to be excellent disassemblers, but I also want to introduce another disassembler tool that is famous in the reverse engineering world.</p>
<h5>3.2.1 Proview disassembler</h5>
<p><a href="http://community.reverse-engineering.net/viewforum.php?f=50&amp;sid=a77c210bc1030dd395452bb7e1f67439" target="new">Proview</a> or <a href="http://pvdasm.reverse-engineering.net/" target="new" class="broken_link">PVDasm</a> is an admirable disassembler by the <a href="http://community.reverse-engineering.net/" target="new" class="broken_link">Reverse-Engineering-Community</a>; it is still under development and bug fixing. You can find its disassmbler source engine and employ it to create your own disassembler.</p>
<h5>3.2.2 W32Dasm</h5>
<p><a href="http://www.softpedia.com/get/Programming/Debuggers-Decompilers-Dissasemblers/WDASM.shtml" target="new">W32DASM</a> can disassemble both 16- and 32-bit executable file formats. In addition to its disassembling ability, you can employ it to analyze import, export, and resource data directories data.</p>
<h5>3.2.3 IDA Pro</h5>
<p>All reverse-engineering experts know that <a href="http://www.datarescue.com/idabase/idaproc.htm" target="new" class="broken_link">IDA Pro</a> can be used to investigate, not only x86 instructions, but that of various kinds of CPU types like AVR, PIC, and so forth. It can illustrate the assembly source of a portable executable file by using colored graphics and tables, and is very useful for any newbie in this area. Furthermore, it has the capability to trace an executable file inside the user mode level in the same way as OllyDbg.</p>
<h4>3.3 Some Useful Tools</h4>
<p>A good PE tools developer is conversant with the tools that save his time, so I recommend that you select some appropriate instruments to investigate the base information under a portable executable file.</p>
<h5>3.3.1 LordPE</h5>
<p><a href="http://www.softpedia.com/get/Programming/File-Editors/LordPE.shtml" target="new" class="broken_link">LordPE</a> by <a href="http://scifi.pages.at/yoda9k/aboutme.htm" target="new">y0da</a> is still the first choice to retrieve PE file information with the possibility to modify them.</p>
<p><img height="206" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=LORDPE_GIF&amp;ds=20060302" width="441" alt="" /></p>
<h5>3.3.2 PEiD</h5>
<p><a href="http://peid.has.it/" target="new">PE iDentifier</a> is valuable to identify the type of compilers, packers, and cryptors of PE files. As of now, it can detect more than 500 different signature types of PE files.</p>
<p><img height="166" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=PEID_GIF&amp;ds=20060302" width="296" alt="" /></p>
<h5>3.3.3 Resource Hacker</h5>
<p><a href="http://www.angusj.com/resourcehacker/" target="new">Resource Hacker </a>can be employed to modify resource directory information; icon, menu, version info, string table, and so on.</p>
<p><img height="141" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=RESOURCEHACKER_GIF&amp;ds=20060302" width="191" alt="" /></p>
<h5>3.3.4 WinHex</h5>
<p><a href="http://www.winhex.com/winhex/index-m.html" target="new">WinHex</a>, it is clear what you can do with this tool.</p>
<p><img height="230" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=WINHEX_GIF&amp;ds=20060302" width="329" alt="" /></p>
<h5>3.3.5 CFF Explorer</h5>
<p>Eventually, <a href="http://www.pmode.net/CFF.php" target="new" class="broken_link">CFF Explorer </a>by <a href="http://www.pmode.net/USERS/116/UserInfo.xml" target="new" class="broken_link">Ntoskrnl </a>is what you want to have as a PE Utility tool in your arsenal; it supports PE32/64, PE rebuild included <a href="http://en.wikipedia.org/wiki/Common_Language_Infrastructure" target="new">Common Language Infrastructure (CLI)</a> file. In other words, the <a href="http://en.wikipedia.org/wiki/Microsoft_.NET" target="new">.NET file</a>, a resource modifier, and much more facilities which can not be found in others. Just try to discover every unimaginable option by hand.</p>
<p><img height="217" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=CFFEXPLORER_GIF&amp;ds=20060302" width="301" alt="" /></p>
<h3>4 Add a New Section and Change the OEP</h3>
<p>You are ready to do the first step of making your project. I have provided a library to add a new section and rebuild the portable executable file. Before starting, I wnat you to get familiar with the headers of a PE file, by using <a href="http://www.ollydbg.de/" target="new">OllyDbg</a>. You should first open a PE file; that pops up a menu, <strong>View-&gt;Executable file</strong>. Again, you get a popup menu: <strong>Special-&gt;PE header</strong>. You will observe a scene similar to Figure 3. Now, come to the Main Menu <strong>View-&gt;Memory</strong>, and try to distinguish the sections inside the <strong>Memory map</strong> window.</p>
<h4>Figure 3</h4>
<table cellspacing="0" cellpadding="0" border="1">
<tbody>
<tr>
<td><font color="#808080">
<pre>00000000000000020000000400000006000000080000000A0000000C0000000E00000010000000120000001400000016000000180000001A0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C</pre>
<p>                </font></td>
<td>
<pre> 4D 5A 9000 0300 0000 0400 0000 FFFF 0000 B800 0000 0000 0000 4000 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0000000</pre>
</td>
<td>
<pre> ASCII <font color="#008000">&quot;MZ&quot;</font> DW 0090 DW 0003 DW 0000 DW 0004 DW 0000 DW FFFF DW 0000 DW 00B8 DW 0000 DW 0000 DW 0000 DW 0040 DW 0000 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DB 00 DD <font color="#ff0000">000000F0</font></pre>
</td>
<td>
<pre> DOS EXE Signature DOS_PartPag = 90 (144.) DOS_PageCnt = 3 DOS_ReloCnt = 0 DOS_HdrSize = 4 DOS_MinMem = 0 DOS_MaxMem = FFFF (65535.) DOS_ReloSS = 0 DOS_ExeSP = B8 DOS_ChkSum = 0 DOS_ExeIP = 0 DOS_ReloCS = 0 DOS_TablOff = 40 DOS_Overlay = 0 Offset to PE signature</pre>
</td>
</tr>
</tbody>
</table>
<p>    <a name="more"><font color="#000000">&nbsp;</font>
<p>I want to explain how you can plainly change the Offset of Entry Point (OEP) in your sample file, <em>CALC.EXE</em> of Windows XP. First, by using a PE Tool, and also using your PE Viewer, you find OEP, <tt>0x00012475</tt>, and Image Base, <tt>0x01000000</tt>. This value of OEP is the Relative Virtual Address, so the Image Base value is used to convert it to the Virtual Address.</p>
<table cellspacing="0" cellpadding="0" width="450" border="1">
<tbody>
<tr>
<td>
<p><strong>Virtual_Address = Image_Base + Relative_Virtual_Address</strong></p>
</td>
</tr>
</tbody>
</table>
<pre>DWORD OEP_RVA = image_nt_headers-&gt;   OptionalHeader.AddressOfEntryPoint ;<span class="codeComment">// OEP_RVA = 0x00012475</span>DWORD OEP_VA = image_nt_headers-&gt;   OptionalHeader.ImageBase + OEP_RVA ;<span class="codeComment">// OEP_VA = 0x01000000 + 0x00012475 = 0x01012475</span></pre>
<h4>PE Maker: Step 1</h4>
<p>Download pemaker1.zip and test1.zip from the files at the end of this article.</p>
<p><tt>DynLoader()</tt>, in <em>loader.cpp</em>, is reserved for the data of the new section&mdash;in other words, the <strong>Loader</strong>.</p>
<h4>DynLoader Step 1</h4>
<pre><span class="codeKeyword">__stdcall</span> <span class="codeKeyword">void</span> DynLoader(){_asm{<span class="codeComment">//----------------------------------</span>    DWORD_TYPE(DYN_LOADER_START_MAGIC)<span class="codeComment">//----------------------------------</span>    MOV EAX,01012475h <span class="codeComment">// &lt;&lt; Original OEP</span>    JMP EAX<span class="codeComment">//----------------------------------</span>    DWORD_TYPE(DYN_LOADER_END_MAGIC)<span class="codeComment">//----------------------------------</span>}}</pre>
<p>Unfortunately, this source can only be applied for the sample test file. You should complete it by saving the value of the original OEP in the new section, and use it to reach the real OEP. I have accomplished it in Step 2 (Section 5).</p>
<h4>4.1 Retrieve and Rebuild PE file</h4>
<p>I have made a simple class library to recover PE information and to use it in a new PE file.</p>
<h4>CPELibrary Class Step 1</h4>
<pre><span class="codeComment">//----------------------------------------------------------------</span><span class="codeKeyword">class</span> CPELibrary{<span class="codeKeyword">private</span>:    <span class="codeComment">//-----------------------------------------</span>    PCHAR                   pMem;    DWORD                   dwFileSize;    <span class="codeComment">//-----------------------------------------</span><span class="codeKeyword">protected</span>:    <span class="codeComment">//-----------------------------------------</span>    PIMAGE_DOS_HEADER       image_dos_header;    PCHAR                   pDosStub;    DWORD                   dwDosStubSize, dwDosStubOffset;    PIMAGE_NT_HEADERS       image_nt_headers;    PIMAGE_SECTION_HEADER   image_section_header[MAX_SECTION_NUM];    PCHAR                   image_section[MAX_SECTION_NUM];    <span class="codeComment">//-----------------------------------------</span><span class="codeKeyword">protected</span>:    <span class="codeComment">//-----------------------------------------</span>    DWORD PEAlign(DWORD dwTarNum,DWORD dwAlignTo);    <span class="codeKeyword">void</span> AlignmentSections();    <span class="codeComment">//-----------------------------------------</span>    DWORD Offset2RVA(DWORD dwRO);    DWORD RVA2Offset(DWORD dwRVA);    <span class="codeComment">//-----------------------------------------</span>    PIMAGE_SECTION_HEADER ImageRVA2Section(DWORD dwRVA);    PIMAGE_SECTION_HEADER ImageOffset2Section(DWORD dwRO);    <span class="codeComment">//-----------------------------------------</span>    DWORD ImageOffset2SectionNum(DWORD dwRVA);    PIMAGE_SECTION_HEADER AddNewSection(<span class="codeKeyword">char</span>* szName,DWORD dwSize);    <span class="codeComment">//-----------------------------------------</span><span class="codeKeyword">public</span>:    <span class="codeComment">//-----------------------------------------</span>    CPELibrary();    ~CPELibrary();    <span class="codeComment">//-----------------------------------------</span>    <span class="codeKeyword">void</span> OpenFile(<span class="codeKeyword">char</span>* FileName);    <span class="codeKeyword">void</span> SaveFile(<span class="codeKeyword">char</span>* FileName);    <span class="codeComment">//-----------------------------------------</span>};</pre>
<p>In Table 1, the usage of <tt>image_dos_header</tt>, <tt>pDosStub</tt>, <tt>image_nt_headers</tt>, <tt>image_section_header</tt> [<tt>MAX_SECTION_NUM</tt>], and <tt>image_section</tt>[<tt>MAX_SECTION_NUM</tt>] is clear. You use <tt>OpenFile()</tt> and <tt>SaveFile()</tt> to retrieve and rebuild a PE file. Furthermore, <tt>AddNewSection()</tt> is employed to create the new section, the important step.</p>
<p>    </a><br />
<h4>4.2 Create data for the new section</h4>
<p><a name="more"><font color="#000000"> </font></a><a href="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=LINKTIP1_GIF&amp;ds=20060302" target="_blank">Full Size Image</a>)
<p>You can comprehend the difference between incremental link and no-incremental link by looking at the following picture:</p>
<p>    <img height="130" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=INCREMENTAL_LINK_GIF&amp;ds=20060302" width="415" alt="" />
<p>To acquire the virtual address of <tt>DynLoader()</tt>, you obtain the virtual address of <tt>JMP pemaker.DynLoader</tt> in the incremental link, but by no-incremental link, the real virtual address is gained by the following code:</p>
<pre>DWORD dwVA= (DWORD) DynLoader;</pre>
<p>This setting is more critical in the incremental link when you try to find the beginning and ending of the <strong>Loader</strong>, <tt>DynLoader()</tt>, by <tt>CPECryptor::ReturnToBytePtr()</tt>:</p>
<pre><span class="codeKeyword">void</span>* CPECryptor::ReturnToBytePtr(<span class="codeKeyword">void</span>* FuncName, DWORD findstr){    <span class="codeKeyword">void</span>* tmpd;    __asm   {        mov eax, FuncName        jmp dfhjg:    inc eaxdf:     mov ebx, [eax]        cmp ebx, findstr        jnz hjg        mov tmpd, eax    }    <span class="codeKeyword">return</span> tmpd;}</pre>
</p>
<p>In <em>pecrypt.cpp</em>, I have represented another class, <tt>CPECryptor</tt>, to comprise the data of the new section. Nevertheless, the data of the new section is created by <tt>DynLoader()</tt> in <em>loader.cpp</em>, DynLoader Step 1. You use the <tt>CPECryptor</tt> class to enter this data in to the new section, and also some other stuff.</p>
<h4>CPECryptor Class Step 1</h4>
<pre><span class="codeComment">//----------------------------------------------------------------</span><span class="codeKeyword">class</span> CPECryptor: <span class="codeKeyword">public</span> CPELibrary{<span class="codeKeyword">private</span>:    <span class="codeComment">//----------------------------------------</span>    PCHAR pNewSection;    <span class="codeComment">//----------------------------------------</span>    DWORD GetFunctionVA(<span class="codeKeyword">void</span>* FuncName);    <span class="codeKeyword">void</span>* ReturnToBytePtr(<span class="codeKeyword">void</span>* FuncName, DWORD findstr);    <span class="codeComment">//----------------------------------------</span><span class="codeKeyword">protected</span>:    <span class="codeComment">//----------------------------------------</span><span class="codeKeyword">public</span>:    <span class="codeComment">//----------------------------------------</span>    <span class="codeKeyword">void</span> CryptFile(<span class="codeKeyword">int</span>(__cdecl *callback) (<span class="codeKeyword">unsigned</span> <span class="codeKeyword">int</span>,                                           <span class="codeKeyword">unsigned</span> <span class="codeKeyword">int</span>));    <span class="codeComment">//----------------------------------------</span>};<span class="codeComment">//----------------------------------------------------------------</span></pre>
<h4>4.3 Some notes regarding creating a new PE file</h4>
<ul>
<li>Align the <tt>VirtualAddress</tt> and the <tt>VirtualSize</tt> of each section by <tt>SectionAlignment</tt>:
<pre>image_section_header[i]-&gt;VirtualAddress=    PEAlign(image_section_header[i]-&gt;VirtualAddress,    image_nt_headers-&gt;OptionalHeader.SectionAlignment);image_section_header[i]-&gt;Misc.VirtualSize=    PEAlign(image_section_header[i]-&gt;Misc.VirtualSize,    image_nt_headers-&gt;OptionalHeader.SectionAlignment);</pre>
</li>
<li>Align the <tt>PointerToRawData</tt> and the <tt>SizeOfRawData</tt> of each section by <tt>FileAlignment</tt>:
<pre>image_section_header[i]-&gt;PointerToRawData =    PEAlign(image_section_header[i]-&gt;PointerToRawData,            image_nt_headers-&gt;OptionalHeader.FileAlignment);image_section_header[i]-&gt;SizeOfRawData =    PEAlign(image_section_header[i]-&gt;SizeOfRawData,            image_nt_headers-&gt;OptionalHeader.FileAlignment);</pre>
</li>
<li>Correct the <tt>SizeofImage</tt> by the virtual size and the virtual address of the last section:
<pre>image_nt_headers-&gt;OptionalHeader.SizeOfImage =   image_section_header[LastSection]-&gt;VirtualAddress +   image_section_header[LastSection]-&gt;Misc.VirtualSize;</pre>
</li>
<li>Set the Bound Import Directory header to zero because this directory is not very important to execute a PE file:
<pre>image_nt_headers-&gt;   OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].  VirtualAddress = 0;image_nt_headers-&gt;   OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_                                IMPORT].Size = 0;</pre>
</li>
</ul>
<h4>4.4 Some notes regarding linking this VC Project</h4>
<ul>
<li>Set <em>Linker-&gt;General-&gt;Enable Incremental Linking</em> to <strong>No (/INCREMENTAL:NO)</strong>.</p>
<p>        <img height="125" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=LINKTIP1_GIF&amp;ds=20060302" width="500" alt="" /><br />        (</li>
</ul>
<h3>5 Store Important Data and Reach the Original OEP</h3>
<p>Right now, we save the Original OEP and also the Image Base in order to reach to the virtual address of OEP. I have reserved a free space at the end of <tt>DynLoader()</tt> to store them, DynLoader Step 2.</p>
<h4>PE Maker &#8211; Step 2</h4>
<p>Download the pemaker2.zip source files from the end of the article.</p>
<h4>DynLoader Step 2</h4>
<pre><span class="codeKeyword">__stdcall</span> <span class="codeKeyword">void</span> DynLoader(){_asm{<span class="codeComment">//------------------------------------</span>    DWORD_TYPE(DYN_LOADER_START_MAGIC)<span class="codeComment">//------------------------------------</span>Main_0:    PUSHAD    <span class="codeComment">// get base ebp</span>    CALL Main_1Main_1:    POP EBP    SUB EBP,OFFSET Main_1    MOV EAX,DWORD PTR [EBP+_RO_dwImageBase]    ADD EAX,DWORD PTR [EBP+_RO_dwOrgEntryPoint]    PUSH EAX    RETN <span class="codeComment">// &gt;&gt; JMP to Original OEP</span><span class="codeComment">//----------------------------------</span>    DWORD_TYPE(DYN_LOADER_START_DATA1)<span class="codeComment">//----------------------------------<font color="#ff0000"></font><span class="codeComment">//----------------------------------</span>    DWORD_TYPE(DYN_LOADER_END_MAGIC)<span class="codeComment">//----------------------------------</span>}}</span>_RO_dwImageBase:                DWORD_TYPE(0xCCCCCCCC)_RO_dwOrgEntryPoint:            DWORD_TYPE(0xCCCCCCCC)</pre>
<p>The new function, <tt>CPECryptor::CopyData1()</tt>, will implement the copy of the Image Base value and the Offset of Entry Point value into 8 bytes of free space in the loader.</p>
<h4>5.1 Restore the first register&#8217;s context</h4>
<p>It is important to recover the Original Context of the thread. You have not yet done it in the DynLoader Step 2 source code. You can modify the source of <tt>DynLoader()</tt> to repossess the first Context.</p>
<pre><span class="codeKeyword">__stdcall</span> <span class="codeKeyword">void</span> DynLoader(){_asm{<span class="codeComment">//------------------------------------</span>    DWORD_TYPE(DYN_LOADER_START_MAGIC)<span class="codeComment">//------------------------------------</span>Main_0:    <font color="#ff0000">PUSHAD<span class="codeComment">// Save the registers context in stack</span>    CALL Main_1Main_1:    POP EBP<span class="codeComment">// Get Base EBP</span>    SUB EBP,OFFSET Main_1    MOV EAX,DWORD PTR [EBP+_RO_dwImageBase]    ADD EAX,DWORD PTR [EBP+_RO_dwOrgEntryPoint]    MOV DWORD PTR [ESP+1Ch],EAX <span class="codeComment">// pStack.Eax &lt;- EAX</span>    <font color="#ff0000">POPAD <span class="codeComment">// Restore the first registers context from stack</span>    PUSH EAX    XOR  EAX, EAX    RETN <span class="codeComment">// &gt;&gt; JMP to Original OEP</span><span class="codeComment">//----------------------------------</span>    DWORD_TYPE(DYN_LOADER_START_DATA1)<span class="codeComment">//----------------------------------</span>_RO_dwImageBase:                DWORD_TYPE(0xCCCCCCCC)_RO_dwOrgEntryPoint:            DWORD_TYPE(0xCCCCCCCC)<span class="codeComment">//----------------------------------</span>    DWORD_TYPE(DYN_LOADER_END_MAGIC)<span class="codeComment">//----------------------------------</span>}}</font></font></pre>
<h4>5.2 Restore the original stack</h4>
<p>You also can recover the original stack by setting the value of the beginning stack + <tt>0x34</tt> to the Original OEP, but it is not very important. Nevertheless, in the following code, I have accomplished the loader code by a simple trick to reach the OEP in addition to redecorating the stack. You can observe the implementation by tracing using <a href="http://www.ollydbg.de/" target="new">OllyDbg</a> or SoftICE.</p>
<pre><span class="codeKeyword">__stdcall</span> <span class="codeKeyword">void</span> DynLoader(){_asm{<span class="codeComment">//----------------------------------</span>    DWORD_TYPE(DYN_LOADER_START_MAGIC)<span class="codeComment">//----------------------------------</span>Main_0:    PUSHAD    <span class="codeComment">// Save the registers context in stack</span>    CALL Main_1Main_1:    POP EBP    SUB EBP,OFFSET Main_1    MOV EAX,DWORD PTR [EBP+_RO_dwImageBase]    ADD EAX,DWORD PTR [EBP+_RO_dwOrgEntryPoint]    MOV DWORD PTR [ESP+54h],EAX    <span class="codeComment">// pStack.Eip &lt;- EAX</span>    POPAD    <span class="codeComment">// Restore the first registers context from stack</span>    CALL _OEP_Jump    DWORD_TYPE(0xCCCCCCCC)_OEP_Jump:    PUSH EBP    MOV EBP,ESP    MOV EAX,DWORD PTR [ESP+3Ch]    <span class="codeComment">// EAX &lt;- pStack.Eip</span>    MOV DWORD PTR [ESP+4h],EAX     <span class="codeComment">// _OEP_Jump RETURN pointer &lt;- EAX</span>    XOR EAX,EAX    LEAVE    RETN<span class="codeComment">//----------------------------------</span>    DWORD_TYPE(DYN_LOADER_START_DATA1)<span class="codeComment">//----------------------------------</span>_RO_dwImageBase:                DWORD_TYPE(0xCCCCCCCC)_RO_dwOrgEntryPoint:            DWORD_TYPE(0xCCCCCCCC)<span class="codeComment">//----------------------------------</span>    DWORD_TYPE(DYN_LOADER_END_MAGIC)<span class="codeComment">//----------------------------------</span>}}</pre>
<h4>5.3 Approach OEP by structured exception handling</h4>
<p><a name="more"><font color="#000000"> </font></a><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/key_s-z_4.asp" target="new"><tt>try-except</tt> statement</a> in C++ clarifies the operation of <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/about_structured_exception_handling.asp" target="new">structured exception handling</a>. Besides the assembly code of this code, it elucidates the structured exception handler installation, the raise of an exception, and the exception handler function.</p>
<p>An exception is generated when a program falls into a fault code execution and an error happens, so in such a special condition, the program immediately jumps to a function called the exception handler from exception handler list of the Thread Information Block.</p>
<p>The next example of a </p>
<pre><span class="codeKeyword">#include</span> &quot;stdafx.h&quot;<span class="codeKeyword">#include</span> &quot;windows.h&quot;<span class="codeKeyword">void</span> RAISE_AN_EXCEPTION(){_asm{    INT 3    INT 3    INT 3    INT 3}}<span class="codeKeyword">int</span> _tmain(<span class="codeKeyword">int</span> argc, _TCHAR* argv[]){    <span class="codeKeyword">__try</span>    {        <span class="codeKeyword">__try</span>{            printf(&quot;1: Raise an Exception\n&quot;);            RAISE_AN_EXCEPTION();        }        <span class="codeKeyword">__finally</span>        {            printf(&quot;2: In Finally\n&quot;);        }    }    <span class="codeKeyword">__except</span>( printf(&quot;3: In Filter\n&quot;), EXCEPTION_EXECUTE_HANDLER )    {        printf(&quot;4: In Exception Handler\n&quot;);    }    <span class="codeKeyword">return</span> 0;}</pre>
<pre><font color="#000000"><strong>; main()</strong></font><font color="#808080">00401000: PUSH EBP00401001: MOV EBP,ESP00401003: PUSH -100401005: PUSH 00407160<font color="#000000"><strong>; <span class="codeKeyword">__try</span> {</strong></font><font color="#008000">; the structured exception handler (SEH) installation </font><font color="#0000ff">0040100A: PUSH _except_handler30040100F: MOV EAX,DWORD PTR FS:[0]00401015: PUSH EAX00401016: MOV DWORD PTR FS:[0],ESP</font>0040101D: SUB ESP,800401020: PUSH EBX00401021: PUSH ESI00401022: PUSH EDI00401023: MOV DWORD PTR SS:[EBP-18],ESP<font color="#000000"><strong>;     <span class="codeKeyword">__try</span> {</strong></font>00401026: XOR ESI,ESI00401028: MOV DWORD PTR SS:[EBP-4],ESI0040102B: MOV DWORD PTR SS:[EBP-4],100401032: PUSH OFFSET <font color="#a52a2a">&quot;1: Raise an Exception&quot;</font>00401037: CALL printf0040103C: ADD ESP,4<font color="#008000">; the raise a exception, INT 3 exception</font>; RAISE_AN_EXCEPTION()<font color="#0000ff">0040103F: INT300401040: INT300401041: INT300401042: INT3</font><font color="#000000"><strong>;     } <span class="codeKeyword">__finally</span> {</strong></font>00401043: MOV DWORD PTR SS:[EBP-4],ESI00401046: CALL 0040104D0040104B: JMP 004010800040104D: PUSH OFFSET <font color="#a52a2a">&quot;2: In Finally&quot;</font>00401052: CALL printf00401057: ADD ESP,40040105A: RETN<font color="#000000"><strong>;     }</strong></font><font color="#000000"><strong>; }</strong></font><font color="#000000"><strong>; <span class="codeKeyword">__except</span>( </strong></font>0040105B: JMP 004010800040105D: PUSH OFFSET <font color="#a52a2a">&quot;3: In Filter&quot;</font>00401062: CALL printf00401067: ADD ESP,40040106A: MOV EAX,1 ; EXCEPTION_EXECUTE_HANDLER = 10040106F: RETN<font color="#000000"><strong>;     , EXCEPTION_EXECUTE_HANDLER )</strong></font><font color="#000000"><strong>; {</strong></font><font color="#008000">; the exception handler funtion</font><font color="#0000ff">00401070: MOV ESP,DWORD PTR SS:[EBP-18]00401073: PUSH OFFSET <font color="#a52a2a">&quot;4: In Exception Handler&quot;</font>00401078: CALL printf0040107D: ADD ESP,4</font><font color="#000000"><strong>; }</strong></font>00401080: MOV DWORD PTR SS:[EBP-4],-10040108C: XOR EAX,EAX<font color="#008000">; restore previous SEH</font><font color="#0000ff">0040108E: MOV ECX,DWORD PTR SS:[EBP-10]00401091: MOV DWORD PTR FS:[0],ECX</font>00401098: POP EDI00401099: POP ESI0040109A: POP EBX0040109B: MOV ESP,EBP0040109D: POP EBP0040109E: RETN</font></pre>
<p>Make a Win32 console project, and link and run the preceding C++ code, to perceive the result:</p>
<p>
<table cellspacing="0" cellpadding="0" width="400" border="1">
<tbody bgcolor="#000000" color="gray">
<tr>
<td><font color="#ffffff"><strong>1: Raise an Exception<br />                3: In Filter<br />                2: In Finally<br />                4: In Exception Handler<br />                _</p>
<p>                </strong></font></td>
</tr>
</tbody>
</table>
<p>This program runs the exception expression, <tt>printf(&quot;3: In Filter\n&quot;);</tt>, when an exception happens&mdash;in this example, the <tt>INT 3</tt> exception. You can employ other kinds of exception too. In <a href="http://www.ollydbg.de/" target="new">OllyDbg</a>, <strong>Debugging options-&gt;Exceptions</strong>, you can see a short list of different types of exceptions.</p>
<p><img height="200" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=OLLYDBG_EXCEPTIONS_GIF&amp;ds=20060302" width="280" alt="" /></p>
<h5>5.3.1 Implement Exception Handler</h5>
<p>You want to construct a structured exception handler to reach OEP. Now, I think you have distinguished the SEH installation, the exception raise, and the exception expression filter, by foregoing the assembly code. To establish your exception handler approach, you need to comprise the following codes:</p>
<ul>
<li><strong>SEH installation</strong>:
<pre><font color="#808080">LEA EAX,[EBP+_except_handler1_OEP_Jump]PUSH EAXPUSH DWORD PTR FS:[0]MOV DWORD PTR FS:[0],ESP</font></pre>
</li>
<li><strong>An Exception Raise</strong>:
<pre><font color="#808080">INT 3</font></pre>
</li>
<li><strong>Exception handler expression filter</strong>:
<pre><font color="#808080">_except_handler1_OEP_Jump:   PUSH EBP   MOV EBP,ESP   ...   <span class="codeComment">// EXCEPTION_CONTINUE_SEARCH = 0</span>   MOV EAX, EXCEPTION_CONTINUE_SEARCH   LEAVE   RETN</font></pre>
</li>
</ul>
<p>So, you yearn to make the ensuing C++ code in assembly language to inaugurate your engine to approach the Offset of the Entry Point by SEH.</p>
<pre><span class="codeKeyword">__try</span>    <span class="codeComment">// SEH installation</span>{    __asm    {        INT 3    <span class="codeComment">// An Exception Raise</span>    }}<span class="codeKeyword">__except</span>( ..., EXCEPTION_CONTINUE_SEARCH ){}<span class="codeComment">// Exception handler expression filter</span></pre>
<p>In assembly code&#8230;</p>
<pre><font color="#808080">    <font color="#008000">; ----------------------------------------------------    ; the structured exception handler (SEH) installation    <font color="#000000"><strong>; <span class="codeKeyword">__try</span> {</strong></font></font>    LEA EAX,[EBP+_except_handler1_OEP_Jump]    PUSH EAX    PUSH DWORD PTR FS:[0]    MOV DWORD PTR FS:[0],ESP    <font color="#008000">; ----------------------------------------------------    ; the raise a INT 3 exception</font>    INT 3    INT 3    INT 3    INT 3    <font color="#000000"><strong>; }    ; <span class="codeKeyword">__except</span>( ... </strong></font>    <font color="#008000">; ----------------------------------------------------    ; exception handler expression filter</font>_except_handler1_OEP_Jump:    PUSH EBP    MOV EBP,ESP    ...    MOV EAX, EXCEPTION_CONTINUE_SEARCH ; EXCEPTION_CONTINUE_SEARCH = 0    LEAVE    RETN    <font color="#000000"><strong>; , EXCEPTION_CONTINUE_SEARCH ) { }</strong></font></font></pre>
<p>The exception value, <tt>__except(..., Value)</tt>, determines how the exception is handled. It can have three values: 1, 0, -1. To understand them, refer to the <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/key_s-z_4.asp" target="new"><tt>try-except</tt> statement</a> description in the MSDN library. You set it to <tt>EXCEPTION_CONTINUE_SEARCH (0)</tt>, not to run the exception handler function; therefore, by this value, the exception is not recognized. It is simply ignored, and the thread continues its code execution.</p>
<h4>How the SEH installation is implemented</h4>
<p>As you perceived from the illustrated code, the SEH installation is done by the FS segment register. Microsoft Windows 32 bit uses the FS segment register as a pointer to the data block of the main thread. The first <font color="#0000ff">0x1C</font> bytes comprise the information of the Thread Information Block (TIB). Therefore, <tt>FS:[00h]</tt> refers to <tt>ExceptionList</tt> of the main thread, Table 3. In your code, you have pushed the pointer to <tt>_except_handler1_OEP_Jump</tt> in the stack and changed the value of <tt>ExceptionList</tt>, <tt>FS:[00h]</tt>, to the beginning of the stack, <tt>ESP</tt>.</p>
<h4>Thread Information Block (TIB)</h4>
<pre><span class="codeKeyword">typedef</span> <span class="codeKeyword">struct</span> _NT_TIB32 {   DWORD ExceptionList;   DWORD StackBase;   DWORD StackLimit;   DWORD SubSystemTib;   <span class="codeKeyword">union</span> {      DWORD FiberData;      DWORD Version;   };   DWORD ArbitraryUserPointer;   DWORD Self;} NT_TIB32, *PNT_TIB32;</pre>
<h4>Table 3: FS segment register and Thread Information Block</h4>
<table cellspacing="0" cellpadding="0" border="1">
<tbody>
<tr>
<td align="center"><font color="#0000ff">DWORD PTR FS:[00h]</font></td>
<td align="center">ExceptionList</td>
</tr>
<tr>
<td align="center"><font color="#0000ff">DWORD PTR FS:[04h]</font></td>
<td align="center">StackBase</td>
</tr>
<tr>
<td align="center"><font color="#0000ff">DWORD PTR FS:[08h]</font></td>
<td align="center">StackLimit</td>
</tr>
<tr>
<td align="center"><font color="#0000ff">DWORD PTR FS:[0Ch]</font></td>
<td align="center">SubSystemTib</td>
</tr>
<tr>
<td align="center"><font color="#0000ff">DWORD PTR FS:[10h]</font></td>
<td align="center">FiberData / Version</td>
</tr>
<tr>
<td align="center"><font color="#0000ff">DWORD PTR FS:[14h]</font></td>
<td align="center">ArbitraryUserPointer</td>
</tr>
<tr>
<td align="center"><font color="#0000ff">DWORD PTR FS:[18h]</font></td>
<td align="center">Self</td>
</tr>
</tbody>
</table>
<h5>5.3.2 Attain OEP by adjusting the Thread Context</h5>
<p>In this part, you effectuate your performance by accomplishing the OEP approach. You change the Context of the thread and ignore every simple exception handling, and let the thread continue the execution, but in the original OEP!</p>
<p>    <a name="more"><font color="#000000">&nbsp;</font>
<p>When an exception happens, the context of the processor during the time of the exception is saved in the stack. Through </p>
<pre>MOV EAX, ContextRecordMOV EDI, dwOEP                   ; EAX &lt;- dwOEPMOV DWORD PTR DS:[EAX+0B8h], EDI ; pContext.Eip &lt;- EAX</pre>
<h4>Win32 Thread Context structure</h4>
<pre><span class="codeKeyword">#define</span> MAXIMUM_SUPPORTED_EXTENSION     512<span class="codeKeyword">typedef</span> <span class="codeKeyword">struct</span> _CONTEXT {    <span class="codeComment">//-----------------------------------------</span>    DWORD ContextFlags;    <span class="codeComment">//-----------------------------------------</span>    DWORD   Dr0;    DWORD   Dr1;    DWORD   Dr2;    DWORD   Dr3;    DWORD   Dr6;    DWORD   Dr7;    <span class="codeComment">//-----------------------------------------</span>    FLOATING_SAVE_AREA FloatSave;    <span class="codeComment">//-----------------------------------------</span>    DWORD   SegGs;    DWORD   SegFs;    DWORD   SegEs;    DWORD   SegDs;    <span class="codeComment">//-----------------------------------------</span>    DWORD   Edi;    DWORD   Esi;    DWORD   Ebx;    DWORD   Edx;    DWORD   Ecx;    DWORD   Eax;    <span class="codeComment">//-----------------------------------------</span>    DWORD   Ebp;    DWORD   Eip;    DWORD   SegCs;    DWORD   EFlags;    DWORD   Esp;    DWORD   SegSs;    <span class="codeComment">//-----------------------------------------</span>    BYTE    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];    <span class="codeComment">//----------------------------------------</span>} CONTEXT,*LPCONTEXT;</pre>
<h4>Table 4: CONTEXT</h4>
<table cellspacing="0" cellpadding="0" width="200" border="1">
<tbody>
<tr>
<td align="center" height="35">Context Flags</td>
<td align="center" height="35"><font color="#0000ff">0&#215;00000000</font></td>
<td align="center" colspan="2" height="35"><tt>ContextFlags</tt></td>
</tr>
<tr>
<td align="center" rowspan="6">
<p>Context Debug Registers</p>
</td>
<td align="center"><font color="#0000ff">0&#215;00000004</font></td>
<td align="center" colspan="2"><tt>Dr0</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000008</font></td>
<td align="center" colspan="2"><tt>Dr1</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0x0000000C</font></td>
<td align="center" colspan="2"><tt>Dr2</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000010</font></td>
<td align="center" colspan="2"><tt>Dr3</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000014</font></td>
<td align="center" colspan="2"><tt>Dr6</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000018</font></td>
<td align="center" colspan="2"><tt>Dr7</tt></td>
</tr>
<tr>
<td align="center" rowspan="9">
<p>Context Floating Point</p>
</td>
<td align="center"><font color="#0000ff">0x0000001C</font></td>
<td align="center" rowspan="9"><tt>FloatSave</tt></td>
<td align="center"><tt>StatusWord</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000020</font></td>
<td align="center"><tt>StatusWord</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000024</font></td>
<td align="center"><tt>TagWord</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000028</font></td>
<td align="center"><tt>ErrorOffset</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0x0000002C</font></td>
<td align="center"><tt>ErrorSelector</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000030</font></td>
<td align="center"><tt>DataOffset</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000034</font></td>
<td align="center"><tt>DataSelector</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000038<br />                &#8230;<br />                0&#215;00000087</font></td>
<td align="center"><tt>RegisterArea</tt> [<font color="#0000ff">0x50</font>]</td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000088</font></td>
<td align="center"><tt>Cr0NpxState</tt></td>
</tr>
<tr>
<td align="center" rowspan="4">Context Segments</td>
<td align="center"><font color="#0000ff">0x0000008C</font></td>
<td align="center" colspan="2"><tt>SegGs</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000090</font></td>
<td align="center" colspan="2"><tt>SegFs</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000094</font></td>
<td align="center" colspan="2"><tt>SegEs</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0&#215;00000098</font></td>
<td align="center" colspan="2"><tt>SegDs</tt></td>
</tr>
<tr>
<td align="center" rowspan="6">Context Integer</td>
<td align="center"><font color="#0000ff">0x0000009C</font></td>
<td align="center" colspan="2"><tt>Edi</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0x000000A0</font></td>
<td align="center" colspan="2"><tt>Esi</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0x000000A4</font></td>
<td align="center" colspan="2"><tt>Ebx</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0x000000A8</font></td>
<td align="center" colspan="2"><tt>Edx</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0x000000AC</font></td>
<td align="center" colspan="2"><tt>Ecx</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0x000000B0</font></td>
<td align="center" colspan="2"><tt>Eax</tt></td>
</tr>
<tr>
<td align="center" rowspan="6">Context Control</td>
<td align="center"><font color="#0000ff">0x000000B4</font></td>
<td align="center" colspan="2"><tt>Ebp</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0x000000B8</font></td>
<td align="center" colspan="2"><tt>Eip</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0x000000BC</font></td>
<td align="center" colspan="2"><tt>SegCs</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0x000000C0</font></td>
<td align="center" colspan="2"><tt>EFlags</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0x000000C4</font></td>
<td align="center" colspan="2"><tt>Esp</tt></td>
</tr>
<tr>
<td align="center"><font color="#0000ff">0x000000C8</font></td>
<td align="center" colspan="2"><tt>SegSs</tt></td>
</tr>
<tr>
<td align="center">Context Extended Registers</td>
<td align="center">
<p align="center"><font color="#0000ff">0x000000CC<br />                &#8230;<br />                0x000002CB</font></p>
</td>
<td align="center" colspan="2"><tt>ExtendedRegisters</tt>[<font color="#0000ff">0x200</font>]</td>
</tr>
</tbody>
</table>
<p>By the following code, you have accomplished the main purpose of coming to OEP by the structured exception handler:</p>
<pre><span class="codeKeyword">__stdcall</span> <span class="codeKeyword">void</span> DynLoader(){_asm{<span class="codeComment">//----------------------------------</span>    DWORD_TYPE(DYN_LOADER_START_MAGIC)<span class="codeComment">//----------------------------------</span>Main_0:    PUSHAD  <span class="codeComment">// Save the registers context in stack</span>    CALL Main_1Main_1:    POP EBP    SUB EBP,OFFSET Main_1 <span class="codeComment">// Get Base EBP</span>    MOV EAX,DWORD PTR [EBP+_RO_dwImageBase]    ADD EAX,DWORD PTR [EBP+_RO_dwOrgEntryPoint]    MOV DWORD PTR [ESP+10h],EAX    <span class="codeComment">// pStack.Ebx &lt;- EAX</span>    LEA EAX,[EBP+_except_handler1_OEP_Jump]    MOV DWORD PTR [ESP+1Ch],EAX    <span class="codeComment">// pStack.Eax &lt;- EAX</span>    POPAD  <span class="codeComment">// Restore the first registers context from stack</span>    <span class="codeComment">//----------------------------------------------------</span>    <span class="codeComment">// the structured exception handler (SEH) installation</span>    PUSH EAX    XOR  EAX, EAX    PUSH DWORD PTR FS:[0]       <span class="codeComment">// NT_TIB32.ExceptionList</span>    MOV DWORD PTR FS:[0],ESP    <span class="codeComment">// NT_TIB32.ExceptionList &lt;-ESP</span>    <span class="codeComment">//----------------------------------------------------</span>    <span class="codeComment">// the raise a INT 3 exception</span>    DWORD_TYPE(0xCCCCCCCC)    <span class="codeComment">//--------------------------------------------------------</span><span class="codeComment">// -------- exception handler expression filter ----------</span>_except_handler1_OEP_Jump:    PUSH EBP    MOV EBP,ESP    <span class="codeComment">//------------------------------</span>    MOV EAX,DWORD PTR SS:[EBP+010h]   <span class="codeComment">// PCONTEXT: pContext &lt;- EAX</span>    <span class="codeComment">//==============================</span>    PUSH EDI    <span class="codeComment">// restore original SEH</span>    MOV EDI,DWORD PTR DS:[EAX+0C4h]    <span class="codeComment">// pContext.Esp</span>    PUSH DWORD PTR DS:[EDI]    POP DWORD PTR FS:[0]    ADD DWORD PTR DS:[EAX+0C4h],8    <span class="codeComment">// pContext.Esp</span>    <span class="codeComment">//------------------------------</span>    <span class="codeComment">// set the Eip to the OEP</span>    MOV EDI,DWORD PTR DS:[EAX+0A4h] <span class="codeComment">// EAX &lt;- pContext.Ebx</span>    MOV DWORD PTR DS:[EAX+0B8h],EDI <span class="codeComment">// pContext.Eip &lt;- EAX</span>    <span class="codeComment">//------------------------------</span>    POP EDI    <span class="codeComment">//==============================</span>    MOV EAX, EXCEPTION_CONTINUE_SEARCH    LEAVE    RETN<span class="codeComment">//----------------------------------</span>    DWORD_TYPE(DYN_LOADER_START_DATA1)<span class="codeComment">//----------------------------------</span>_RO_dwImageBase:                DWORD_TYPE(0xCCCCCCCC)_RO_dwOrgEntryPoint:            DWORD_TYPE(0xCCCCCCCC)<span class="codeComment">//----------------------------------</span>    DWORD_TYPE(DYN_LOADER_END_MAGIC)<span class="codeComment">//----------------------------------</span>}}</pre>
<h3>6 Build an Import Table and Reconstruct the Original Import Table</h3>
<p>There are two ways to use the Windows <a href="http://en.wikipedia.org/wiki/Microsoft_Dynamic_Link_Library" target="new">dynamic link library (DLL)</a> in Windows application programming:</p>
<ul>
<li><strong>Using Windows libraries by additional dependencies</strong>:&nbsp;<br />        <a name="more"><font color="#000000"> </font>
<p><font color="#000000"><img height="145" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=DEPENDENCIES_GIF&amp;ds=20060302" width="500" alt="" /><br />        </font>(</p>
<p>        </a><a href="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=DEPENDENCIES_GIF&amp;ds=20060302" target="_blank">Full Size Image</a>)</li>
<li><strong>Using Windows dynamic link libraries in run-time</strong>:
<pre><span class="codeComment">// DLL function signature</span><span class="codeKeyword">typedef</span> HGLOBAL (*importFunction_GlobalAlloc)(UINT, SIZE_T);...importFunction_GlobalAlloc __GlobalAlloc;<span class="codeComment">// Load DLL file</span>HINSTANCE hinstLib = LoadLibrary(&quot;Kernel32.dll&quot;);<span class="codeKeyword">if</span> (hinstLib == <span class="codeKeyword">NULL</span>){   <span class="codeComment">// Error - unable to load DLL</span>}<span class="codeComment">// Get function pointer</span>__GlobalAlloc =   (importFunction_GlobalAlloc)GetProcAddress(hinstLib,                                              &quot;GlobalAlloc&quot;);<span class="codeKeyword">if</span> (addNumbers == <span class="codeKeyword">NULL</span>){    <span class="codeComment">// Error - unable to find DLL function</span>}FreeLibrary(hinstLib);</pre>
</li>
</ul>
<p>When you make a Windows application project, the linker includes at least <em>kernel32.dll</em> in the base dependencies of your project. Without <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/loadlibrary.asp" target="new"><tt>LoadLibrary()</tt></a> and <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocaddress.asp" target="new"><tt>GetProcAddress()</tt></a> of <em>Kernel32.dll</em>, you cannot load a DLL at run time. The dependencies information is stored in the import table section. By using <a href="http://www.microsoft.com/resources/documentation/Windows/XP/all/reskit/en-us/Default.asp?url=/resources/documentation/Windows/XP/all/reskit/en-us/prmb_tol_kewf.asp" target="new">Dependency Walker</a>, it is not so difficult to observe the DLL module and the functions that are imported into a PE file.</p>
<p><img height="352" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=DEPENDENCY_WALKER_GIF&amp;ds=20060302" width="480" alt="" /></p>
<p>You attempt to establish your custom import table to conduct your project. Furthermore, you have to fix up the original import table at the end to run the real code of the program.</p>
<h4>PE Maker: Step 3</h4>
<p>Download the pemaker3.zip source files from the end of the article.</p>
<h4>6.1 Construct the Client Import Table</h4>
<p>I strongly advise that you to read Section 6.4 of the <a href="http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx" target="new">Microsoft Portable Executable and the Common Object File Format Specification</a> document. This section contains the principal information to comprehend the import table performance. The import table data is accessible by a second data directory of the optional header from PE headers, so you can access it by using the following code:</p>
<pre>DWORD dwVirtualAddress = image_nt_headers-&gt;   OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].      VirtualAddress;DWORD dwSize = image_nt_headers-&gt;   OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].      Size;</pre>
<p>The <tt>VirtualAddress</tt> refers to structures by <tt>IMAGE_IMPORT_DESCRIPTOR</tt>. This structure contains the pointer to the imported DLL name and the relative virtual address of the first thunk.</p>
<pre><span class="codeKeyword">typedef</span> <span class="codeKeyword">struct</span> _IMAGE_IMPORT_DESCRIPTOR {    <span class="codeKeyword">union</span> {        DWORD   Characteristics;        DWORD   OriginalFirstThunk;    };    DWORD   TimeDateStamp;    DWORD   ForwarderChain;    DWORD   <font color="#ff0000">Name</font>;         <span class="codeComment">// the imported DLL name</span>    DWORD   <font color="#ff0000">FirstThunk</font>;   <span class="codeComment">// the relative virtual address of the</span>                          <span class="codeComment">// first thunk</span>} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;</pre>
<p>When a program is running, the Windows Task Manager sets the thunks by the virtual address of the function. The virtual address is found by the name of the function. At first, the thunks hold the relative virtual address of the function name, as shown in Table 5; during execution, they are fixed up by the virtual address of the functions (see Table 6).</p>
<h4>Table 5: The Import Table in a file image</h4>
<p>
<table cellspacing="0" cellpadding="0" border="1">
<tbody>
<tr>
<td rowspan="8"><tt>IMAGE_IMPORT_<br />                DESCRIPTOR[0]</tt></td>
<td><tt>OriginalFirstThunk</tt></td>
<td colspan="2" rowspan="3">&nbsp;</td>
<td colspan="2" rowspan="4">&nbsp;</td>
</tr>
<tr>
<td><tt>TimeDateStamp</tt></td>
</tr>
<tr>
<td><tt>ForwarderChain</tt></td>
</tr>
<tr>
<td><tt>Name_RVA</tt></td>
<td>&#8212;&#8212;&gt;</td>
<td><font color="#a52a2a">&quot;kernel32.dll&quot;<font color="#0000ff">,0</font></font></td>
</tr>
<tr>
<td><tt>FirstThunk_RVA</tt></td>
<td>&#8212;&#8212;&gt;</td>
<td><tt>proc_1_name_RVA</tt></td>
<td>&#8212;&#8212;&gt;</td>
<td><font color="#0000ff">0,0,</font><font color="#a52a2a">&quot;LoadLibraryA&quot;</font><font color="#0000ff">,0</font></td>
</tr>
<tr>
<td colspan="2" rowspan="3">&nbsp;</td>
<td><tt>proc_2_name_RVA</tt></td>
<td>&#8212;&#8212;&gt;</td>
<td><font color="#0000ff">0,0,</font><font color="#a52a2a">&quot;GetProcAddress&quot;</font><font color="#0000ff">,0</font></td>
</tr>
<tr>
<td><tt>proc_3_name_RVA</tt></td>
<td>&#8212;&#8212;&gt;</td>
<td><font color="#0000ff">0,0,</font><font color="#a52a2a">&quot;GetModuleHandleA&quot;</font><font color="#0000ff">,0</font></td>
</tr>
<tr>
<td>&#8230;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><tt>IMAGE_IMPORT_<br />                DESCRIPTOR[1]</tt></td>
<td colspan="5">&nbsp;</td>
</tr>
<tr>
<td><tt>...</tt></td>
<td colspan="5">&nbsp;</td>
</tr>
<tr>
<td><tt>IMAGE_IMPORT_<br />                DESCRIPTOR[n]</tt></td>
<td colspan="5">&nbsp;</td>
</tr>
</tbody>
</table>
<h4>Table 6: The Import Table in virtual memory</h4>
<p>
<table cellspacing="0" cellpadding="0" border="1">
<tbody>
<tr>
<td rowspan="8"><tt>IMAGE_IMPORT_DESCRIPTOR[0]</tt></td>
<td><tt>OriginalFirstThunk</tt></td>
<td colspan="2" rowspan="3">&nbsp;</td>
</tr>
<tr>
<td><tt>TimeDateStamp</tt></td>
</tr>
<tr>
<td><tt>ForwarderChain</tt></td>
</tr>
<tr>
<td><tt>Name_RVA</tt></td>
<td><tt>------&gt;</tt></td>
<td><font color="#a52a2a">&quot;kernel32.dll&quot;<font color="#0000ff">,0</font></font></td>
</tr>
<tr>
<td><tt>FirstThunk_RVA</tt></td>
<td><tt>------&gt;</tt></td>
<td><tt>proc_1_VA</tt></td>
</tr>
<tr>
<td colspan="2" rowspan="3">&nbsp;</td>
<td><tt>proc_2_VA</tt></td>
</tr>
<tr>
<td><tt>proc_3_VA</tt></td>
</tr>
<tr>
<td><tt>...</tt></td>
</tr>
<tr>
<td><tt>IMAGE_IMPORT_DESCRIPTOR[1]</tt></td>
<td colspan="3">&nbsp;</td>
</tr>
<tr>
<td><tt>...</tt></td>
<td colspan="3">&nbsp;</td>
</tr>
<tr>
<td><tt>IMAGE_IMPORT_DESCRIPTOR[n]</tt></td>
<td colspan="3">&nbsp;</td>
</tr>
</tbody>
</table>
<p>You want to make a simple import table to import <tt>LoadLibrary()</tt>, and <tt>GetProcAddress()</tt> from <em>Kernel32.dll</em>. You need these two essential API functions to cover other API functions in run-time. The following assembly code shows how easily you can reach your solution:</p>
<pre><font color="#808080">0101F000: <font color="#0000ff">00000000</font> ; OriginalFirstThunk0101F004: <font color="#0000ff">00000000</font> ; TimeDateStamp0101F008: <font color="#0000ff">00000000</font> ; ForwarderChain0101F00C: <font color="#0000ff">0001F034</font> ; Name;       ImageBase + 0001F034                                 -&gt; 0101F034 -&gt; &quot;Kernel32.dll&quot;,00101F010: <font color="#0000ff">0001F028</font> ; FirstThunk; ImageBase + 0001F028 -&gt; 0101F0280101F014: <font color="#0000ff">00000000</font>0101F018: <font color="#0000ff">00000000</font>0101F01C: <font color="#0000ff">00000000</font>0101F020: <font color="#0000ff">00000000</font>0101F024: <font color="#0000ff">00000000</font>0101F028: <font color="#0000ff">0001F041</font> ; ImageBase + 0001F041 -&gt; 0101F041                     -&gt; 0,0,&quot;LoadLibraryA&quot;,00101F02C: <font color="#0000ff">0001F050</font> ; ImageBase + 0001F050 -&gt; 0101F050                     -&gt; 0,0,&quot;GetProcAddress&quot;,00101F030: <font color="#0000ff">00000000</font>0101F034: <font color="#a52a2a"><span class="codeComment">'K' 'e' 'r' 'n' 'e' 'l' '3' '2' '.' 'd' 'l' 'l' </span>0001F041: <font color="#0000ff">00 00</font> <font color="#a52a2a"><span class="codeComment">'L' 'o' 'a' 'd' 'L' 'i' 'b' 'r' 'a' 'r' 'y' 'A'</span>0001F050: <font color="#0000ff">00 00</font> <font color="#a52a2a"><span class="codeComment">'G' 'e' 't' 'P' 'r' 'o' 'c' 'A' 'd' 'd' 'r' 'e' 's'</span>          <span class="codeComment">'s'</span></font> <font color="#0000ff">00</font></font> <font color="#0000ff">00</font></font><font color="#0000ff">00</font></font></pre>
<p>After running&#8230;</p>
<pre><font color="#808080">0101F000: <font color="#0000ff">00000000</font> ; OriginalFirstThunk0101F004: <font color="#0000ff">00000000</font> ; TimeDateStamp0101F008: <font color="#0000ff">00000000</font> ; ForwarderChain0101F00C: <font color="#0000ff">0001F034</font> ; Name;       ImageBase + 0001F034                                 -&gt; 0101F034 -&gt; &quot;Kernel32.dll&quot;,00101F010: <font color="#0000ff">0001F028</font> ; FirstThunk; ImageBase + 0001F028 -&gt; 0101F0280101F014: <font color="#0000ff">00000000</font>0101F018: <font color="#0000ff">00000000</font>0101F01C: <font color="#0000ff">00000000</font>0101F020: <font color="#0000ff">00000000</font>0101F024: <font color="#0000ff">00000000</font>0101F028: <font color="#ff0000">7C801D77</font> ; -&gt; Kernel32.LoadLibrary()0101F02C: <font color="#ff0000">7C80AC28</font> ; -&gt; Kernel32.GetProcAddress()0101F030: <font color="#0000ff">00000000</font>0101F034: <font color="#a52a2a"><span class="codeComment">'K' 'e' 'r' 'n' 'e' 'l' '3' '2' '.' 'd' 'l' 'l' </span>0001F041: <font color="#0000ff">00 00</font> <font color="#a52a2a"><span class="codeComment">'L' 'o' 'a' 'd' 'L' 'i' 'b' 'r' 'a' 'r' 'y' 'A'</span>0001F050: <font color="#0000ff">00 00</font> <font color="#a52a2a"><span class="codeComment">'G' 'e' 't' 'P' 'r' 'o' 'c' 'A' 'd' 'd' 'r' 'e' 's'</span>          <span class="codeComment">'s'</span></font> <font color="#0000ff">00</font></font> <font color="#0000ff">00</font></font><font color="#0000ff">00</font></font></pre>
<p>I have prepared a class library to make every import table by using a client string table. The <tt>CITMaker</tt> class library in <em>itmaker.h</em>; it will build an import table by <tt>sz_IT_EXE_strings</tt> and also the relative virtual address of the import table.</p>
<pre><span class="codeKeyword">static</span> <span class="codeKeyword">const</span> <span class="codeKeyword">char</span> *sz_IT_EXE_strings[]={    &quot;Kernel32.dll&quot;,    &quot;LoadLibraryA&quot;,    &quot;GetProcAddress&quot;,    0,,    0,};</pre>
<p>You subsequently employ this class library to establish an import table to support DLLs and OCXs, so this is a general library to present all possible import tables easily. The next step is clarified in the following code.</p>
<pre>CITMaker *<font color="#ff0000">ImportTableMaker</font> = <span class="codeKeyword">new</span> CITMaker( IMPORT_TABLE_EXE );...pimage_section_header=AddNewSection( &quot;.xxx&quot;, dwNewSectionSize );<span class="codeComment">// build import table by the current virtual address</span><font color="#ff0000">ImportTableMaker</font>-&gt;<font color="#008000">Build</font>( <font color="#0000ff">pimage_section_header-&gt;VirtualAddress</font> );memcpy( pNewSection, <font color="#ff0000">ImportTableMaker</font>-&gt;<font color="#008000">pMem</font>,<font color="#ff0000">ImportTableMaker</font>-&gt;<font color="#008000">dwSize</font> );...memcpy( image_section[image_nt_headers-&gt;FileHeader.NumberOfSections-1],        pNewSection,        dwNewSectionSize );...image_nt_headers-&gt;OptionalHeader.  DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress  = <font color="#0000ff">pimage_section_header-&gt;VirtualAddress</font>;image_nt_headers-&gt;OptionalHeader.  DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size  = <font color="#ff0000">ImportTableMaker</font>-&gt;<font color="#008000">dwSize</font>;...<span class="codeKeyword">delete</span> <font color="#ff0000">ImportTableMaker</font>;</pre>
<p>The import table is copied at the beginning of the new section, and the relevant data directory is adjusted to the relative virtual address of the new section and the size of the new import table.</p>
<h4>6.2 Using other API functions at run time</h4>
<p>At this time, you can load other DLLs and find the process address of other functions by using <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/loadlibrary.asp" target="new"><tt>LoadLibrary()</tt></a> and <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocaddress.asp" target="new"><tt>GetProcAddress()</tt></a>:</p>
<pre><font color="#808080">lea edi, <font color="#ff0000">@</font><font color="#a52a2a">&quot;Kernel32.dll&quot;</font><span class="codeComment">//-------------------</span><font color="#0000ff">push edimov eax,offset _p_LoadLibrarycall [ebp+eax] <span class="codeComment">//LoadLibrary(lpLibFileName);</span><span class="codeComment">//-------------------</span>mov esi,eax    <span class="codeComment">// esi -&gt; hModule</span>lea edi, <font color="#ff0000">@</font><font color="#a52a2a">&quot;GetModuleHandleA&quot;</font><span class="codeComment">//-------------------</span><font color="#0000ff">push edipush esimov eax,offset _p_GetProcAddresscall [ebp+eax] <span class="codeComment">//GetModuleHandle=GetProcAddress(hModule, lpProcName);</span><span class="codeComment">//--------------------</span></font></font></font></pre>
<p>    <a name="more"><font color="#000000">&nbsp;</font></a><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/loadlibrary.asp" target="new"><tt>LoadLibrary()</tt></a> and <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocaddress.asp" target="new"><tt>GetProcAddress()</tt></a> aid you in your effort to reach your intention.</p>
<p>I want to have a complete imported function table similar in performance done in a real EXE file. If you look inside a PE file, you will discover that an API call is done by an indirection jump through the virtual address of the API function:</p>
<h4>JMP DWORD PTR [XXXXXXXX]</h4>
<pre><font color="#808080">...0101F028: <font color="#ff0000">7C801D77</font>      ; Virtual Address of kernel32.LoadLibrary()...0101F120: JMP DWORD PTR [<font color="#ff0000">0101F028</font>]...0101F230: CALL <font color="#ff0000">0101F120</font> ;  JMP to kernel32.LoadLibrary...</font></pre>
<p>It makes it easy to expand the other part of your project by this performance, so you construct two data tables: the first for API virtual addresses, and the second for the <tt>JMP [XXXXXXXX]</tt>.</p>
<pre><span class="codeKeyword">#define</span> __jmp_api               byte_type(0xFF) byte_type(0x25)__asm{...<span class="codeComment">//----------------------------------------------------------------</span>_p_GetModuleHandle:             dword_type(0xCCCCCCCC)_p_VirtualProtect:              dword_type(0xCCCCCCCC)_p_GetModuleFileName:           dword_type(0xCCCCCCCC)_p_CreateFile:                  dword_type(0xCCCCCCCC)_p_GlobalAlloc:                 dword_type(0xCCCCCCCC)<span class="codeComment">//----------------------------------------------------------------</span>_jmp_GetModuleHandle:           __jmp_api   dword_type(0xCCCCCCCC)_jmp_VirtualProtect:            __jmp_api   dword_type(0xCCCCCCCC)_jmp_GetModuleFileName:         __jmp_api   dword_type(0xCCCCCCCC)_jmp_CreateFile:                __jmp_api   dword_type(0xCCCCCCCC)_jmp_GlobalAlloc:               __jmp_api   dword_type(0xCCCCCCCC)<span class="codeComment">//----------------------------------------------------------------</span>...}</pre>
<p>In the succeeding code, you have concluded your ambition to install a custom internal import table! (You cannot call it import table.)</p>
<pre><font color="#808080">    ...    lea edi,[ebp+_p_szKernel32]    lea ebx,[ebp+_p_GetModuleHandle]    lea ecx,[ebp+_jmp_GetModuleHandle]    add ecx,02h_api_get_lib_address_loop:        push ecx        <font color="#0000ff">push edi        mov eax,offset _p_LoadLibrary        call [ebp+eax]    <span class="codeComment">//LoadLibrary(lpLibFileName);</span>        pop ecx        mov esi,eax       <span class="codeComment">// esi -&gt; hModule</span>        push edi        call __strlen        add esp,04h        add edi,eax_api_get_proc_address_loop:            push ecx            <font color="#0000ff">push edi            push esi            mov eax,offset _p_GetProcAddress            <span class="codeComment">//GetModuleHandle=GetProcAddress(hModule, lpProcName);</span>            call [ebp+eax]            pop ecx</font>            <font color="#008000">mov [ebx],eax            mov [ecx],ebx    <span class="codeComment">// JMP DWORD PTR [XXXXXXXX]</span>            add ebx,04h            add ecx,06h            push edi            call __strlen            add esp,04h            add edi,eax            mov al,<span class="codeKeyword">byte</span> ptr [edi]        test al,al        jnz _api_get_proc_address_loop        inc edi        mov al,<span class="codeKeyword">byte</span> ptr [edi]    test al,al    jnz _api_get_lib_address_loop    ...</font></font></font></pre>
<h4>6.3 Fix up the Original Import Table</h4>
<p>To run the program again, you should fix up the thunks of the actual import table; otherwise, you have a corrupted target PE file. Your code must correct all of the thunks the same as Table 5 to Table 6. Once more, </p>
<pre><font color="#808080">    ...    mov ebx,[ebp+<font color="#ff0000">_p_dwImportVirtualAddress</font>]    test ebx,ebx    jz _it_fixup_end    mov esi,[ebp+<font color="#ff0000">_p_dwImageBase</font>]    add ebx,esi             <span class="codeComment">// dwImageBase + dwImportVirtualAddress</span>_it_fixup_get_lib_address_loop:        mov eax,[ebx+00Ch]  <span class="codeComment">// image_import_descriptor.Name</span>        test eax,eax        jz _it_fixup_end        mov ecx,[ebx+010h]  <span class="codeComment">// image_import_descriptor.FirstThunk</span>        add ecx,esi        mov [ebp+<font color="#ff0000">_p_dwThunk</font>],ecx    <span class="codeComment">// dwThunk</span>        mov ecx,[ebx]       <span class="codeComment">// image_import_descriptor.Characteristics</span>        test ecx,ecx        jnz _it_fixup_table            mov ecx,[ebx+010h]_it_fixup_table:        add ecx,esi        mov [ebp+<font color="#ff0000">_p_dwHintName</font>],ecx    <span class="codeComment">// dwHintName</span>        add eax,esi  <span class="codeComment">// image_import_descriptor.Name + dwImageBase = ModuleName</span>        <font color="#0000ff">push eax     <span class="codeComment">// lpLibFileName</span>        mov eax,offset _p_LoadLibrary        call [ebp+eax]               <span class="codeComment">// LoadLibrary(lpLibFileName);</span>        test eax,eax        jz _it_fixup_end        mov edi,eax_it_fixup_get_proc_address_loop:            mov ecx,[ebp+<font color="#ff0000">_p_dwHintName</font>]    <span class="codeComment">// dwHintName</span>            mov edx,[ecx]            <span class="codeComment">// image_thunk_data.Ordinal</span>            test edx,edx            jz _it_fixup_next_module            test edx,080000000h      <span class="codeComment">// .IF( import by ordinal )</span>            jz _it_fixup_by_name                and edx,07FFFFFFFh    <span class="codeComment">// get ordinal</span>                jmp _it_fixup_get_addr_it_fixup_by_name:            add edx,esi  <span class="codeComment">// image_thunk_data.Ordinal</span>                         <span class="codeComment">// + dwImageBase = OrdinalName</span>            inc edx            inc edx                  <span class="codeComment">// OrdinalName.Name</span>_it_fixup_get_addr:            <font color="#0000ff">push edx <span class="codeComment">//lpProcName</span>            push edi                 <span class="codeComment">// hModule</span>            mov eax,offset _p_GetProcAddress            call [ebp+eax]    <span class="codeComment">// GetProcAddress(hModule, lpProcName);</span>            <font color="#008000">mov ecx,[ebp+<font color="#ff0000">_p_dwThunk</font>]    <span class="codeComment">// dwThunk</span>            mov [ecx],eax  <span class="codeComment">// correction the thunk</span>            <span class="codeComment">// dwThunk =&gt; next dwThunk</span>            add dword ptr [ebp+<font color="#ff0000">_p_dwThunk</font>], <font color="#0000ff">004h</font>            <span class="codeComment">// dwHintName =&gt; next dwHintName</span>            add dword ptr [ebp+<font color="#ff0000">_p_dwHintName</font>],<font color="#0000ff">004h</font>        jmp _it_fixup_get_proc_address_loop_it_fixup_next_module:        add ebx,014h      <span class="codeComment">// sizeof(IMAGE_IMPORT_DESCRIPTOR)</span>    jmp _it_fixup_get_lib_address_loop_it_fixup_end:    ...</font></font></font></font></pre>
<pre>
<h3>7 Support DLL and OCX</h3>

Now, you intend to include the <a href="http://en.wikipedia.org/wiki/Microsoft_Dynamic_Link_Library" target="new">dynamic link library (DLL)</a> and <a href="http://en.wikipedia.org/wiki/OCX" target="new">OLE-ActiveX Control</a> in your PE builder project. Supporting them is very easy if you pay attention to the two-time arrival into the Offset of Entry Point, the relocation table implementation, and the client import table.
<h4>PE Maker: Step 4</h4>

&nbsp;

<a name="more"><font color="#000000"> </font></a><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/loadlibrary.asp" target="new"><tt>LoadLibrary()</tt></a>, or an OCX is registered by using <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/loadlibrary.asp" target="new"><tt>LoadLibrary()</tt></a> and <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocaddress.asp" target="new"><tt>GetProcAddress()</tt></a> through calling <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/4442206b-b2ad-47d7-8add-18002c44c5a2.asp" target="new"><tt>DllRegisterServer()</tt></a>, the first of the OEP arrival is done.

&nbsp;
<pre>hinstDLL = LoadLibrary( &quot;test1.dll&quot; );hinstOCX = LoadLibrary( &quot;test1.ocx&quot; );_DllRegisterServer = GetProcAddress( hinstOCX,                                     &quot;DllRegisterServer&quot; );_DllRegisterServer();    <span class="codeComment">// ocx register</span></pre>
</p>
<p>Download the pemaker4.zip source files from the end of the article.</p>
<h4>7.1 Twice OEP approach</h4>
<p>The Offset of Entry Point of a DLL file or an OCX file is touched by the main program atleast twice:</p>
<ul>
<li><strong>Constructor</strong>: When a DLL is loaded by </li>
<li><strong>Destructor</strong>: When the main program frees the library usage by <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/freelibrary.asp" target="new"><tt>FreeLibrary()</tt></a>, the second OEP arrival happens.
<p>&nbsp;</p>
<pre>FreeLibrary( hinstDLL );FreeLibrary( hinstOCX );</pre>
</li>
</ul>
<p>To perform this, I have employed a trick that causes in the second time again, the instruction pointer (EIP) traveling towards the original OEP by the structured exception handler.</p>
<pre><font color="#808080"><font color="#000000">_main_0:    pushad    <span class="codeComment">// save the registers context in stack</span>    call _main_1_main_1:    pop ebp    sub ebp,offset _main_1    <span class="codeComment">// get base ebp</span>    <span class="codeComment">//---------------- support dll, ocx  -----------------</span>_support_dll_0:</font>    jmp _support_dll_1        <span class="codeComment">// <font color="#ff0000">nop; nop;    // &lt;&lt; trick</font></span>                              <span class="codeComment">// in the second time OEP</span>    <font color="#000000">jmp _support_dll_2</font>_support_dll_1:    <span class="codeComment">//----------------------------------------------------</span>    ...    <span class="codeComment">//---------------- support dll, ocx  1 ---------------</span>    mov edi,[ebp+_p_dwImageBase]    add edi,[edi+03Ch]            <span class="codeComment">// edi -&gt; IMAGE_NT_HEADERS</span>    mov ax,word ptr [edi+016h]    <span class="codeComment">// edi -&gt; image_nt_headers-&gt;</span>                                  <span class="codeComment">// FileHeader.Characteristics</span>    test ax,<font color="#008000">IMAGE_FILE_DLL</font>    jz _support_dll_2        mov ax, <font color="#ff0000">9090h <span class="codeComment">// &lt;&lt; trick</span>        mov word ptr [ebp+_support_dll_0],ax</font></font><font color="#000000">_support_dll_2:    <span class="codeComment">//----------------------------------------------------</span>    ...    into OEP by SEH ...</font></pre>
<p>I hope you caught the trick in the preceding code, but this is not all of it. You have a problem in <tt>ImageBase</tt>, when the library has been loaded in different image bases by the main program. You should write some code to find the real image base and store it to use forward.</p>
<pre><font color="#808080">    mov eax,<font color="#008000">[esp+24h]</font>    <span class="codeComment">// the real imagebase</span>    mov ebx,<font color="#008000">[esp+30h]</font>    <span class="codeComment">// oep</span>    cmp eax,ebx    ja _no_dll_pe_file_0        cmp word ptr [eax],IMAGE_DOS_SIGNATURE        jne _no_dll_pe_file_0            mov [ebp+_p_dwImageBase],eax_no_dll_pe_file_0:</font></pre>
<p>This code finds the real image base by investigating the stack information. By using the real image base and the formal image base, you should correct all memory calls inside the image program!! Don't be afraid; it will be done simply by the relocating the table information.</p>
<h4>7.2 Implement relocation table</h4>
<p>To understand the relocation table better, you can take a look at Section 6.6 of the <a href="http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx" target="new">Microsoft Portable Executable and Common Object File Format Specification</a> document. The relocation table contains many packages to relocate the information related to the virtual address inside the virtual memory image. Each package is comprised of an 8-byte header to exhibit the base virtual address and the number of data, demonstrated by the <tt>IMAGE_BASE_RELOCATION</tt> data structure.</p>
<pre><span class="codeKeyword">typedef</span> <span class="codeKeyword">struct</span> _IMAGE_BASE_RELOCATION {   DWORD   VirtualAddress;   DWORD   SizeOfBlock;} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;</pre>
<h4>Table 7 - The Relocation Table</h4>
<p>
<table cellspacing="0" cellpadding="0" border="1">
<tbody>
<tr>
<td align="center" rowspan="7">Block[1]</td>
<td align="center" colspan="4">VirtualAddress</td>
</tr>
<tr>
<td align="center" colspan="4">SizeOfBlock</td>
</tr>
<tr>
<td align="center">type:4</td>
<td align="center">offset:12</td>
<td align="center">type:4</td>
<td align="center">offset:12</td>
</tr>
<tr>
<td align="center">type:4</td>
<td align="center">offset:12</td>
<td align="center">type:4</td>
<td align="center">offset:12</td>
</tr>
<tr>
<td align="center">type:4</td>
<td align="center">offset:12</td>
<td align="center">type:4</td>
<td align="center">offset:12</td>
</tr>
<tr>
<td align="center">...</td>
<td align="center">...</td>
<td align="center">...</td>
<td align="center">...</td>
</tr>
<tr>
<td align="center">type:4</td>
<td align="center">offset:12</td>
<td align="center">00</td>
<td align="center">00</td>
</tr>
<tr>
<td align="center" rowspan="7">Block[2]</td>
<td align="center" colspan="4">VirtualAddress</td>
</tr>
<tr>
<td align="center" colspan="4">SizeOfBlock</td>
</tr>
<tr>
<td align="center">type:4</td>
<td align="center">offset:12</td>
<td align="center">type:4</td>
<td align="center">offset:12</td>
</tr>
<tr>
<td align="center">type:4</td>
<td align="center">offset:12</td>
<td align="center">type:4</td>
<td align="center">offset:12</td>
</tr>
<tr>
<td align="center">type:4</td>
<td align="center">offset:12</td>
<td align="center">type:4</td>
<td align="center">offset:12</td>
</tr>
<tr>
<td align="center">...</td>
<td align="center">...</td>
<td align="center">...</td>
<td align="center">...</td>
</tr>
<tr>
<td align="center">type:4</td>
<td align="center">offset:12</td>
<td align="center">00</td>
<td align="center">00</td>
</tr>
<tr>
<td align="center">...</td>
<td align="center" colspan="4">
<p>&nbsp;</p>
<p>... </p>
<p>&nbsp;</p>
</td>
</tr>
<tr>
<td align="center" rowspan="7">Block[n]</td>
<td align="center" colspan="4">VirtualAddress</td>
</tr>
<tr>
<td align="center" colspan="4">SizeOfBlock</td>
</tr>
<tr>
<td align="center">type:4</td>
<td align="center">offset:12</td>
<td align="center">type:4</td>
<td align="center">offset:12</td>
</tr>
<tr>
<td align="center">type:4</td>
<td align="center">offset:12</td>
<td align="center">type:4</td>
<td align="center">offset:12</td>
</tr>
<tr>
<td align="center">type:4</td>
<td align="center">offset:12</td>
<td align="center">type:4</td>
<td align="center">offset:12</td>
</tr>
<tr>
<td align="center">...</td>
<td align="center">...</td>
<td align="center">...</td>
<td align="center">...</td>
</tr>
<tr>
<td align="center">type:4</td>
<td align="center">offset:12</td>
<td align="center">00</td>
<td align="center">00</td>
</tr>
</tbody>
</table>
<p>Table 7 illustrates the main idea of the relocation table. Furthermore, you can upload a DLL or an OCX file in <a href="http://www.ollydbg.de/" target="new">OllyDbg</a> to observe the relocation table, the <em>&quot;.reloc&quot;</em> section through <em>Memory map window</em>. By the way, you find the position of the relocation table by using the following code in your project:</p>
<pre>DWORD dwVirtualAddress = image_nt_headers-&gt;  OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].  VirtualAddress;DWORD dwSize = image_nt_headers-&gt;  OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;</pre>
<p>By OllyDbg, you have the same as the following for the <em>&quot;.reloc&quot;</em> section, by using the Long Hex viewer mode. In this example, the base virtual address is <strong>0x1000</strong> and the size of the block is <strong>0x184</strong>.</p>
<pre>008E1000 : 00001000  00000184  30163000  30403028008E1010 : 30683054  308C3080  30AC309C  30D830CC008E1020 : 30E030DC  30E830E4  30F030EC  310030F4008E1030 : 3120310D  315F3150  31A431A0  31C031A8008E1040 : 31D031CC  31F431EC  31FC31F8  32043200008E1050 : 320C3208  32143210  324C322C  32583254008E1060 : 3260325C  32683264  3270326C  32B03274</pre>
<p>It relocates the data in the subsequent virtual addresses:</p>
<pre>0x1000 + 0x0000 = 0x10000x1000 + 0x0016 = 0x10160x1000 + 0x0028 = 0x10280x1000 + 0x0040 = 0x10400x1000 + 0x0054 = 0x1054...</pre>
<p>Each package performs the relocation by using consecutive 4 bytes form its internal information. The first byte refers to the type of relocation and the next three bytes are the offset that must be used with the base virtual address and the image base to correct the image information.</p>
<p>
<table cellspacing="0" cellpadding="0" border="1">
<tbody>
<tr>
<td align="center" width="30">type</td>
<td align="center" colspan="3">offset</td>
</tr>
<tr>
<td align="center"><font color="#0000ff">03</font></td>
<td align="center"><font color="#0000ff">00</font></td>
<td align="center"><font color="#0000ff">00</font></td>
<td align="center"><font color="#0000ff">00</font></td>
</tr>
</tbody>
</table>
<h4>What is the type?</h4>
<p>The type can be one of the following values:</p>
<ul>
<li><tt>IMAGE_REL_BASED_ABSOLUTE (0)</tt>: No effect </li>
<li><tt>IMAGE_REL_BASED_HIGH (1)</tt>: Relocate by the high 16 bytes of the base virtual address and the offset </li>
<li><tt>IMAGE_REL_BASED_LOW (2)</tt>: Relocate by the low 16 bytes of the base virtual address and the offset </li>
<li><tt>IMAGE_REL_BASED_HIGHLOW (3)</tt>: Relocate by the base virtual address and the offset </li>
</ul>
<h4>What is done in the relocation?</h4>
<p>By relocation, some values inside the virtual memory are corrected according to the current image base by the <em>&quot;.reloc&quot;</em> section packages.</p>
<p>
<table cellspacing="0" cellpadding="0" border="1">
<tbody>
<tr>
<td align="center"><strong>delta_ImageBase = current_ImageBase - image_nt_headers-&gt;OptionalHeader.ImageBase</strong></td>
</tr>
</tbody>
</table>
<pre>mem[ current_ImageBase + 0x1000 ] =   mem[ current_ImageBase + 0x1000 ] + delta_ImageBase ;mem[ current_ImageBase + 0x1016 ] =   mem[ current_ImageBase + 0x1016 ] + delta_ImageBase ;mem[ current_ImageBase + 0x1028 ] =   mem[ current_ImageBase + 0x1028 ] + delta_ImageBase ;mem[ current_ImageBase + 0x1040 ] =   mem[ current_ImageBase + 0x1040 ] + delta_ImageBase ;mem[ current_ImageBase + 0x1054 ] =  mem[ current_ImageBase + 0x1054 ] + delta_ImageBase ;...</pre>
<p>I have employed the following code from Morphine packer to implement the relocation.</p>
<pre><font color="#808080">    ..._reloc_fixup:    mov eax,[ebp+_p_dwImageBase]    mov edx,eax    mov ebx,eax    add ebx,[ebx+3Ch]    <span class="codeComment">// edi -&gt; IMAGE_NT_HEADERS</span>    <span class="codeComment">// edx -&gt;image_nt_headers-&gt;OptionalHeader.ImageBase</span>    mov ebx,[ebx+034h]    <font color="#ff0000">sub edx,ebx <span class="codeComment">// edx -&gt; reloc_correction    // delta_ImageBase</span>    je _reloc_fixup_end    mov ebx,[ebp+_p_dwRelocationVirtualAddress]    test ebx,ebx    jz _reloc_fixup_end    add ebx,eax_reloc_fixup_block:    mov eax,[ebx+004h]          <span class="codeComment">//ImageBaseRelocation.SizeOfBlock</span>    test eax,eax    jz _reloc_fixup_end    lea ecx,[eax-008h]    shr ecx,001h    lea edi,[ebx+008h]_reloc_fixup_do_entry:        movzx eax,word ptr [edi]<span class="codeComment">//Entry</span>        push edx        mov edx,eax        shr eax,00Ch            <span class="codeComment">//Type = Entry &gt;&gt; 12</span>        mov esi,[ebp+_p_dwImageBase]<span class="codeComment">//ImageBase</span>        and dx,00FFFh        add esi,[ebx]        add esi,edx        pop edx_reloc_fixup_HIGH:              <span class="codeComment">// IMAGE_REL_BASED_HIGH</span>        dec eax        jnz _reloc_fixup_LOW            mov eax,edx            shr eax,010h        <span class="codeComment">//HIWORD(Delta)</span>            jmp _reloc_fixup_LOW_fixup_reloc_fixup_LOW:               <span class="codeComment">// IMAGE_REL_BASED_LOW</span>            dec eax        jnz _reloc_fixup_HIGHLOW        movzx eax,dx            <span class="codeComment">//LOWORD(Delta)</span>_reloc_fixup_LOW_fixup:            <font color="#ff0000">add word ptr [esi],ax<span class="codeComment">// mem[x] = mem[x] + delta_ImageBase</span>        jmp _reloc_fixup_next_entry_reloc_fixup_HIGHLOW:           <span class="codeComment">// IMAGE_REL_BASED_HIGHLOW</span>            dec eax        jnz _reloc_fixup_next_entry        <font color="#ff0000">add [esi],edx           <span class="codeComment">// mem[x] = mem[x] + delta_ImageBase</span>_reloc_fixup_next_entry:        inc edi        inc edi                 <span class="codeComment">//Entry++</span>        loop _reloc_fixup_do_entry_reloc_fixup_next_base:    add ebx,[ebx+004h]    jmp _reloc_fixup_block_reloc_fixup_end:    ...</font></font></font></font></pre>
<h4>7.3 Build a special import table</h4>
<p>To support the <a href="http://en.wikipedia.org/wiki/OCX" target="new">OLE-ActiveX Control</a> registration, you should present an appropriate import table to your target OCX and DLL file. Therefore, I have established an import table by the following string:</p>
<pre><span class="codeKeyword">const</span> <span class="codeKeyword">char</span> *sz_IT_OCX_strings[]={   &quot;Kernel32.dll&quot;,   &quot;LoadLibraryA&quot;,   &quot;GetProcAddress&quot;,   &quot;GetModuleHandleA&quot;,   0,   &quot;User32.dll&quot;,   &quot;GetKeyboardType&quot;,   &quot;WindowFromPoint&quot;,   0,   &quot;AdvApi32.dll&quot;,   &quot;RegQueryValueExA&quot;,   &quot;RegSetValueExA&quot;,   &quot;StartServiceA&quot;,   0,   &quot;Oleaut32.dll&quot;,   &quot;SysFreeString&quot;,   &quot;CreateErrorInfo&quot;,   &quot;SafeArrayPtrOfIndex&quot;,   0,   &quot;Gdi32.dll&quot;,   &quot;UnrealizeObject&quot;,   0,   &quot;Ole32.dll&quot;,   &quot;CreateStreamOnHGlobal&quot;,   &quot;IsEqualGUID&quot;,   0,   &quot;ComCtl32.dll&quot;,   &quot;ImageList_SetIconSize&quot;,   0,   0,};</pre>
<p>Without these API functions, the library can not be loaded, and moreover the <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/4442206b-b2ad-47d7-8add-18002c44c5a2.asp" target="new"><tt>DllregisterServer()</tt></a> and <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/b71137a7-284e-4521-a3b2-9dad9c9d3c54.asp" target="new"><tt>DllUregisterServer()</tt></a> will not operate. In <tt>CPECryptor::CryptFile</tt>, I have distinguished between EXE files and DLL files in the initialization of the new import table object during creation:</p>
<pre><span class="codeKeyword">if</span>(( image_nt_headers-&gt;FileHeader.Characteristics             &amp; IMAGE_FILE_DLL ) == IMAGE_FILE_DLL ){    ImportTableMaker = <span class="codeKeyword">new</span> CITMaker( IMPORT_TABLE_OCX );}<span class="codeKeyword">else</span>{    ImportTableMaker = <span class="codeKeyword">new</span> CITMaker( IMPORT_TABLE_EXE );}</pre>
<p>&nbsp;</p>
<h3>8 Preserve the Thread Local Storage</h3>
<p>By using Thread Local Storage (TLS), a program is able to execute a multithreaded process, This performance mostly is used by <a href="http://www.borland.com/" target="new">Borland</a> linkers: <a href="http://www.borland.com/us/products/delphi/index.html" target="new">Delphi</a> and <a href="http://www.borland.com/us/products/cbuilder/index.html" target="new">C++ Builder</a>. When you pack a PE file, you should take care to keep the TLS clean; otherwise, your packer will not support Borland Delphi and C++ Builder linked EXE files. To comprehend TLS, I refer you to Section 6.7 of the <a href="http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx" target="new">Microsoft Portable Executable and Common Object File Format Specification</a> document. You can observe the TLS structure by <tt>IMAGE_TLS_DIRECTORY32</tt> in <em>winnt.h</em>.</p>
<pre><span class="codeKeyword">typedef</span> <span class="codeKeyword">struct</span> _IMAGE_TLS_DIRECTORY32 {   DWORD   StartAddressOfRawData;   DWORD   EndAddressOfRawData;   DWORD   AddressOfIndex;   DWORD   AddressOfCallBacks;   DWORD   SizeOfZeroFill;   DWORD   Characteristics;} IMAGE_TLS_DIRECTORY32, * PIMAGE_TLS_DIRECTORY32;</pre>
<p>    <a name="more"><font color="#000000"> </font></a><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/dialogboxes/dialogboxreference/dialogboxfunctions/messagebox.asp" target="new"><tt>MessageBox()</tt></a> from <em>user32.dll</em>.</p>
<p>To keep the TLS directory safe, I have copied it in a special place inside the loader:</p>
<pre><font color="#808080">..._tls_dwStartAddressOfRawData:   dword_type(0xCCCCCCCC)_tls_dwEndAddressOfRawData:     dword_type(0xCCCCCCCC)_tls_dwAddressOfIndex:          dword_type(0xCCCCCCCC)_tls_dwAddressOfCallBacks:      dword_type(0xCCCCCCCC)_tls_dwSizeOfZeroFill:          dword_type(0xCCCCCCCC)_tls_dwCharacteristics:         dword_type(0xCCCCCCCC)...</font></pre>
<p>It is necessary to correct the TLS directory entry in the Optional Header:</p>
<pre><span class="codeKeyword">if</span>(image_nt_headers-&gt;   OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].   VirtualAddress!=0){   memcpy(&amp;pDataTable-&gt;image_tls_directory,          image_tls_directory,          <span class="codeKeyword">sizeof</span>(IMAGE_TLS_DIRECTORY32));   dwOffset=DWORD(pData1)-DWORD(pNewSection);   dwOffset+=<span class="codeKeyword">sizeof</span>(t_DATA_1)-<span class="codeKeyword">sizeof</span>(IMAGE_TLS_DIRECTORY32);   image_nt_headers-&gt;      OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].      VirtualAddress=dwVirtualAddress + dwOffset;}</pre>
<h3>9 Inject Your Code</h3>
<p>You are ready to place your code inside the new section. Your code is a &quot;Hello World!&quot; message by </p>
<pre><font color="#808080">...push MB_OK | MB_ICONINFORMATIONlea eax,[ebp+_p_szCaption]push eaxlea eax,[ebp+_p_szText]push eaxpush <span class="codeKeyword">NULL</span>call _jmp_MessageBox<span class="codeComment">// MessageBox(NULL, szText, szCaption, MB_OK | MB_ICONINFORMATION) ;</span>...</font></pre>
<h4>PE Maker: Step 5</h4>
<p>Download the pemaker5.zip source files from the end of the article.</p>
<p><img height="119" src="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=HELLOWORLD_GIF&amp;ds=20060302" width="146" alt="" /></p>
<h3>10 Conclusion</h3>
<p>By reading this article, you have perceived how easily you can inject code to a portable executable file. You can complete the code by using the source of other packers, create a packer in the same way as <a href="http://yodap.sourceforge.net/" target="new">Yoda's Protector</a>, and make your packer undetectable by mixing up with <a href="http://www.hxdef.org/download.php" target="new" class="broken_link">Morphine</a> source code. I hope that you have enjoyed this brief discussion of one part of the reverse engineering field. See you again in the next discussion!</p>
<p>&nbsp;</p>
</pre>
<p>    </a><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/exception_pointers_str.asp" target="new"><tt>EXCEPTION_POINTERS</tt></a>, you have access to the pointer of <tt>ContextRecord</tt>. The <tt>ContextRecord</tt> has the <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/context_str.asp" target="new"><tt>CONTEXT</tt></a> data structure, as seen in Table 4. This is the thread context during the exception time. When you ignore the exception by <tt>EXCEPTION_CONTINUE_SEARCH (0)</tt>, the instruction pointer, as well as the context, will be set to <tt>ContextRecord</tt> to return to the previous condition. Therefore, if you change the <tt>Eip</tt> of the Win32 Thread Context to the Original Offset of Entry Point, it will come clearly into OEP.</a><a href="http://www.codeguru.com/dbfiles/get_image.php?id=11393&amp;lbl=SCREENSHOT_JPG&amp;ds=20060302" target="_blank">Full Size Image</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/330.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《越狱》第二季口语重点</title>
		<link>http://www.donevii.com/post/320.html</link>
		<comments>http://www.donevii.com/post/320.html#comments</comments>
		<pubDate>Sun, 08 Apr 2007 05:32:35 +0000</pubDate>
		<dc:creator>gavinkwoe</dc:creator>
				<category><![CDATA[doc]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[生活]]></category>
		<category><![CDATA[男人]]></category>
		<category><![CDATA[类]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=320</guid>
		<description><![CDATA[《越狱》第二季口语重点 &#60;PrisonBreak season2&#62;作者charlotte85请勿用于任何商业用途，转载请注明作者及出处。http://bbs.prisonbreak.cn/viewthread.php?tid=7000&#38;extra=page%3D1&#38;page=1 第一集1.And he&#8217;s th... ]]></description>
			<content:encoded><![CDATA[<p>《越狱》第二季口语重点 &lt;PrisonBreak season2&gt;<br />作者charlotte85<br />请勿用于任何商业用途，转载请注明作者及出处。<br /><a title="http://bbs.prisonbreak.cn/viewthread.php?tid=7000&amp;extra=page%3D1&amp;page=1" href="http://bbs.prisonbreak.cn/viewthread.php?tid=7000&amp;extra=page%3D1&amp;page=1" target="_blank" class="broken_link">http://bbs.prisonbreak.cn/viewthread.php?tid=7000&amp;extra=page%3D1&amp;page=1</a></p>
<p>第一集<br />1.And he&#8217;s the mastermind of this whole thing. 他是整个事情的主谋<br />mastermind＝策划者,主谋<br />2.he acknowledge that whatever neuroses drove the criminal to commit the original crime is compounded.他知道无论是什么神经机能病变导致的最初犯罪都是复杂的<br />commit the crime=犯罪<br />acknowledge =承认,知道<br />3.You&#8217;re not being very transparent,Warden. 你不是很坦率，狱长<br />transparent＝透明的 <br />4.But it&#8217;s going to make collaboration kind of hard. 不过这样合作起来就不那么容易了 <br />collaboration＝cooperation 协作,合作 <br />5.i&#8217;m the furthest thing from a threat.我根本没有威胁<br />这句话体现了老外说话的艺术性,非直来直去的表达自己的意思,譬如老外喜欢用&quot;is the ice cold?&quot; 来表达&quot;yes&quot;之意<br />6.why don&#8217;t you cut out all the riddles,snowflake,and just give us to a straight.你干嘛不把话说明点,小白脸.<br />riddle=谜题<br />straight除了&quot;直&quot;的意思外,也用于&quot;异性恋者&quot;,反义是homosexual同性恋者<br />7.the harder you struggle,the worse it gets你越挣扎,情况越糟<br />这是我们在中文里经常听到的<br />struggle=挣扎<br />8.Self-presevation is a strong motivator.自卫是很强的因素<br />self-presevation=self-protection 自卫<br />motivator=动机,因素<br />9.one thing you learn when you&#8217;re walking the steps is that you never outsource a blame that belons in your own backyard.当你经历这些,你学到的一件事就是你再不用寻求你所受到的责备<br />walk the steps=一步步地经历下来<br />10.you fell for her 你爱上了她<br />等于我们常见的you felling in love with her<br />11.Sir,I cannot do a procedure like this without an anesthetic. 先生，如果没有麻醉剂，我没法动这个手术 procedure＝手术 ；anesthetic＝麻醉药<br />12.i want you to turn youself in.我希望你去自首<br />这里的turn in 是&quot;自首&quot;的意思,若换成&quot;i want you to turn him in&quot;则turn in为&quot;告发&quot;的意思 </p>
<p>第二集<br />1.yeah,yuck it up,funny man.耶,尽情大笑吧,可笑的人<br />yuck up=开怀大笑<br />2.we&#8217;re headed out,man 我们出发了,伙计<br />3.That is absolutely hogwash. 简直一派胡言<br />Hogwash=猪食<br />4.how was scofield able to have exclusive access to you?为什么scofield能单独接触你?<br />exclusive=专门的,独家的 ; access to=接近&#8230;<br />5.This will be your last outburst,officer. 这将是你最后一次发飙了，长官<br />outburst=爆发,发飙<br />6.Is it true you sold the right to run prison industries to the highest bidder. 你将监狱工厂管理权卖给出价最高的人是不是真的？ <br />run=经营 eg. run a company 经营一家公司<br />highest bidder=最高价竞买人7.We&rsquo;ll call for you when we&rsquo;ve reached a decision. 等我们做好决定后会通知你们<br />reach a decision=作出决定 (注意reach的用法)8.your call.你决定吧<br />常用口语<br />9.This can go down humanely if you don&rsquo;t fight,but if you pull a stunt like that again,it&#8217;s going to get inhumane right quick. 你要不挣扎的话,那接下来我将会很仁慈，不过要是你想再耍花招，我就会变得很残忍<br />humanely=慈悲地 ；pull a stunt=耍花招 ；inhumane=残忍的<br />10.if you would have just told us in the beginning that this was going to be a railroad.如果你一开始就告诉我们这是个快速通过案<br />railroad在俗语中指&quot;议案快速通过&quot;,泛指&quot;铁路运输&quot;<br />11.But you need a fall guy,fine. 但是你们需要一个替罪羊<br />a fall guy=替罪羊;替身演员<br />12.he went out with his boots on.他死在工作岗位<br />翻译组的译文是&quot;他走得很平静&quot;,我觉得不确切.die with one&#8217;s boots on&rdquo;,源自美国西部,它有两 <br />层含义。一为死于工作岗位(&ldquo;die in harness&rdquo;)、一为殉职，尤指在战斗中或者为高尚的事业而 <br />献身。因为如果是病死或老死的情况下，一般是躺在床上等待死亡，不会穿着鞋子；如果是在枪战中死去，自然是穿着靴子的。而在英式英语里，通常把它说成&ldquo;die in one&#8217;s boots&rdquo;。 <br />13.i failed him.我让他失望了. </p>
<p>第三集<br />1.well,Hector says that you can serve your full sentence.嗯,hector说你要刑满才释放.<br />sentence=判决,宣判<br />serve the sentence=服刑<br />2.anything break on the other six.其他六人有什么进展?<br />break=突破,进展<br />3.Listen,you know I&#8217;m thankful for the help with the green card,but I just don&#8217;t want to get involved. 我很感激你帮我搞到绿卡但我不想卷入此事。<br />be involved in sth=卷入&#8230;事情中<br />4.those ass-hats are worth more dead than you and i are alives.那些混蛋就是死了也比我们值钱<br />ass-hats=混蛋<br />eg. ass hat inside 内心卑鄙的<br />5.i hope you&#8217;re holding on to something tight &#8217;cause i&#8217;m about to break it down for you.我希望你做好心理准备,因为我要说的东西会让你崩溃<br />holding on to something tight牢牢扶助什么东西<br />break down=崩溃 <br />6.you were attending when I first started here. 我刚来的时候你是主治医师。<br />attending=主治的<br />7.i want to alert you to a possible situation.我要提醒你可能发生的情况<br />alert sb=warn sb 警告某人<br />8.Give me one good reason why I shouldn&#8217;t turn you in right now. 给我个不告发你的理由。<br />turn in=告发;上缴;上床睡觉<br />9.we keep tapping on cracks,and she&#8217;s going to break.我们深入利用这个弱点,她就会崩溃<br />tap on=轻轻敲打 ; crack=裂缝<br />tap on cracks 敲打已有的裂缝,即深入利用弱点<br />10.humpty dumpty climbed up a wall,humpty dumpty had a great fall.胖墩爬上墙,胖墩摔下来<br />此句来源于一首童谣,humpty dumpty现在都用来称呼胖墩<br />11.How do you throw the hunter off the scent?Get rid of the prey.你怎么才能逃过猎人的鼻子? 扔掉猎物。<br />throw off=摆脱掉 scent=气味，嗅觉<br />12.your tags are expired.你的车牌过期了<br />expire=期满;死亡<br />13.provided the transport comes though.若果交通顺利的话<br />provied和provided that常用于数学属于中,为&quot;假设,假如&quot;的意思<br />14.You have the right to speak to an attorney before you speak to the police.Anything you say may be used against you in a court of law. 在你向警方供述之前，你有权去请律师,但是你所说的一切将成为呈堂证供</p>
<p>第四集<br />1.We&rsquo;ll drop you off in the next town,and I&rsquo;ll wire you that 10,000 like I said.我们让你在下个镇下车,我会给你汇10000美元<br />wire=汇款;诱饵<br />2.Don&rsquo;t even think about getting cute,smart-ass.And now,you and your brother are gonna take me right to where that money is,or the whore gets dead real fast.别耍花招，现在你和你哥带我们去藏钱的地方，不然这妓女会死的很快<br />cute=狡猾的;花招 ; whore=妓女<br />3.The dredging of the river under Scofield&rsquo;s apartment bore some fruit. 从Scofeld公寓下的 河里打捞出了些东西<br />dredging=捕捞 ; fruit=成果<br />4.to forge ahead with its nuclear program 继续核武器的计划<br />forge=锻造; ahead with sth=继续做&#8230;<br />5.he&#8217;s got a stateroom listed as a cargo hold on the manifest.他将头等舱伪造成装货物的仓库<br />stateroom=头等舱 ; cargo=货物 ; manifest=货单6.i travel light 我轻松旅行 <br />light做副词为&quot;轻轻地&quot;意思<br />7.and you&#8217;re just hoofing it out here in the middle of nowhere?你就在中途闲逛?<br />另外hang around也是&quot;闲逛&quot;的意思<br />8.I admire your optimism.She&rsquo;s rolling,man. 我很钦佩你的乐观，她在叛变<br />admire sb=羡慕某人;钦佩某人<br />rolling=转变,在此句中指&quot;叛变&quot;<br />9.not in a thousand years.想都别想<br />等于no way(没门),但比no way的拒绝程度更坚决<br />10.you think that tire went flat by accident?你以为车轮瘪了是个意外么?<br />flat=平的,扁的; 充气为inflate<br />by accident=偶然的,意外的<br />11.Don&#8217;t turn your back on us.别抛弃我们<br />turn one&#8217;s back on / upon=背弃..，抛弃..<br />eg.One should never turn his back on his home country. 一个人永远也不能背弃自己的祖国<br />12.my dogs are just barking. 我走得脚痛<br />此句是t-bag在被邀请搭个顺风车时说的,翻译组的翻译是&quot;正合我意&quot; . 原因是在美国的俚语中&quot;my dogs are just barking&quot;的意思是&quot;我的脚走得都痛了&quot;<br />13.When dad&rsquo;s back acts up,we stop. 当爸爸的背不舒服时我们就得停下来<br />act up=运作不正常 <br />14.Hit a sore spot,didnt I? 说到你痛处了，是不是？<br />sore spot=痛处,提起来就伤感情的话题<br />15.it&#8217;s over for good 永远结束了<br />for good=永远</p>
<p>第五集<br />1.I bought us some time-that&#8217;s what counts. 我争取到了时间，那才是最重要的。<br />count=有价值<br />2.What you call it?Double K Ranch.No.You from around here? Yeah,born and raise.你说哪里？双K农场。没听过。你是这里人吗？是的，土生土长。<br />Ranch=大农场<br />born and raise=土生土长<br />3.thanks for your time.谢谢你的配合<br />这是实用而简单的口语,当你耽误了别人时间时最好都说一声thanks for your time<br />4.every plot is mapped out with dimensions.每一小块都会用尺寸标注出<br />map with=标示 ; dimension=尺寸<br />5.Keep me posted. 和我保持联系<br />posted=消息灵通的<br />6.that&#8217;s my ego.是我自以为是了<br />ego=自负,自我主义<br />7.none of your beeswax.不关你事<br />大家常见的是&quot;none of your business&quot;,可用beeswax代替business<br />8.Do you happen to have a pen handy? 你手头有笔吗？ <br />handy=唾手可得的,手边的<br />9.they&#8217;re due west and we need to know why.他们都计划去西边,我们得知道为什么<br />due=计划的<br />10.that bitch treed herself and i brought her down in one shot.那个贱人困住了自己,我一枪射中<br />tree sb 口语中表示&quot;使某人陷入困境&quot;<br />11.i&#8217;ll ring it up.我来打价<br />超市里打价都是&quot;滴&quot;一声,ring up 由此得来<br />12.before i destroyed it,i committed it to my photographic memory.在我销毁它之前,我把它存入我的相机一样的记忆中了<br />commit=委托,托负<br />photographic =摄影般的<br />13.now let&#8217;s not dissolve into threats,all right.别化为恐吓好么?<br />14.Probably out of your price range. 恐怕你买不起</p>
<p>第六集<br />1.I want to don&#8217;t hear anything out of your mouth other than what yourphotograpic&#8230;map除了你说关于地图的事，其它事我都不要听<br />want to 在口语里读成wanna other than＝除了we&#8217;re pulling them now.我们在全力以赴<br />2.we&#8217;re going to get made out here.我们会被认出的<br />make out=辨认出<br />3.oh ,shut it　哦　闭嘴吧<br />4.我们一般多用shut up,shut it语气没shut up 强烈<br />something was in their way 有东西挡着它们<br />特口语的说法，本集里说的是仓库档着树的阳光，也可用于ＸＸ东西阻碍了什么什么的发展<br />5.if we hit the foundation,we stay<br />hit the foundation=触到地基<br />6.we got to do something and it&#8217;s not going to involve hurting anyone　我们要干点什么，但不能伤人<br />involve doing sth=包括&#8230;then gas up the car　给车加满油<br />7.can I hitch a ride?　我能搭个便车吗？<br />hitchhike=徒步搭过路车式的旅行<br />8.Fresh out of the academy 一毕业就开始了<br />9.If you&#8217;re telling me the road to him leads through Sara Tancredi ,by all means,pursue it.如果你认为抓到他必须利用到ST,那就用任何手段继续下去<br />这个词组蛮好用的，road to sb/sth leads through sb/sth是很形象的说法＝达到。。。必须通过。。。。<br />by all means＝用尽一切方法<br />10.The president has unwavering faith in you.总统对你很有信心<br />unwavering也是好的用法＝不动摇的，意志坚定的，可替代unchangeable<br />11.Now feel free to call your company<br />feel free to 请便<br />12.we&#8217;re ready to turn your juice back on 我们准备好去恢复你家的电力 <br />juice＝&lt;俚语&gt;电流<br />13.the niose might be substabtial噪音会很大<br />substabtial的意思很多，这里指&ldquo;相当的&rdquo;，除此之外，它还有&ldquo;实际的；重要的；真实的；坚固的&rdquo;等含义<br />14.What&#8217;s up,snowflake?<br />snowflake表面意是&ldquo;小雪花&rdquo;，引申义是白种高加索人不友好的称呼，可见C-NOTE对MS的不满<br />15.ask him if he would like have a drink with me after the punches out?问问他下班能和我喝一杯吗？<br />punch 有打孔的意思，punch out引申为&ldquo;打卡下班&rdquo; punch in则同理为&ldquo;打卡上班&rdquo;</p>
<p>第七集<br />1.Just go easy.放松点<br />2.Go nothing.别动<br />警察的惯用语是:Freeze! 即&quot;别动&quot;的意思<br />3.It was 1:00 PM when they tangled it up.他们在下午一点聚集在一起<br />tangle up 集中在一起<br />4.The guy id&#8217;d both of them 那个人认出了他们两<br />ID=identify,鉴别,识别,id card=身份证<br />5.your car&#8217;s empty.<br />car=超市里用的手推车<br />6.It&#8217;s time to get the hat.我们该去拿钱了<br />hat在这里不是&quot;帽子&quot;=非法所得的收入<br />7.We have already committed the crime.我们已经犯罪了<br />committe the crime犯罪<br />committe the suicide自杀<br />8.The hat&#8217;s over the wall.犯罪已成事实<br />9.There was a way we could wipe the slate clean.这样我们可以洗清冤屈<br />wipe the slate clean 是个再常用不过的词组,你会在很多电影和歌词中碰到,意思为&quot;勾销往事 洗清冤屈&quot;<br />slate=石板, 古人会把罪犯的名字刻在石板上<br />9.it looks like we&#8217;re back to square one.看来我们又回到起点了<br />10.They withdrew his nomination他们撤销了对他的提名<br />withdraw=撤销;撤退 nomination=提名<br />11.oh,hit me a nerve 哦,真吓人12.knock it off. 安静<br />13.whatever you got eating at you,you just give it up.无论什么事在折磨你,你就让它去吧(即别让这种内疚折磨你<br />14.Bodies kept stacking up.<br />stack up=不断堆积 body=尸首<br />15.The picture makes me look like a sociopath.照片上的我跟精神变态者似的<br />这里教一个猜单词词义的方法 sociopath: socio-为单词前缀=社会 -path为单词后缀=恨<br />所以sociopath可翻译成憎恨社会的,反社会的<br />16.Keep your head down.小心撞头,引申为&quot;小心行事&quot;<br />17.She found no signs of foul play.她没发现谋杀迹象<br />foul play原义为&quot;球场上的严重的恶意的犯规&quot;</p>
<p>第八集<br />1.The money was never yours to begin with．本来就不是你们的钱<br />to begin with=本来，原先<br />2.you are outnumbered and we will come after you.你人数少，我们会追上你的<br />　outnumber=数量上胜过<br />　come after 追上<br />3.i let that psychopath t-bag loose once.我让T-BAG那个变态逃掉一次<br />　psychopath＝精神变态者<br />　4. i didn&#8217;t mean to startle you. 我没想吓你。<br />　startle=使吃惊<br />5.in an apparent attempt to avoid jail time.有意逃避入狱<br />　avoid+n.／doing sth.<br />老外喜欢用名词＋time,表＂一段什么的日子＂<br />6.that stuff on that table is premium.桌子上放着保险费<br />　很多人说＂东西＂时喜欢用＂thing＂，其实stuff是最贴切的<br />premium ＝n.保险费　　　a.高价值的　<br />7.here is a list of options available to you.单子上提供的东西对你有用<br />　available在口语中是常用的词，譬如问别人有没有空＂are you available today?＂，或问座位有没有人占＂is the seat available?＂<br />8.Places to stay,business that are more open to hiring men out of the correctional system. 能住的地方，优　先聘用劳改犯的商家。<br />　 be open to=对&#8230;开放； correctional system＝引申为教改所<br />9.without the money,we are screwed　没有钱我们就完了<br />screw=螺丝钉，此处用被动，表示被牢牢定住了　<br />10.we ran into some car trouble 我们遇到车祸了<br />run into=遭遇，撞上<br />11.They&#8217;re ladies&#8217; clubs &#8212; I&#8217;m guessing they&#8217;re hotter than a monkey&#8217;s jock strap.那些小妞的酒吧，我猜她们比猴子的护裆还热<br />　　Jockstrap是指男用的护裆(打壁球容易被球反弹击中），大家都知道猴子的PP是红的嘛，所以monkey&#8217;s jock strap红热红热的。。<br />12.we got to lose the bike. 我们得扔掉这车。<br />throw,leave 用腻了，用用lose也不错<br />13.from a public relations standpoint,abruzzi and apolskia were by the book.从公众角度出发,（杀）abruzzi and apolskia是按规定的。<br />　　standpoint=立场，观点<br />　　by the book=按常规，按规矩<br />14.your brilliant plan to eliminate sara tancredi from the equation failed.你的伟大的铲除SARA的计划，失败得也如此&ldquo;伟大&rdquo;<br />　　一个brilliant一个和equation，把讽刺意味表露无疑<br />15.It&#8217;s a simple strategy,plays across the board. 很简单的策略，广为人知<br />16.Get some two-bit job? 找份廉价工打打？ <br />two-bit=二毛五分，即廉价的<br />17.and then when you strat running out of air&#8230;当你没气的时候<br />　在学校学的都是&ldquo;out of breath&rdquo;<br />18.i will chain you to this desk until i get some answers i cannot fertilize my lawn with<br />我就把你困在这儿，寻找答案，找到我不能再找为止　fertilize＝施肥　　lawn＝草坪<br />　这里用了个比喻，i cannot fertilize my lawn with原义&ldquo;直到我的草坪施肥到不能再施为止&rdquo;</p>
<p>第九集<br />1.I&#8217;ve been working.Uh,night shifts,cleanup and&#8230;Jimmy said I could change my shift　我一 <br />直在这儿工作，上的晚班，负责打扫，jimmy同意我换班<br />the night shift＝夜班；the day shift＝白班 ;three shifts＝三班倒<br />2.copy that.收到<br />　copy在口语中常用于＂收到／听到＂<br />eg. Do you copy?收到了吗？<br />　 Roger. 收到了<br />3.all the charges against you have been dropped,you&#8217;re free and clear to start a new life.<br />　你身上所有的指控都撤销了，你可以重新开始新的生活了<br />　drop在这里意为＂删去＂　　<br />　指控：charge somebody with<br />4.Not be constantly running,looking over your shoulder不用到处躲藏，小心翼翼地生活<br />constantly=不时的，频繁的<br />　looking over your shoulder小心翼翼，时刻警惕<br />5.was there any opprtunity to subdue him? 是否有机会制服他？<br />　subdue=打败，使顺从<br />6.But sometimes things happen that are just out of your control.但有时候事情的发展会超出你 <br />的控制（M叔叔深刻的教训啊～这句不错）<br />7.care to comment? 有啥想说的么？<br />　want to用腻了就用care to吧，同样是＂愿意，想要＂的意思<br />8.i believe i said no comment.我说过无可奉告了<br />　no comment＝无可奉告<br />9.God help the who goes behind my back and talks to the press.上帝保佑那个背着我向媒体通风报信的家伙（别被我抓到）<br />　go behind sb&#8217;s back=背着某人<br />　 press=新闻界，媒体<br />10.the only way to win a war is to try to konw your prey completely.知己知彼，百战不殆<br />　 prey=对手<br />11.everything&#8217;s arranged.一切就绪<br />　everything&#8217;s arranged＝everything&#8217;s ready<br />12.let&#8217;s roll out.我们出发吧<br />　 let&#8217;s roll out=let&#8217;s go<br />13.We don&#8217;t have to ditch the car. 我们不必丢弃这辆车。<br />ditch=放弃；挖沟<br />14.It&#8217;s a one-shot deal out of the country. 这是离开这个国家的惟一的机会。<br />　　shot=射击；one-shot=一射即出的，即＂只有一次的＂<br />15.i just figured that since we were divorced&#8230;我只是发现自从我们结婚后．．．<br />　　figure和figure out 在口语中非常常用，为＂发现，觉得＂的意思<br />16.the bureau take its toll on your family.当局给你家带来了损害<br />　　bureau=局<br />　　toll=损失，代价<br />17.can you guarantee me that my family ain&#8217;t going to get hurt?你保证我家人不会受伤？<br />这里说说promise和guarantee的区别：两者都为＂保证，确保＂，但promise的＂保证＂比　　　　<br />guarantee要弱很多．<br />　　eg. i promise that i&#8217;m on your side.我尽量保证支持你（即如果事情有变我可以背叛你）<br />　　　　i guarantee that i&#8217;m on your side.我誓死保证支持你<br />18.nobody&#8217;s punking out没人退出<br />punking out ＝退出<br />　 这里再教大家一个新用法－－punkd=被耍了<br />　　i&#8217;m punkd 即＂我被耍了＂<br />19.he&#8217;s a closed book.他很自我保护　　<br />20.All you have to do is wait by the merry-go-round. 你要做的就是等在旋转木马旁<br />merry-go-round=旋转木马<br />21.Alex was consumed with finding him.Alex费尽气力去找他<br />22.you&#8217;re slipping.你错了<br />　 slipping=wrong<br />23.two caucasian males on foot ,fleeing the willcox station.两个白种男人徒步从willcox火车站逃逸<br />　　（这里可以看出警察的训练有素，短短一句话就把细节都说明了）<br />　　caucasian＝高加索人的，白种人的<br />flee=逃走</p>
<p>第十集<br />1.he ain&#8217;t coming off the goods.他什么都不说<br />　come off就是二个原来在一起的东西分开的意思<br />2.i&#8217;m on my way and I need your talents,on the ground as well. 我正在赶去，我需要你的帮助<br />on the ground=从基础开始<br />　另外与之相对的hit the ceiling的意思的＂暴跳如雷＂<br />3.You wanted me to figure out Scofield&#8217;s rendezvous with Tancredi? 你想我找出Scofield和Tancredi的　　　　　　　会面地点么？<br />　rendezvous=集合点<br />4.I&#8217;m sitting right on top of it. 我就快得手了<br />on top of=了解知道，熟练掌握<br />5.i could drop you back off with the crops if you&#8217;d prefer.若你喜欢我可以把你们再还给警察<br />　drop&#8230; back off=退还给<br />6.she&#8217;s picking me uo in a few hours.她一会来接我<br />　pick up 是常用口语，意为＂接某人上车＂，或＂搭便车＂<br />7.Running away into the sunset with the man who lied to me? 和一个骗我的男人一起逃亡？ <br />sunset=日落；晚年（这里两种意思都有吧＾＾）<br />8.he&#8217;s not gonna call for backup.他不会叫后援的<br />　back up=后援，增援<br />9.i don&#8217;t wanna get trapped in here.我不想被困在这里<br />　trap＝陷阱　　　　　　　　　be trapped in=被困住<br />10.you are somebody.你是个大人物<br />　同样的，i&#8217;m nobody意思就是＂我是个小人物＂<br />11.you&#8217;re on the wrong side.你站错了立场<br />　on sb&#8217;s side 站在某人一边<br />　eg.i&#8217;m on your side.我站在你这边，我支持你<br />12.This is a monumental moment for both of us. 这是我们的重要时刻<br />　 monumental=纪念碑的，即不朽的<br />13.i&#8217;m not kidding around.我没有开玩笑<br />　 i&#8217;m not kidding太常用啦<br />14.you named him after yourself.他跟你姓<br />　 name A after B＝A以B命名<br />15.Well,thanks for bailing as out. 谢谢你把我们弄出来 <br />　bail=保释<br />16.Down by the border. 南部的边境 <br />up by the border. 北部的边境</p>
<p>第十一集<br />1.this is the tribune police.make yourself known.我们是警察,请表明身份<br />tribune=保护百姓的官<br />make yourself known=表明身份<br />2.cops found your girlfriend fish-belly white,gargling her own puke.警察发现你女朋友不省人 事,口吐 白沫<br />fish-belly=鱼腹;fish-belly white=鱼翻白肚,即生命岌岌可危<br />gargle=漱口 ; puke=呕吐物 <br />gargling her own puke口吐白沫(若换成字面意思挺恶心*_*)<br />3.bring her down 将她打垮了<br />这里再说另一个常用的词组let sb down,即&quot;使某人失望<br />4.the analyst got his hands on a phone conversation.分析员得到一通电话交谈<br />get a hand on sth=得到&#8230;<br />5.And judging by how hard they&#8217;re going after sara tancredi,i&#8217;m pretty sure they think she has it.以他们追捕sara的力度看,我很确定她有(带子)<br />judge by=以&#8230;为判断 (因为这里的主语为I,所以用judge的动名词)<br />go after=追逐;追求<br />在动词前加上pretty,加深程度<br />6.But i hope his death properly illustrates the magnitude of the situation that we&#8217;re in right now. 但我希望他的死完全说明了我们的麻烦，已经很严重了。<br />properly=适当地，完全地； illustrate=举例说明,阐明； magnitude=大小<br />7.are you aware of the nature of your sins?你知道你犯的罪的性质么?<br />be aware of=知道,了解<br />nature=(神学中)性质,种类<br />sin=罪,其实sin和一般的罪不一样,它一般指人的原罪Original sin,如大家所熟悉的&quot;七宗罪&quot;(七宗 <br />罪即:Gluttony 暴食 Greed 贪婪 Sloth 懒惰 Pride 自负 Lust 淫欲 Envy 嫉妒 Warth 愤怒) <br />8.What are those ends? 这些的目的是什么？<br />9.surrender your will to god.屈服于上帝<br />surrender=投降 ; wil=意愿<br />10.I don&#8217;t like being out in the field,I only do so when there&#8217;s been a screw up. 我不喜欢抛头露面,我只在事情办砸的时候才出来<br />screw up=事情办砸 eg.sorry,i screw it up 对不起,我把事情搞砸了<br />11.you have my word.我保证<br />实用口语12.Yeah,but i mean it. 是的但是我是认真的<br />实用口语<br />13.Do you think i&#8217;m just withholding information because i like hanging out with you.你以为我隐瞒消息是因为喜欢和你待一起么?<br />withhold=保留,隐瞒<br />hang out with sb=与某人待在一起<br />14.Don&#8217;t try to float a babe-in-the-woods routine by me. 别想耍我把我当成不懂事的小孩<br />babe-in-the-wood(s)=涉世未深的人,幼稚盲从的人,无经验而易受骗的人<br />15.It&#8217;s really going to piss me off.这可真会把我惹火<br />piss off=滚开<br />16.I already named my price. 我已经开价了<br />注意name的用法<br />17.you&#8217;d better get down on your knees and pray to god that i don&#8217;t find you.你最好跪下祈祷我不会找到你<br />get down on your knees=双膝跪下18.kiss my ass,cobarde.求我吧,懦夫<br />kiss sb&#8217;s ass求某人,讨好某人<br />相反,kick sb&#8217;s ass的意思为&quot;揍某人一顿&quot;</p>
<p>第十二集<br />1.They put me with this foster father down on pershing avenue.他们让我和住在pershing大街的养父一起生活.<br />foster-father=养父. 另外step-father=继父<br />avenue=林荫道,大街<br />2.Apparently,you were some kind of analyst.That&#8217;s the job you chose over your family. 显然你是个分析家，你就为了那工作不要家了。<br />3.Michael,turning on the company put me and you at even greater risk.Michael,跟公司作对会让你们和我冒更大的危险<br />我们常见的turn on是指&quot;打开,拧开&quot;,在此处trun on (sb)指&quot;攻击&quot;<br />eg.Why are you all turning on me ? 你们为什么都冲我来了?<br />另外,turn sb on=使某人激动或兴奋<br />4.You must be relieved that it&#8217;s over. 这事结束了你就解脱了<br />relieve=放心,解脱<br />5.we don&#8217;t get a whole bunch of homicides out here,and,well,we&#8217;re trying to play catch-up.我们还没抓到那帮逃犯,我们正努力呢<br />a bunch of=一堆,一群 ; homicide=杀人犯 <br />6.we can each sniff out a perp like a hot fart.我们能查觉谁是罪犯,就像闻臭屁一样<br />sniff out=闻到;查觉到 ; fart=[俗语]屁<br />perp=罪犯,为perpetrator的缩略<br />7.I&#8217;d be indebted. 我很感激<br />indebted=感恩的;负债的<br />8.I&#8217;ll do whatever i can to help you nail that son of bitch.我会尽我所能去帮你们抓住那个狗娘养的<br />nail=指甲;钉住;[俚语]抓住 (在此句中表&quot;抓住&quot;)<br />9.He got me clean through.他打穿我的身体了<br />clean=整个地. eg.The bullet went clean through his shoulder. 子弹整个儿穿过了他的肩膀<br />10.it&#8217;s a backup.这是后备的<br />backup=后援;替代的<br />而词组back up=支持;倒退<br />11.Geary and me had a little dustup over how to go about finding bagwell.Geary和我在对于怎么寻找bagwell的问题上出现了纠纷<br />dustup=纠纷,争执<br />12.All we need to do is find a pharmacy. 我们要找的就是个药店<br />pharmacy=药房，制药业<br />13.I&#8217;ll make sure that everybody involved knows that your help was invaluable. 我保证每个有关人员都知道你的帮助是无价的<br />invaluable=无价的<br />in-和un-都是表&quot;不&quot;的前缀,但invaluable是指&quot;无价的,珍贵的&quot;,unvalued才是指&quot;无价值的,没用的&quot;<br />14.And i want to cut a deal first.我想先做个交易<br />cut a deal 并不是破坏一个交易。相反地，to cut a deal就是在做生意方面,或者是在司法方面和对方 达成一个协议<br />15.A little incentive,and i want it in writing. 以防万一，我要书面承诺。<br />16.When we found the money,Geary double-crossed me. 当我们找到钱时,Geary出卖了我<br />double-crossed=欺骗，出卖<br />17.Now,at this juncture,thing will go a whole lot easier for you if you admit to the crime.事情到这份上，你还是早早认罪的好<br />at this juncture=在这个当口上，在这个节骨眼上<br />18.Bagwell set me up.bagwell陷害我<br />set up是一个常用的词组，用法很灵活,有&quot;竖起;排版;创立;张贴;树立(榜样);装置、安放&#8230;.&quot;一堆意思</p>
<p>第十三集<br />1.Until we verify,you will drop your weapon or we will drop you.在我们核实之前,放下武器,不然我们就放 倒你<br />2.There men are in my custody. 我抓住了两个逃犯<br />in custody=被拘留<br />3.I was wondering if you could help a brother out.我想问问你能否帮兄弟我一个忙.<br />我们都知道help sb是&quot;帮助某人&quot;,help sb out 即&quot;帮助解决难题,帮助摆脱困境,救出 &quot;<br />4.Remain at large. 仍逃亡在外<br />at large=未被捕<br />5.How a guy goes about getting a hold of one of those prosthetic jobbies. 一个人怎么才能得到假肢?<br />get hold of=得到 ; prosthetic=[医]修补学,装补学 <br />6.He just neglected to tuck in the sheets. 他(医生)只是忽略我了<br />这里说一下neglect,overlook, ignore的区别,虽然三个单词都表&quot;忽视,忽略&quot;的意思,但neglect指因粗心或遗 忘而没有事,ignore指有意识地拒绝、故意不予理会；overlook指由于草率或没有注意到而忽视某事。<br />在搭配上, neglect除了可接sb.或sth.之外,还可接to do sth或doing sth作其宾语，而ignore 后面只可接sb. 或sth.不可接不定式。<br />7.You sure as hell can figure out how to get a prosthetic for that stump of yours by yourself. 你自然能给自己搞个假肢 <br />as hell=表示强调，意为&ldquo;非常&rdquo; <br />hell 在口语中使用频率很高，经常见到的由hell构成的词组还有：<br />1)a / one hell of 表示强调，意思为&ldquo;极好的/极糟的&rdquo;。<br />e.g. Forrest Gump is a hell of a good soldier. 阿甘是一个绝对出色的士兵<br />2)go to hell 去你的，见鬼去吧<br />3)feel / look like hell (感觉或气色)很差<br />4)the hell表示强调，意思为&ldquo;到底&rdquo;<br />stump=截肢<br />8.with his escape,the aiding and abetting charges the felonies he&#8217;s racked up along the way,on top of his original sentence,I&#8217;d say Mr.Scofield will be spending the rest of his life behind bars.介于他越狱,协助并教唆犯罪等种种重罪指控,我得说Scofield要在监狱渡过余生了<br />abet=怂恿,教唆 ; rack up=积累 ; behind bars=坐牢<br />9.We&#8217;re entitled to a phone call. 我们有打电话的权利<br />be entitled to do sth.=有权利,有资格做某事<br />10.So sit tight.所以给我好好坐着<br />tight=安稳的<br />sleep tight=&quot;睡个好觉&quot;<br />11.What you&#8217;re asking me to do is tantamount to suicide. 你要我干的事相当于让我自杀<br />tantamount to=等价于<br />12.Pardon my forwardness. 原谅我的粗鲁<br />pardon=原谅,宽恕 ; forwardness=卤莽;热心<br />13.there&#8217;s sure to be a moment or two of chaos.会有一小会儿骚乱<br />a moment or two=一会儿<br />chaos=骚乱,吵杂 (教一个音忆法 chaos&#8211;chao+s,用汉语拼音读就是&quot;吵死&quot; ,这个词一下就能记住啦^ ^)<br />14.Refresh my memory. 我回忆一下<br />15.there is just one teensy-tiny thing i been meaning to ask.我只要求你帮个一个小小的忙<br />tessy=[俗]极小的=tiny ; teensy-tiny=小之又小的<br />16.copy that.收到<br />常用口语<br />17.You just found your inside man,but it&#8217;s got to be right now. 你们得找个知情人,不过我们现在就得行 动<br />inside man=知情人,线人</p>
<p>第十四集<br />1.Give me a medevac,asap!我需要医疗直升飞机,快点!<br />medevac=医疗后送直升飞机<br />asap=尽快,为&quot;as soon as possible&quot;的缩写,在紧急情况下读成&quot;asap&quot;以节省时间<br />2.No offense,sir,but we&#8217;re searching every vehicle.恕我冒犯,但我们在搜查每一辆车<br />no offense在美语中很常用,当你要指出别人的缺点，或者表示不同观点的时候，都可以加这样一句,表示没有故意要冒犯的意思.另外,no offense如果用在打球方面,就是一方没有进攻,或没有得分<br />3.That means,that at this stage,every second is critical.So if you detain me for one moment more,i will have all of your jobs. 这说明,眼下每一秒都至关重要.如果你们再妨碍我,我就让你们都失业<br />at this stage=眼下，暂时 ； critical=批评的;万分紧急的； detain=阻止，拘留<br />4.Now I have a bull&#8217;s-eye on my chest,just as you two.现在我也你们俩一样被人追杀<br />bull&#8217;s-eye=靶心 ; chest=胸口<br />5.Don&#8217;t fret now. 先不要急<br />fret=(使)焦急<br />6.We got ourselves a clean slate.我们都清白了<br />slate=(书写用的)石板,在美语中也指&quot;候选人名单,提名名单&quot;<br />a clean slate相当于中文里的&quot;白纸一张,如白纸一样纯洁&quot;<br />7.Well,you were a little more formidable than we anticipated.你们比我们想像中要强大些<br />formidable=强大的;令人敬畏的,可怕的<br />8.We don&#8217;t need compliments out of you,jackass. 我们不需要你的恭维,混蛋<br />compliments=称赞，恭维 <br />out of=来自;从&#8230;里面;在&#8230;范围外<br />9.well,it was touch-and-go there for a minute,but i got everything handled.嗯,刚开始有点儿惊险,不过我已经掌控一切了<br />touch-and-go= 草率从事的行动;一触即发的形势<br />10.He is a losse end.他是个麻烦<br />loose end=(常由于复数)不用的部分;未了结的零星问题<br />11.you are great,top-notch.你们真强,是高手.<br />(这句话是steadman在电视上看到ms和linc又逃走后,对某FBI说的 ^^)<br />top大家都知道是最高的意思.notch为在一样东西上刻记号.当然最高的就是最好的,所以Top-notch是指最出众的人或其他东西. 如&quot;top-notch personnel&quot;即指&quot;拔尖人才&quot;<br />12.Man,you don&#8217;t quit. 老兄,你真是执着<br />13.You are smarter than a bee sting.你真聪明<br />这是一个形象的比喻,bee sting为蜂刺,smart在此一语双关,以为smart既有&quot;聪明&quot;的意思,还有&quot;刺痛&quot;之意, 故于bee sting比较<br />14.If anything jumps off,you get my back,I won&#8217;t forget it. 如果有事发生,你帮我一把,我不会忘记的<br />jumps off的字面意思为&quot;跳下,脱离&quot;,在文章中常表示&quot;开始&quot;<br />15.Out there,you&#8217;re on your own. 在外面你得靠自己<br />on your own=独立自主<br />16.just relax and keep your head.只需放松和冷静<br />keep one&#8217;s head=保持冷静 <br />此外,keep your head down的意思是&quot;说话做事保持低调,不为人注意&quot;</p>
<p>第十五集<br />1.Exit with your hands in the air.举手出来<br />with your hands in the air=我们更熟悉的:with your hands up<br />2.I&#8217;ll make you a deal if you don&#8217;t move a muscle,i won&#8217;t blow your head off.我跟你说好,只要你乖乖着.我就不打爆你的头 <br />not move a muscle=毫不动容,不变神色<br />此外,在美国俚语中be on the muscle=准备动武; 准备蛮干 <br />在口语中flex one&#8217;s muscles =小试身手 <br />on the muscle =用暴力方式;气势汹汹的<br />3.pull over. 靠边,靠岸,开到路边<br />发现这是michael经常跟linc说的话&#8212;-&quot;把车停到一边&quot;,每当linc问&quot;why&quot;的时候,michael都是一脸懒得跟你解释的那种神情说&quot;just pull over&quot;<br />4.Your commitment to help others,and i put you in a place that&#8217;s every doctor&#8217;s nightmare.你承诺帮助他人,我却让你陷入医生的恶梦中<br />commitment to=许诺<br />5.I&#8217;m going to take a leak. 我去小解<br />leak=泄漏; take a leak=小解<br />6.That&#8217;s a nasty contusion.那是恶意殴打<br />nasty=令人不快的;恶意的 ; contusion=殴打;打伤<br />7.If you think i can pull some strings to keep you out of gen pop.I can&#8217;t do that. 如果你以为我能让你不关禁闭,那么你错了<br />pull strings=在幕后操作 <br />gen pop是lockdown的口语说法,意为&quot;一级防范紧闭&quot;<br />8.They&#8217;re already done irreparable damage. 他们已经造成了不可挽回的损失<br />irreparable=不可挽回的 ; ir-为&quot;不&quot;的前缀<br />reparable=可修复的,可挽回的<br />9.A tape purported to be made by escaped convicts lincoln burrows and michael scofield was immediarely dismissed by the justice department.逃犯lincoln与michael做的可疑录影带被司法部门立即驳回<br />purported=可疑的 (purport=意义,主旨) <br />dismiss=[法律]不受理.dismiss还有&quot;打发,解散,开除&quot;的意思<br />10.They dumped it off the front page and buried it.他们把这事从报纸头条撤下并隐瞒起来<br />dump=倾倒,抛弃<br />我们常在电影里听到的&quot;He/She dumped me&quot;的意思就是&quot;他/她甩了我&quot;<br />front page=报纸上的头版头条,也可用&quot;page one&quot;<br />11.It&#8217;s a hail mary,man.这是孤注一掷,老兄<br />hail mary原指祷告者向圣母玛丽亚求救,而在美国口语中通常是指当成功的机率非常小时,做绝望的尝试<br />12.I&#8217;m guessing they&#8217;re spoon-feeding us every lead they want us to follow.我猜他们想让我们顺着他们铺的路去白忙一场<br />spoon-feeding=填鸭式<br />spoon-feeding education=填鸭式教育<br />13.What if this is just one giant setup?如何这是个巨大的圈套呢?<br />giant=巨大的;伟大的 ; setup=陷阱,圈套<br />14.I didn&#8217;t drive all this way to gloat. 我跑这么远不是来嘲笑你的<br />gloat=幸灾乐祸<br />15.The girl bailed on you back in Gila.这女孩在Gila都没跟你走<br />我们在PB里常见的bail的用法为&quot;保释&quot;,而bail还有个常用词义为&quot;离开&quot;</p>
<p>第十六集<br />1.Out in the cold. remember? 我被流放着,你还记得么?<br />Out in the cold=被忽视,被冷落<br />2.I don&#8217;t recognize the insignia, do you? 我不认识这标志?你呢?<br />insignia=阶级、团体成员身份等用的佩章、衣饰等<br />3.I want Scofield&#8217;s and Burrows&#8217; pictures on each and every gas pump.我希望S和B的照片贴在每个加油站上<br />gas pump=加油站<br />each and every.虽然老师一直教我们each和every的区别,但从此句可以看到,口语中可用&quot;each and every&quot;是可以连用的,起强调作用<br />4.Everything goes through headquarters from now on.从现在起,所有事都要向总部汇报<br />headquarters=n.(公司,机关等的)总部,总公司;(军,警的)司令部<br />headquarter=v.设立总部<br />5.I need you to clear a car for me.我需要你腾出一节车厢给我<br />car=火车车厢 <br />6.You want him to rub elbows with your other passengers?你想他和其他乘客坐一起么?<br />rub=磨擦 ; elbow=肘<br />rub elbows with sb.的引申义就是&quot;与某人挨很近&quot;<br />7.Everything is jake.一切都好<br />jake=(俚)对的,好<br />Everything is jake=Everything is all right<br />8.I tried, but your new warden, straight as an arrow.我试过了,但你们的新狱长固执得要命<br />straight as an arrow=像弓箭一样直,来比喻一个人待人处世抱诚守真、刚正不阿<br />eg. The man insisted that he was innocent and that he was as straight as an arrow. 那个人坚持自己是清 白的, 而且他是个正直的人<br />9.And you tracked down bagwell by following susan hollander.你又通过跟踪susan hollander追捕到了bagwell.<br />track down=追捕<br />10.It&#8217;s just waiting to be rubber-stamped. 只需一些盖章的批准工作 <br />rubber-stamped=橡皮图章；照常规的批准<br />11.Fowl is not part of a traditional brunch.禽肉不是传统的早午餐的一部分<br />brunch=breakfast+lunch,即&quot;早午餐&quot;<br />12.We have got company.我们有客人<br />company=客人<br />13.Remember that merry-go-round that we saw today? 记得我们今天看到的旋转木马么?<br />merry-go-round=旋转木马<br />14.what if the only thing inside&#8217;s a bunch of stogies?要里面只有一些雪茄怎么办?<br />stogie=stogy=廉价的细长雪茄烟,产于宾西法尼亚(Pennsylvania)州的科内斯托加(Conestoga)<br />15.I don&#8217;t wanna spend any more minutes in here than necessary.我不想再在这里浪费时间了<br />&#8230;more&#8230;than necessary=比应当的更&#8230;<br />16.I&#8217;m no local hayseed cop. 我不是地方草包警察<br />hayseed=甘草种子，甘草屑,在美国口语中指&quot;乡巴佬&quot;<br />17.whoever this is..tell bill kim that he just screwed up..big time.不管你是谁,告诉bill kim他这次搞砸了&#8230;砸大了<br />screw up=搞糟,搞砸<br />big time=[俚语]十分,极度;欢乐时刻</p>
<p>第十七集<br />1.she&#8217;s been ill, some chronic condition.她有病,慢性病<br />chronic=(病)慢性的 ; 反之,acute=(病)急性的<br />2.Find a spot close to the club and sit tight.找个离俱乐部近的地方,慢慢等着<br />tight可作形容词或副词,指&quot;牢牢的/地,不动的/地&quot;<br />3.What the hell are you thinking about, waltzing here?你到底想怎么样,还悠闲地跑到这儿?<br />waltz=华尔兹,在这里指&quot;轻松前进&quot;<br />4.She&#8217;s had this kidney thing since she was real young.她从小肾就有问题<br />kidney=肾<br />5.I don&#8217;t give a rat&#8217;s ass about your or your brother.我对你和你哥的事都他妈的没兴趣<br />I don&#8217;t give a shit/damn/rat&#8217;s ass about sth.都算是粗口了,表示&quot;我不在乎&#8230;&quot;<br />6.What if i&#8217;m standing on this side? 如果我处于这种情况呢?<br />7.There are places that can better serve your needs.有些地方更适合你们的需要<br />serve sb&#8217;s needs=help sb. (当help用腻时,可用serve sb&#8217;s needs替换)<br />8.What the hell are you trying to pull.你到底想干嘛?<br />pull在美国口语中指&quot;干(勾当),耍阴谋&quot;<br />eg.Don&#8217;t try to pull anything.别想耍什么花招<br />9.Look me in the eye,tell me you don&#8217;t believe there&#8217;s a cover-up going on right now.看着我的眼睛,你觉得我在欺骗你吗?<br />cover-up=掩饰;掩盖<br />(顺便体会一下Look me in the eye和Look at me的小区别)<br />10.&#8217;cause i feel like a circus freak.因为我觉得自己像马戏团小丑<br />circus=马戏团;马戏表演 ; freak=行为怪诞的人<br />11.you mark my words.你牢牢记住我说的话<br />mark=记下,录下,可与&quot;remember/record&quot;替换<br />12.President reynolds attended a chicago fundraiser last night.reynolds总统昨晚在芝加哥参加了一个筹款活动<br />fund=基金 ; raiser=筹措者 ; fundraiser=资金筹集活动<br />13.Scofield,i don&#8217;t know what you&#8217;re used to,but anything short of filet mignon is not going to cult it with me.Scofield,我不知道你习惯怎么着,但没有一客腓力牛排别想打发我.<br />short of=缺少,不足<br />filet mignon=腓力牛排.这个词源于法语.意思就是牛里脊,是牛身上最贵的部分.<br />14.Do you think i&#8217;d bring you here to so sacred a place to me as this if i meant you ill.如果我要害你,你觉得我会带你来这个对我来说如此神圣的地方么?<br />ill用在此处指&quot;坏的;冷酷的;恶劣的&quot;.比&quot;bad&quot;的程度深<br />15.I am the laws of karma all come down wrong.我是因果报应的作孽的产物<br />karma=命运;因果报应<br />佛教中认为节制万众生灵的是所谓&ldquo;功德法轮&rdquo;(law of karma)此功德法轮是一组定律常规, 支配善恶的因果报应, 生命的托世轮回,.反之, <br />物理的自然定律(laws of Nature), 是客观的, 是永恒的, 不受鬼神的支配的<br />(由此可看出t-bag的文字功底确实了得)<br />16.may need to run a few tests.可能得做些化验<br />17.You don&#8217;t mind if i ask you to empty your pockets.你不介意我搜一下你的口袋吧?<br />empty (out) sb&#8217;s pockets=搜查某人<br />eg.The police made the thief empty out his pocket.警察搜查小偷<br />此外,an empty pocket=没有钱的人.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/320.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>解决 AJAX 跨域方案一(PHP Proxy)</title>
		<link>http://www.donevii.com/post/172.html</link>
		<comments>http://www.donevii.com/post/172.html#comments</comments>
		<pubDate>Mon, 06 Nov 2006 02:43:48 +0000</pubDate>
		<dc:creator>dengwei</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[技术]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=172</guid>
		<description><![CDATA[在工作中需要用到 AJAX 跨域技术，并且在各个外部服务器上修改 httpd.conf 代价太大，所以先用 PHP Proxy 来解决。以下是 Yahoo! 的解决方法。 Why You Need a Proxy All modern web browsers impose a security restricti... ]]></description>
			<content:encoded><![CDATA[<p>在工作中需要用到 AJAX 跨域技术，并且在各个外部服务器上修改 httpd.conf 代价太大，所以先用 <a href="http://www.donevii.com/post/tag/php" class="st_tag internal_tag" rel="tag" title="Posts tagged with php">PHP</a> Proxy 来解决。以下是 Yahoo! 的解决方法。</p>
<h2 class="first">Why You Need a Proxy<a name="why"></a></h2>
<p>All modern <a href="http://www.donevii.com/post/tag/web" class="st_tag internal_tag" rel="tag" title="Posts tagged with web">web</a> browsers impose a security restriction on network connections, which includes calls to XMLHttpRequest. This restriction prevents a script or application from making a connection to any <a href="http://www.donevii.com/post/tag/web" class="st_tag internal_tag" rel="tag" title="Posts tagged with web">web</a> <a href="http://www.donevii.com/post/tag/server" class="st_tag internal_tag" rel="tag" title="Posts tagged with server">server</a> other than the one the web page originally came from (Internet Explorer will allow cross-domain requests if the option has been enabled in the preferences). If both your web application and the XML data that application uses come directly from the same <a href="http://www.donevii.com/post/tag/server" class="st_tag internal_tag" rel="tag" title="Posts tagged with server">server</a>, then you do not run into this restriction. </p>
<p><img height="189" src="http://developer.yahoo.com/javascript/img/proxy1.gif" width="336" alt="" /></p>
<p>If, however, you serve your web application from one web server and you make web service data requests to another server &#8212; for example, to the Yahoo! Web Services &#8212; then the browser prevents the connection from being opened at all. Bummer. </p>
<p><img height="284" src="http://developer.yahoo.com/javascript/img/proxy2.gif" width="347" alt="" /></p>
<p>There are a number of solutions to this problem but the most commonly-used one is to install a proxy on your web server. Instead of making your XMLHttpRequest calls directly to the web service, you make your calls to your web server proxy. The proxy then passes the call onto the web service and in return passes the data back to your client application. Because the connection is made to your server, and the data comes back from your server, the browser has nothing to complain about.</p>
<p><img height="201" src="http://developer.yahoo.com/javascript/img/proxy3.gif" width="525" alt="" /></p>
<p>For security reasons it&#8217;s a good idea for any proxy you install on your web server should be limited in use. An open proxy that passes on connections to any web site URL is open to abuse. Although it is difficult to limit the connections to your proxy from only your application, you can prevent the proxy from making connections to servers other than those you specify. Hard code the URL to connect to in the proxy itself or provide limited options. This makes the proxy less open and less useful to users other than your client application.</p>
<h2>PHP Proxy for Yahoo! Web Services<a name="phpproxy"></a></h2>
<p>For the Yahoo! Developer Network <a href="http://developer.yahoo.com/javascript/index.html">JavaScript Developer Center</a> we have provided sample code for a <a href="http://developer.yahoo.com/javascript/samples/proxy/php_proxy_simple.txt">simple web proxy</a>, written in PHP, that takes requests for the Yahoo! Search APIs. You can install this proxy on your own web server in any convenient location (your web server must be set up to run PHP). </p>
<p>The proxy encodes the Yahoo! Web services site URL in a global variable called HOSTNAME. ou will need to modify this variable to refer to the Yahoo! Web Services API you&#8217;ll be using. This is the domain used by the Yahoo! Search web services; other domains include Yahoo! Local (<code>http://api.local.yahoo.com</code>) and Yahoo! Travel (<code>http://api.travel.yahoo.com</code>). </p>
<p><code>define ('HOSTNAME', 'http://api.search.yahoo.com/');</code></p>
<p>To use the PHP web proxy in your client application, the URL for the request in the <a href="http://www.donevii.com/post/tag/javascript" class="st_tag internal_tag" rel="tag" title="Posts tagged with javascript">JavaScript</a> code includes the path for the Yahoo! Web Services request, minus the domain name. The domain name is added by the proxy itself on the server side. This code snippet comes from a <a href="http://developer.yahoo.com/javascript/samples/ajax/sample_proxy_ajax.html">more complete XMLHttpRequest code sample</a> on our <a href="http://developer.yahoo.com/javascript/index.html">JavaScript Developer Center</a>.</p>
<p><code>// The web services request minus the domain name<br />var path = 'VideoSearchService/V1/videoSearch?appid=YahooDemo&amp;query=madonna&amp;results=2';</p>
<p>// The full path to the PHP proxy<br />var url = 'http://localhost/php_proxy_simple.php?yws_path=' + encodeURIComponent(path);<br />... // core xmlhttp code<br />xmlhttp.open('GET', url, true); </code></p>
<p>Note that although this example uses an HTTP GET request, the sample PHP web proxy also supports POST.</p>
<p>You could modify the proxy to do post-processing of the data you get from the request on the server side, for example, to strip out only the elements you&#8217;re interested in or the parse the XML into a format you can more comfortably handle in JavaScript. </p>
<h2>Other Solutions<a name="other"></a></h2>
<p>In addition to using a web proxy to pass web services data to your application, there are several other options to working around cross-domain browser restrictions: </p>
<ul class="topspace">
<li>Use apache&#8217;s <code>mod_rewrite</code> or <code>mod_proxy</code> to pass requests from your server to some other server. In your client code you just make the request as if it was actually on your server &#8212; no browser problems with that. Apache then does its magic and makes the request to the other server for you. </li>
<li>Use JSON and dynamic <code>&lt;script&gt;</code> tags instead of XML and XMLHttpRequest. You can get around the browser security problem altogether by making your web services request directly inside a <code>&lt;script&gt;</code> tag. If the Yahoo! Web Service you&#8217;re using can output JSON (using the <code>output=json</code> and <code>callback=</code>function parameters), the data you get back from the web service is evaluated as a JavaScript object when the page is loaded. See our <a href="http://developer.yahoo.com/common/json.html" class="broken_link">JSON Documentation</a> for an example of how to do this in your own scripts. </li>
<li>Digitally sign your scripts. In Firefox you can apply a digital signature to your script and those scripts will then be considered &quot;trusted&quot; by the browser. Firefox will then let you make XMLHttpRequests to any domain. However, no other browsers support script signing at this time, so this solution is of limited use. </li>
</ul>
<h2>For More Information<a name="more"></a></h2>
<p>For more information on JavaScript, XMLHttpRequest, Yahoo! Web Services APIs and other JavaScript development topics, see The Yahoo! Developer Network <a href="http://developer.yahoo.com/javascript/index.html">JavaScript Developer Center</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/172.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VC++开发BHO插件 &#8211; 定制你的浏览器</title>
		<link>http://www.donevii.com/post/152.html</link>
		<comments>http://www.donevii.com/post/152.html#comments</comments>
		<pubDate>Tue, 31 Oct 2006 01:31:49 +0000</pubDate>
		<dc:creator>gavinkwoe</dc:creator>
				<category><![CDATA[c/c++/c#]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[开发]]></category>
		<category><![CDATA[类]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=152</guid>
		<description><![CDATA[转至http://dev.yesky.com 在Windows操作系统上，我们最常见的浏览器有两种：文件浏览器（exploer.exe，应用于文件系统）和Internet浏览器（iexplore.exe，应用于互联网资源）。由于这两个浏览器功能强大... ]]></description>
			<content:encoded><![CDATA[<p>转至<a href="http://dev.yesky.com">http://dev.yesky.com</a></p>
<p>在Windows操作系统上，我们最常见的浏览器有两种：文件浏览器（exploer.exe，应用于文件系统）和Internet浏览器（iexplore.exe，应用于互联网资源）。由于这两个浏览器功能强大，而且又与Windows操作系统捆绑销售，最终也就成为了浏览器的标准。但有时候，为了给浏览器加入一些新的特性，我们往往会重新设计一个自己的浏览器。新的浏览器模仿标准浏览器的大部分功能，同时加入新特性。这种做法最直观，但实际上也是相对于微软的重复劳动，且工作量比较大。其实，使用BHO插件，一切都变得很简单。 </p>
<p>　　BHO（Browser Help Objects），是实现了特定接口的COM组件。开发好的BHO插件在注册表特定的位置注册好后，每当微软的浏览器启动，BHO实例就会被创建。在浏览器工作的工程中，BHO会接收到很多事件，比如浏览器浏览新的地址、前进或后退、生成新的窗口、浏览器退出等等；BHO可以在这些事件的响应中实现与浏览器的交互。<br />　<br />　　下面，我们首先来介绍一下BHO的工作原理。上面我们已经提到，BHO是COM组件，而且一定实现了IObjectWithSite接口。这些组件除了在注册表中注册为COM Server外，还必须将它们的CLSID在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\<a href="http://www.donevii.com/post/tag/windows" class="st_tag internal_tag" rel="tag" title="Posts tagged with windows">Windows</a>\ CurrentVersion\Explorer\Browser Helper Objects下注册为子键。微软在设计浏览器的时候，已经给这些组件预留了空间。每当浏览器启动时，浏览器会首先在上述注册表位置查看是否有注册的BHO CLSID；如果有则分别创建一个实例，并对BHO实例进行初始化，建立交互连接。（注：BHO实例只有在创建它的浏览器窗口销毁时才被释放。）下图演示了BHO的创建过程：</p>
<table width="90%" align="center">
<tbody>
<tr>
<td>
<div align="center"><img alt="说明 Createbho.jpg" src="http://dev.yesky.com/imagelist/06/33/wd0h60g5a5t1.jpg" /></div>
</td>
</tr>
</tbody>
</table>
<p>　　成功创建的BHO，不仅可以得到各种标准的浏览器操作事件，并做出响应；还可以定制浏览器的菜单、工具条等界面元素；更或者可以安装钩子函数，监视浏览器的一举一动。值得注意的是，使用BHO插件，Internet浏览器要求在4.0以上版本；如果是文件浏览器，操作系统要求是Windows 95/98/2000或Window NT 4.0以上版本，并且Shell的版本在4.71以上。下面是支持BHO特性的系统一览表：</p>
<table cellspacing="0" cellpadding="0" width="90%" align="center" border="1">
<tbody>
<tr>
<td>Shell版本</td>
<td>操作系统版本</td>
<td>支持BHO </td>
</tr>
<tr>
<td>4.00</td>
<td>Windows 95 and Windows NT 4.0（IE版本为 4.0）</td>
<td>仅IE4.0 </td>
</tr>
<tr>
<td>4.71</td>
<td>Windows 95 and Windows NT 4.0（IE版本为 4.0）</td>
<td>IE和文件浏览器</td>
</tr>
<tr>
<td>4.72</td>
<td>Windows 98 </td>
<td>IE和文件浏览器</td>
</tr>
<tr>
<td>5.00</td>
<td>Windows 2000</td>
<td>IE和文件浏览器</td>
</tr>
</tbody>
</table>
<p>　　接下去，笔者就来介绍一下如何开发BHO插件，开发环境为VC6.0（使用ATL），安装Platform SDK中的Internet Development SDK。首先，启动VC的ATL COM AppWizard，生成一个项目名为BhoPlugin，其余均采用默认设置。接着，我们就来分步详细阐述。</p>
<p>　　第一步，增加一个ATL Object到该项目中。VC菜单Insert-&gt;New ATL Object&hellip;，在弹出的对话框中选择&ldquo;Internet Explorer Object&rdquo;，输入COM类名（在Short Name后输入EyeOnIE，其它各项会自动生成）。完成后，我们可以看到CEyeOnIE类有一个基类IObjectWithSiteImpl，这个就是实现IObjectWithSite接口的模版类。</p>
<p>　　第二步，实现IObjectWithSite的接口方法。在这之前，我们要先定义几个成员变量：CComQIPtr&lt;IWebBrowser2, &amp;IID_IWebBrowser2&gt; mWebBrowser2，（需要加入#include &quot;ExDisp.h&quot;），用以保存浏览器组件的指针；DWORD mCookie，用以保存与浏览器的连接ID。IObjectWithSite有两个接口方法：SetSite和GetSite。我们只需重载SetSite就行了。在EyeOnIE.h中增加函数声明STDMETHOD(SetSite)(IUnknown *pUnkSite)，在EyeOnIE.cpp实现如下：</p>
<table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1">
<tbody>
<tr>
<td>STDMETHODIMP CEyeOnIE::SetSite(IUnknown *pUnkSite)<br />            {<br />            　USES_CONVERSION;</p>
<p>            　if (pUnkSite)<br />            　{<br />            　　mWebBrowser2 = pUnkSite;<br />            　　if (mWebBrowser2)<br />            　　{<br />            　　　return RegisterEventHandler(TRUE);<br />            　　}<br />            　}<br />            　return E_FAIL;<br />            }</p>
<p>            HRESULT CEyeOnIE::RegisterEventHandler(BOOL inAdvise)<br />            {<br />            　CComPtr&lt;IConnectionPoint&gt; spCP;<br />            　// Receives the connection point for WebBrowser events<br />            　CComQIPtr&lt;IConnectionPointContainer, &amp;IID_IConnectionPointContainer&gt; spCPC(mWebBrowser2);<br />            　HRESULT hr = spCPC-&gt;FindConnectionPoint(DIID_DWebBrowserEvents2, &amp;spCP);<br />            　if (FAILED(hr))<br />            　　return hr;</p>
<p>            　if (inAdvise)<br />            　{<br />            　　// Pass the event handlers to the container<br />            　　hr = spCP-&gt;Advise(reinterpret_cast&lt;IDispatch*&gt;(this), &amp;mCookie);<br />            　}<br />            　else<br />            　{<br />            　　spCP-&gt;Unadvise(mCookie);<br />            　}<br />            　return hr; <br />            }</td>
</tr>
</tbody>
</table>
<p>　　我们可以看到，SetSite的参数实际上指向的是浏览器组件。在SetSite实现中，我们首先保存浏览器组件指针，然后将该BHO向浏览器注册为事件处理器。</p>
<p>第三步，实现IDispatch接口方法。事件处理也就在IDispatch::Invoke中实现（各个事件的ID在ExDispID.h中定义）。BHO可能会接收到很多事件，但我们只需要响应我们感兴趣的那一部分。首先在EyeOnIE.h中增加该函数的声明，在EyeOnIE.cpp的实现中，笔者试着响应浏览器浏览一个地址之前发出的事件DISPID_BEFORENAVIGATE2，以此来实现简单的网址过滤功能，代码参考如下：</p>
<table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1">
<tbody>
<tr>
<td>STDMETHODIMP CEyeOnIE::Invoke(DISPID dispidMember,REFIID riid, LCID lcid, <br />            WORD wFlags, DISPPARAMS * pDispParams, <br />            VARIANT * pvarResult,EXCEPINFO * pexcepinfo, <br />            UINT * puArgErr)<br />            { <br />            　USES_CONVERSION;</p>
<p>            　if (!pDispParams)<br />            　　return E_INVALIDARG;</p>
<p>            　switch (dispidMember)<br />            　{<br />            　　//<br />            　　// The parameters for this DISPID are as follows:<br />            　　// [0]: Cancel flag &#8211; VT_BYREF|VT_BOOL<br />            　　// [1]: HTTP headers &#8211; VT_BYREF|VT_VARIANT<br />            　　// [2]: Address of HTTP POST data &#8211; VT_BYREF|VT_VARIANT <br />            　　// [3]: Target frame name &#8211; VT_BYREF|VT_VARIANT <br />            　　// [4]: Option flags &#8211; VT_BYREF|VT_VARIANT<br />            　　// [5]: URL to navigate to &#8211; VT_BYREF|VT_VARIANT<br />            　　// [6]: An object that evaluates to the top-level or frame<br />            　　// WebBrowser object corresponding to the event. <br />            　　//<br />            　　case DISPID_BEFORENAVIGATE2:<br />            　　{<br />            　　　LPOLESTR lpURL = NULL;<br />            　　　mWebBrowser2-&gt;get_LocationURL(&amp;lpURL);<br />            　　　char * strurl;<br />            　　　if (pDispParams-&gt;cArgs &gt;= 5 &amp;&amp; pDispParams-&gt;rgvarg[5].vt == (VT_BYREF|VT_VARIANT))<br />            　　　{<br />            　　　　CComVariant varURL(*pDispParams-&gt;rgvarg[5].pvarVal);<br />            　　　　varURL.ChangeType(VT_BSTR);<br />            　　　　strurl = OLE2A(varURL.bstrVal);<br />            　　　}<br />            　　　if (strstr(strurl, &quot;girl.com&quot;))<br />            　　　{<br />            　　　　*pDispParams-&gt;rgvarg[0].pboolVal = TRUE;<br />            　　　　::MessageBox(NULL, _T(&quot;该网页已被禁止!&quot;),_T(&quot;Warning&quot;),MB_ICONSTOP);<br />            　　　　return S_OK;<br />            　　　}<br />            　　　break;<br />            　　}</p>
<p>            　　case DISPID_NAVIGATECOMPLETE2:<br />            　　　break;<br />            　　case DISPID_DOCUMENTCOMPLETE:<br />            　　　break;<br />            　　case DISPID_DOWNLOADBEGIN:<br />            　　　break;<br />            　　case DISPID_DOWNLOADCOMPLETE:<br />            　　　break;<br />            　　case DISPID_NEWWINDOW2:<br />            　　　break;<br />            　　case DISPID_QUIT:<br />            　　　RegisterEventHandler(FALSE);<br />            　　　break;<br />            　　default:<br />            　　　break;<br />            　}</p>
<p>            　return S_OK;<br />            }</td>
</tr>
</tbody>
</table>
<p>　　我们看到，当用户浏览的新地址包含&quot;girl.com&quot;字符的时候，浏览器就会弹出一个警告对话框，并且停止进一步的动作。另外值得注意的是，在DISPID_QUIT事件（浏览器将要退出）的响应中，我们将BHO事件处理器进行了注销。</p>
<p>　　第四步，因为BHO可能会被文件浏览器加载。如果我们不想这样，我们就要在DllMain中对加载者进行判断，参考如下：</p>
<table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1">
<tbody>
<tr>
<td>extern &quot;C&quot;<br />            BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)<br />            {<br />            　if (dwReason == DLL_PROCESS_ATTACH)<br />            　{<br />            　　// Check who&#8217;s loading us. <br />            　　// If it&#8217;s Explorer then &quot;no thanks&quot; and exit&#8230;<br />            　　TCHAR pszLoader[MAX_PATH];<br />            　　GetModuleFileName(NULL, pszLoader, MAX_PATH);<br />            　　_tcslwr(pszLoader);<br />            　　if (_tcsstr(pszLoader, _T(&quot;explorer.exe&quot;))) <br />            　　　return FALSE;</p>
<p>            　　_Module.Init(ObjectMap, hInstance, &amp;LIBID_BHOPLUGINLib);<br />            　　DisableThreadLibraryCalls(hInstance);<br />            　}<br />            　else if (dwReason == DLL_PROCESS_DETACH)<br />            　　_Module.Term();<br />            　　return TRUE; // ok<br />            }</td>
</tr>
</tbody>
</table>
<p>　　最后，别忘了修改注册表文件，追加BHO的注册信息。在EyeOnIE.rgs文件的下面增加如下代码：</p>
<table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1">
<tbody>
<tr>
<td>HKLM<br />            {<br />            　SOFTWARE<br />            　{<br />            　　Microsoft<br />            　　{<br />            　　　Windows<br />            　　　{<br />            　　　　CurrentVersion<br />            　　　　{<br />            　　　　　Explorer<br />            　　　　　{<br />            　　　　　　&#8217;Browser Helper Objects&#8217;<br />            　　　　　　{<br />            　　　　　　　{6E28339B-7A2A-47B6-AEB2-46BA53782379}<br />            　　　　　　}<br />            　　　　　}<br />            　　　　}<br />            　　　}<br />            　　}<br />            　}<br />            }</td>
</tr>
</tbody>
</table>
<p>　　注意，{6E28339B-7A2A-47B6-AEB2-46BA53782379}是笔者这个BHO的CLSID，如果你自己开发BHO，这里应该正确填写你的CLSID。</p>
<p>　　好了，一个简单的BHO开发完成了。（可以到本人的个人主页 http://hqtech.nease.net 下载实例源代码。）BHO插件可以实现的功能还有很多，比如网页内容分析、IE界面定制等等。作为总结，笔者还要提醒读者一点的是，如果不想让BHO起作用了，可以注销该插件，如下格式：regsvr32 /u yourpath\yourbho.dll，或者直接在注册表中将&ldquo;Browser Helper Objects&rdquo;目录下注册的CLSID删掉。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/152.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>文学水平测试</title>
		<link>http://www.donevii.com/post/115.html</link>
		<comments>http://www.donevii.com/post/115.html#comments</comments>
		<pubDate>Wed, 25 Oct 2006 03:17:38 +0000</pubDate>
		<dc:creator>dengwei</dc:creator>
				<category><![CDATA[doc]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[测试]]></category>
		<category><![CDATA[生活]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=115</guid>
		<description><![CDATA[今天在一个朋友的 BLOG 上看到的 Sogou 的小东西，比较好玩。我把我的《所谓&#8220;WEB2.0 &#8221;下的创意》这篇BLOG贴在里面测试了一下，竟然得出以下结果。 dengwei，您的总体评价： 文字的平民化... ]]></description>
			<content:encoded><![CDATA[<p>今天在一个朋友的 <a href="http://www.donevii.com/post/tag/blog" class="st_tag internal_tag" rel="tag" title="Posts tagged with blog">BLOG</a> 上看到的 Sogou 的小东西，比较好玩。我把我的《所谓&ldquo;<a href="http://www.donevii.com/post/tag/web" class="st_tag internal_tag" rel="tag" title="Posts tagged with web">WEB</a>2.0 &rdquo;下的创意》这篇BLOG贴在里面测试了一下，竟然得出以下结果。 </p>
<h2 class="title1">dengwei，您的总体评价：</h2>
<p class="evaluate">文字的平民化韵味浓郁，具有很强的生活气息；相对正统的创作路线，可读性较强。架构清晰，逻辑性强，情节缜密，可读性强；文章内容丰富，观点翔实可圈可点；在成语使用方面可以着重下功夫改进。情节缜密题材的小说值得尝试，将推理、悬念、历史的因素掺杂其中；同时也可以尝试杂文、评论等文体。行文时留心描写与情节结构的紧密配合，必然会诞生令人耳目一新的作品。</p>
<style type="text/css">.articletest {width: 305px;background: url(http://www.sogou.com/images/statsword/logo.gif) no-repeat 8px top;padding: 37px 8px 8px;font-size: 12px;}.resultbox{border: 1px solid #bbb;padding: 5px 13px;margin-bottom: 5px;}.resultbox dl, .resultbox dd {	margin: 0;padding: 0;}.authorname {width: 70px;float: left;font-weight: bold;}.bar{width: 80px;float: left;}.similarity{color: #DF5900;float: left;font-weight: bold;}.comment {clear: both;}.bg1 {background:url(http://www.sogou.com/images/statsword/star1.gif) no-repeat right top;}.bg2 {background: url(http://www.sogou.com/images/statsword/star2.gif) no-repeat right top; }.bg3 {	background: url(http://www.sogou.com/images/statsword/star3.gif) no-repeat right top; }.wanttest {	float: left;	clear:both;	font-weight: bold;	color: red;	padding: 4px 6px;	line-height: normal;	border: 1px solid #D6D3B7;}.wanttest {	float: left;	clear:both;	font-weight: bold;	color: red;	padding: 4px 6px 4px 13px;	line-height: normal;	border: 1px solid #D6D3B7;	background: url(http://www.sogou.com/images/statsword/ss.gif) no-repeat 7px 8px;}.wanttest a {	color: red;	text-decoration: none;}.title1, .title2, .title3 {	font-size: 14px;	color: #f60;}.title1 {	background: url(http://www.sogou.com/images/statsword/icon1.gif) no-repeat 4px center;	padding: 0 12px;        height:1%;}</style>
<div class="articletest">
<div class="resultbox bg1">
<dl>
<dt class="authorname"><a target="_blank" href="http://www.sogou.com/web?query= 王朔">王朔</a> </dt>
<dd class="bar"><img height="13" width="84" alt="" src="http://www.sogou.com/images/statsword/bar1.gif" /> </dd>
<dd class="similarity">44% </dd>
<dd class="comment">虽然不明显，但是文章跟这位作家的风格有些形似呢。</dd>
</dl>
</div>
<div class="resultbox bg2">
<dl>
<dt class="authorname"><a target="_blank" href="http://www.sogou.com/web?query= 高行健">高行健</a> </dt>
<dd class="bar"><img height="13" width="32" alt="" src="http://www.sogou.com/images/statsword/bar2.gif" /> </dd>
<dd class="similarity">17% </dd>
<dd class="comment">这个区间是比较正常的，看来你已经有了掌握神韵的感觉喔。</dd>
</dl>
</div>
<div class="resultbox bg3">
<dl>
<dt class="authorname"><a target="_blank" href="http://www.sogou.com/web?query= 说不得大师">说不得大师</a> </dt>
<dd class="bar"><img height="13" width="12" alt="" src="http://www.sogou.com/images/statsword/bar3.gif" /> </dd>
<dd class="similarity">7% </dd>
<dd class="comment">基本可以忽略不计了&#8230;&#8230;实话说吧，这就是凑数的，呵呵&#8230;&#8230;</dd>
</dl>
</div>
<p class="wanttest"><a href="http://www.sogou.com/websearch/test/statsword.jsp" class="broken_link">有意思，我也要去试试！</a></p>
</div>
<p>&nbsp;</p>
<p>感兴趣的话您也可以去试一试</p>
<p><a href="http://www.sogou.com/websearch/test/statsword.jsp" class="broken_link">http://www.sogou.com/websearch/test/statsword.jsp</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/115.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>常用的HR相关英文词汇</title>
		<link>http://www.donevii.com/post/73.html</link>
		<comments>http://www.donevii.com/post/73.html#comments</comments>
		<pubDate>Tue, 10 Oct 2006 03:10:45 +0000</pubDate>
		<dc:creator>dengwei</dc:creator>
				<category><![CDATA[doc]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[ror]]></category>
		<category><![CDATA[开发]]></category>
		<category><![CDATA[测试]]></category>
		<category><![CDATA[类]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=73</guid>
		<description><![CDATA[1. 人力资源管理:(Human Resource Management ,HRM) 人力资源经理:( human resource manager)高级管理人员:(executive)职业:(profession)道德标准:(ethics)操作工:(operative employees)专家:(specialist)人力资源认证协会:(the Human... ]]></description>
			<content:encoded><![CDATA[<p><strong>1. 人力资源管理:(Human Resource Management ,HRM)</p>
<p></strong>人力资源经理:( human resource manager)<br />高级管理人员:(executive)<br />职业:(profession)<br />道德标准:(ethics)<br />操作工:(operative employees)<br />专家:(specialist)<br />人力资源认证协会:(the Human Resource Certification Institute,HRCI)</p>
<p><strong>2. 外部环境:(external environment)</strong></p>
<p>内部环境:(internal environment)<br />政策:(policy)<br />企业文化:(corporate culture)<br />目标:(mission)<br />股东:(shareholders)<br />非正式组织:(informal organization)<br />跨国公司:(multinational corporation,MNC)<br />管理多样性:(managing diversity)</p>
<p><strong>3. 工作:(job)</strong></p>
<p>职位:(posting)<br />工作分析:(job analysis)<br />工作说明:(job description)<br />工作规范:(job specification)<br />工作分析计划表:(job analysis schedule,JAS)<br />职位分析问卷调查法:(Management Position Description Questionnaire,MPDQ)<br />行政秘书:(executive secretary)<br />地区服务经理助理:(assistant district service manager)</p>
<p><strong>4. 人力资源计划:(Human Resource Planning,HRP)</strong></p>
<p>战略规划:(strategic planning)<br />长期趋势:(long term trend)<br />要求预测:(requirement forecast)<br />供给预测:(availability forecast)<br />管理人力储备:(management inventory)<br />裁减:(downsizing)<br />人力资源信息系统:(Human Resource Information System,HRIS)</p>
<p><strong>5. 招聘:(recruitment)</strong></p>
<p>员工申请表:(employee requisition)<br />招聘方法:(recruitment methods)<br />内部提升:(Promotion From Within ,PFW)<br />工作公告:(job posting)<br />广告:(advertising)<br />职业介绍所:(employment agency)<br />特殊事件:(special events)<br />实习:(internship)</p>
<p><strong>6. 选择:(selection)</strong></p>
<p>选择率:(selection rate)<br />简历:(resume)<br />标准化:(standardization)<br />有效性:(validity)<br />客观性:(objectivity)<br />规范:(norm)<br />录用分数线:(cutoff score) <br />准确度:(aiming)<br />业务知识测试:(job knowledge tests)<br />求职面试:(employment interview)<br />非结构化面试:(unstructured interview)<br />结构化面试:(structured interview)<br />小组面试:(group interview)<br />职业兴趣测试:(vocational interest tests)<br />会议型面试:(board interview)</p>
<p><strong>7. 组织变化与人力资源开发</strong></p>
<p>人力资源开发:(Human Resource Development,HRD)<br />培训:(training)<br /><a href="http://www.donevii.com/post/tag/%e5%bc%80%e5%8f%91" class="st_tag internal_tag" rel="tag" title="Posts tagged with 开发">开发</a>:(development)<br />定位:(orientation)<br />训练:(coaching)<br />辅导:(mentoring)<br />经营管理策略:(business games)<br />案例研究:(case study)<br />会议方法:(conference method)<br />角色扮演:(role playing)<br />工作轮换:(job rotating)<br />在职培训:(on-the-job training ,OJT)<br />媒介:(media)</p>
<p><strong>8. 企业文化与组织发展</strong></p>
<p>企业文化:(corporate culture)<br />组织发展:(organization development,OD)<br />调查反馈:(survey feedback)<br />质量圈:(quality circles)<br />目标管理:(management by objective,MBO)<br />全面质量管理:(Total Quality Management,TQM)<br />团队建设:(team building)</p>
<p><strong>9. 职业计划与发展</strong></p>
<p>职业:(career)<br />职业计划:(career planning)<br />职业道路:(career path)<br />职业发展:(career development)<br />自我评价:(self-assessment)<br />职业动机:(career anchors)</p>
<p><strong>10. 绩效评价</strong></p>
<p>绩效评价:(Performance Appraisal,PA)<br />小组评价:(group appraisal)<br />业绩评定表:(rating scales method)<br />关键事件法:(critical incident method)<br />排列法:(ranking method)<br />平行比较法:(paired comparison)<br />硬性分布法:(forced distribution method)<br />晕圈错误:(halo error)<br />宽松:(leniency)<br />严格:(strictness)<br />3600反馈:(360-degree feedback)<br />叙述法:(essay method)<br />集中趋势:(central tendency)</p>
<p><strong>11. 报酬与福利</strong></p>
<p>报酬:(compensation)<br />直接经济报酬:(direct financial compensation)<br />间接经济报酬:(indirect financial compensation)<br />非经济报酬:(no financial compensation)<br />公平:(equity)<br />外部公平:(external equity)<br />内部公平:(internal equity)<br />员工公平:(employee equity)<br />小组公平:(team equity)<br />工资水平领先者:(pay leaders)<br />现行工资率:(going rate)<br />工资水平居后者:(pay followers)<br />劳动力市场:(labor market)<br />工作评价:(job evaluation)<br />排列法:(ranking method)<br />分类法:(classification method)<br />因素比较法:(factor comparison method)<br />评分法:(point method)<br />海氏指示图表个人能力分析法:(Hay Guide Chart-profile Method)<br />工作定价:(job pricing)<br />工资等级:(pay grade)<br />工资曲线:(wage curve)<br />工资幅度:(pay range)</p>
<p><strong>12. 福利和其它报酬问题</strong></p>
<p>福利(间接经济补偿)<br />员工股权计划:(employee stock ownership plan,ESOP)<br />值班津贴:(shift differential)<br />奖金:(incentive compensation)<br />分红制:(profit sharing)</p>
<p><strong>13. 安全与健康的工作环境</strong></p>
<p>安全:(safety)<br />健康:(health)<br />频率:(frequency rate)<br />紧张:(stress)<br />角色冲突:(role conflict)<br />催眠法:(hypnosis)<br />酗酒:(alcoholism)</p>
<p><strong>14. 员工和劳动关系</strong></p>
<p>工会:(union)<br />地方工会:(local union)<br />行业工会:(craft union)<br />产业工会:(industrial union)<br />全国工会:(national union)<br />谈判组:(bargaining union)<br />劳资谈判:(collective bargaining)<br />仲裁:(arbitration)<br />罢工:(strike)<br />内部员工关系:(internal employee relations)<br />纪律:(discipline)<br />纪律处分:(disciplinary action)<br />申诉:(grievance)<br />降职:(demotion)<br />调动:(transfer)<br />晋升:(promotion)</p>
<p><a class="blog_content broken_link" target="_blank" href="http://www.chinahrd.net/zhi_sk/article.asp?articleID=19389">http://www.chinahrd.net/zhi_sk/article.asp?articleID=19389</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/73.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>使用Boost.Python构建混合系统</title>
		<link>http://www.donevii.com/post/24.html</link>
		<comments>http://www.donevii.com/post/24.html#comments</comments>
		<pubDate>Sun, 20 Aug 2006 04:46:09 +0000</pubDate>
		<dc:creator>gavinkwoe</dc:creator>
				<category><![CDATA[doc]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ror]]></category>
		<category><![CDATA[开发]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[类]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=24</guid>
		<description><![CDATA[... ]]></description>
			<content:encoded><![CDATA[<p><!--
<div style="BACKGROUND-COLOR: #eeeeee"> &#8211;><br />
<h1 class="title">使用Boost.Python构建混合系统</h1>
<h1 class="title"><font size="3">Building Hybrid Systems with Boost.<a href="http://www.donevii.com/post/tag/python" class="st_tag internal_tag" rel="tag" title="Posts tagged with python">Python</a></font></h1>
<table rules="none" frame="void" class="docinfo">
<colgroup><font color="#c0c0c0"><br />
<col class="docinfo-name"></col>
<col class="docinfo-content"></col>
<p></font></colgroup>
<tbody valign="top">
<tr>
<th class="docinfo-name"><font color="#c0c0c0">&nbsp; Author:</font></th>
<td><font color="#c0c0c0">David Abrahams</font></td>
</tr>
<tr>
<th class="docinfo-name"><font color="#c0c0c0">Contact:</font></th>
<td><a class="first last reference" href="mailto:dave@boost-consulting.com"><font color="#c0c0c0">dave@boost-consulting.com</font></a></td>
</tr>
<tr>
<th class="docinfo-name"><font color="#c0c0c0">Organization:</font></th>
<td><a class="first last reference" href="http://www.boost-consulting.com/"><font color="#c0c0c0">Boost Consulting</font></a></td>
</tr>
<tr>
<th class="docinfo-name"><font color="#c0c0c0">Date:</font></th>
<td><font color="#c0c0c0">2003-03-19</font></td>
</tr>
<tr>
<th class="docinfo-name"><font color="#c0c0c0">Author:</font></th>
<td><font color="#c0c0c0">Ralf W. Grosse-Kunstleve</font></td>
</tr>
<tr>
<th class="docinfo-name"><font color="#c0c0c0">Translation:</font></th>
<td><font color="#c0c0c0">王志勇( </font><a href="mailto:jerrywang_cn@msn.com"><font color="#c0c0c0">JerryWang_cn@msn.com</font></a><font color="#c0c0c0">)</font></td>
</tr>
<tr>
<th class="docinfo-name"><font color="#c0c0c0">Copyright:</font></th>
<td><font color="#c0c0c0">Copyright David Abrahams and Ralf W. Grosse-Kunstleve 2003. All rights reserved</font></td>
</tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title">&nbsp;</p>
<ul class="simple">
<li><a class="reference" id="id5" name="id5" href="#abstract"><font color="#ffcc00">概要</font></a><font color="#ffcc00"> </font></li>
<li><a class="reference" id="id6" name="id6" href="#introduction"><font color="#ffcc00">介绍</font></a><font color="#ffcc00"> </font></li>
<li><a class="reference" id="id7" name="id7" href="#boost-python-design-goals"><font color="#ffcc00">Boost.Python 的设计目标</font></a><font color="#ffcc00"> </font></li>
<li><a class="reference" id="id8" name="id8" href="#hello-boost-python-world"><font color="#ffcc00">Hello Boost.Python World</font></a><font color="#ffcc00"> </font></li>
<li><a class="reference" id="id9" name="id9" href="#library-overview"><font color="#ffcc00">Library Overview</font></a><font color="#ffcc00"> </font>
<ul>
<li><a name="id10" href="#exposing-classes"><font color="#ffcc00">导出</font></a><a class="reference" id="id10" name="id10" href="#exposing-classes"><font color="#ffcc00"> Classes</font></a><font color="#ffcc00"> </font>
<ul>
<li><a name="id11" href="#constructors"><font color="#ffcc00">构造</font></a><a name="id11" href="#constructors"><font color="#ffcc00">函数</font></a><a name="id11" href="#constructors"><font color="#ffcc00">(</font></a><a class="reference" id="id11" name="id11" href="#constructors"><font color="#ffcc00">Constructors</font></a><font color="#ffcc00">) </font></li>
<li><a name="id12" href="#data-members-and-properties"><font color="#ffcc00">数据</font></a><a name="id12" href="#data-members-and-properties"><font color="#ffcc00">成员</font></a><a name="id12" href="#data-members-and-properties"><font color="#ffcc00">和</font></a><a name="id12" href="#data-members-and-properties"><font color="#ffcc00">属性</font></a><a name="id12" href="#data-members-and-properties"><font color="#ffcc00">(</font></a><a class="reference" id="id12" name="id12" href="#data-members-and-properties"><font color="#ffcc00">Data Members and Properties</font></a><font color="#ffcc00">) </font></li>
<li><a name="id13" href="#operator-overloading"><font color="#ffcc00">操作符</font></a><a name="id13" href="#operator-overloading"><font color="#ffcc00">重载</font></a><font color="#ffcc00">(</font><a class="reference" id="id13" name="id13" href="#operator-overloading"><font color="#ffcc00">Operator Overloading</font></a><font color="#ffcc00">) </font></li>
<li><a class="reference" id="id14" name="id14" href="#inheritance"><font color="#ffcc00">继承(Inheritance</font></a><font color="#ffcc00">) </font></li>
<li><a name="id15" href="#virtual-functions"><font color="#ffcc00">虚</font></a><a name="id15" href="#virtual-functions"><font color="#ffcc00">函数</font></a><a name="id15" href="#virtual-functions"><font color="#ffcc00">(</font></a><a class="reference" id="id15" name="id15" href="#virtual-functions"><font color="#ffcc00">Virtual Functions</font></a><font color="#ffcc00">) </font></li>
<li><a class="reference" id="id16" name="id16" href="#deeper-reflection-on-the-horizon"><font color="#ffcc00">Deeper Reflection on the Horizon?</font></a><font color="#ffcc00"> </font></li>
</ul>
</li>
<li><a name="id17" href="#serialization"><font color="#ffcc00">序列</font></a><a name="id17" href="#serialization"><font color="#ffcc00">化</font></a><a name="id17" href="#serialization"><font color="#ffcc00">(</font></a><a class="reference" id="id17" name="id17" href="#serialization"><font color="#ffcc00">Serialization</font></a><font color="#ffcc00">) </font></li>
<li><a name="id18" href="#object-interface"><font color="#ffcc00">Object 接口</font></a><a name="id18" href="#object-interface"><font color="#ffcc00">(</font></a><a class="reference" id="id18" name="id18" href="#object-interface"><font color="#ffcc00">Object interface</font></a><font color="#ffcc00">) </font></li>
</ul>
</li>
<li><a class="reference" id="id19" name="id19" href="#thinking-hybrid"><font color="#ffcc00">Thinking hybrid</font></a><font color="#ffcc00"> </font></li>
<li><a class="reference" id="id20" name="id20" href="#development-history"><font color="#ffcc00">开发历史</font></a><font color="#ffcc00"> </font></li>
<li><a class="reference" id="id21" name="id21" href="#conclusions"><font color="#ffcc00">总结</font></a><font color="#ffcc00"> </font></li>
<li><a name="id22" href="#citations"><font color="#ffcc00">引用</font></a><font color="#ffcc00"> </font></li>
<li><a name="id23" href="#footnotes"><font color="#ffcc00">脚注</font></a><font color="#ffcc00"> </font></li>
</ul>
</div>
<div class="section" id="abstract">
<h1><a class="toc-backref" name="abstract" href="#id5">概要</a></h1>
<p>Boost.Python是一个开源C＋＋库，她提供了一个简明的 IDL 式的接口用于绑定C＋＋类和函数到Python。得益于C＋＋编译期的内部处理(译注：原文是introspection，我不知道怎么翻译合适)和最近开发的元编程(metaprogramming)<a href="http://www.donevii.com/post/tag/%e6%8a%80%e6%9c%af" class="st_tag internal_tag" rel="tag" title="Posts tagged with 技术">技术</a>，成就了Boost.Python不需引入一种新的语法而只用纯C＋＋的实现。Boost.Python丰富的特性集合以及她的高阶接口使得工程师像混合系统(译注：hybrid system，我听说过油/电混合动力系统)那样做打包的事情成为可能，并且程序员让在应用C＋＋高效的编译期多态性以及Python非常方便的运行期多态性的时候获得易用性和一致性；</p>
</div>
<div class="section" id="introduction">
<h1><a class="toc-backref" name="introduction" href="#id6">介绍</a></h1>
<p>Python和C＋＋在很多方面相当的不同：C＋＋一般编译为机器码，Python是解释处理的。Python的动态类型系统(dynamic type system )作为语言具有灵活性的基础常常被提及，然而C＋＋的静态类型系统是她效率的基石。C＋＋拥有一种复杂和难以理解的编译期元语言(compile-time meta-language)，然而在Python里头几乎所有事情都发生在运行期。</p>
<p>但是对于很多程序员来说，这些很大的不同也意味着Python和C＋＋可以完美的互补。Python程序内性能瓶颈的部分可以用C＋＋重写以带来最高的运行速度，并且强大的C＋＋库的作者们可以选择Python作为中间件语言，利用她灵活的系统集成能力。此外，表面上的不同也掩盖了一些非常相似之处：</p>
<ul class="simple">
<li>C语言家族的控制结构(if, while, for&#8230;) </li>
<li>支持面向对象、函数化编程以及普通语言(these are both <em>multi-paradigm</em> programming languages.) </li>
<li>全面的操作符重载机制，重视为了代码可读性和表达性而提高语法可变性 </li>
<li>高层概念，例如集合和迭代器(collections and iterators) </li>
<li>上层封装机制(C＋＋：namespace，Python：modules)以便支持重用库的设计 </li>
<li>异常捕获机制用于错误情况管理 </li>
<li>C++ idioms in common use, such as handle/body classes and reference-counted smart pointers mirror Python reference semantics </li>
</ul>
<p>提供给Python丰富的&lsquo;C&rsquo;互操作API，应当尊许一个法则：导出C＋＋的类型和函数接口给Python的时候，尽量用和C＋＋相似的接口。然而，Python自己提供的C＋＋集成接口是非常贫乏的。比较C＋＋和 Python ，&lsquo;C&rsquo;只有非常基本的抽象能力，而且不支持异常处理机制。&lsquo;C&rsquo;扩展模块的作者被要求手动管理Python的引用计数，那是非常麻烦而且容易出错的事情。传统的扩展模块往往包含大量的重复的&lsquo;样板代码&rsquo;，使得代码难以维护，特别是当你封装一个发展中的API(译注：指还未完善的API)的时候。</p>
<p>这些限制导致出现了大量的Python封装系统。 <a class="reference" href="http://www.swig.org/">SWIG</a> 大概是最流行的一种用于集成 C/C++ 和 Python 的系统。最近出现的一种是 <a class="reference broken_link" href="http://www.riverbankcomputing.co.uk/sip/index.php">SIP</a>，特别设计用于集成 Python 和 <a class="reference" href="http://www.trolltech.com/">Qt</a>&nbsp; 图形用户接口。SWIG 和 SIP 都引入了他们自己的专门语言用于定制语言间绑定。这么做有一定的好处，但是你不得不去处理三种语言( Python 、C/C++以及引入的接口语言)，所以也带来了实际困难。<a class="reference" href="http://cxx.sourceforge.net/">CXX</a> 则演示了另外一种有趣的选择。她证明了至少部分的 Python 的 &#8216;C&#8217; API 可以被更友好的 C＋＋接口封装。然而，不像 SWIG 和 SIP 那样，CXX 不包含对封装 C＋＋类和 Python 新类型(new Python types)的支持。</p>
<p><a class="reference" href="http://www.boost.org/libs/python/doc">Boost.Python</a> 的特性和目标与很多其它的封装系统是一样的。就是说 Boost.Python 企图提供最大化的易用性和灵活性，但是并不引入一种独立的封装语言。取而代之的是，她提供高级的C＋＋接口给用户用于封装C＋＋类和函数，并且通过静态元程序(static metaprogramming)管理大量内部的复杂性。Boost.Python 超越了早期封装系统提供的特性，包括：</p>
<ul class="simple">
<li>支持能够被Python重载的C＋＋虚函数。 </li>
<li>对于低阶的C＋＋指针和引用(low-level C++ pointers and references)，提供全面的生命期管理机制。 </li>
<li>支持把扩展功能封装为package，通过中心的注册机制作语言间类型转换。 </li>
<li>通过一种安全和易用的方法，用于引入Python强大的序列化引擎(pickle)。 </li>
<li>与C＋＋对lvalues、rvalues的处理机制一致，所以可以对C＋＋以及Python的类型系统深入的理解（译注：明白了一个就明白了另外一个）。 </li>
</ul>
<p>&nbsp;</p>
<p>开发Boost.Python最主要的目的是，通过使用C＋＋的编译期内部处理(原文是：introspection)，大量的传统扩展模块样板代码可以被排除。每个封装的C＋＋参数必须从一个Python对象中取得，根据参数的类型使用不同的过程(procedure)进行处理。同样地，函数的返回类型决定了返回值怎样从C＋＋到Python进行转换。当然，参数和返回值的类型是每个函数类型的一部分，这就是Boost.Python得出大部分所需信息的源头。</p>
<p>这种方法引入了<em>用户指导封装</em>：在纯C＋＋的框架范围内，使得直接导出(到Python)的信息和被封装的源代码一样多成为了可能，一些额外的信息由用户显式地提供。通常这种&lsquo;指导&rsquo;是机械化的几乎不需要用户实际的干涉。因为接口的规范是用和表述代码同样的全特性语言描述的，用户拥有了空前的能力，当他想进行控制的时候。</p>
</div>
<div class="section" id="boost-python-design-goals">
<h1><a class="toc-backref" name="boost-python-design-goals" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id7">Boost.Python 的设计目标</a></h1>
<p>Boost.Python的主要设计目标是让用户可以只通过C++编译器，就能在Python内使用C＋＋类和函数。简单说，用户感觉就是直接从Python里面操作C＋＋对象。</p>
<p>然而，不逐个转换所有接口也是很重要的：每种语言的习惯必须被尊重。例如，尽管C＋＋和Python都有迭代器(iterator)的概念，他们的表达方式却很不同。Boost.Python不得不具有能把他们结合在一起的能力。</p>
<p>把Python用户从C＋＋接口里的琐碎错误中隔离开必须是可能的，例如访问已经被删除了的对象。同样的，必须使C＋＋用户从低阶Python &#8216;C&#8217; API 隔离开来，用更好的选择去替换掉像手工进行<em>引用计数管理</em>和<em>新的 PyObject 指针管理</em>这些事情，他们都是容易导致错误的 &#8216;C&#8217; 接口。</p>
<p>支持基于组件的开发也是至关重要的，所以，一个扩展模块中的C＋＋导出类型可以被传递到另外一个模块导出的函数内应用，而且不丢失任何重要信息，例如C＋＋的继承关系。</p>
<p>最后，所有的封装必须是<em>非干扰性</em>的，不能修改甚至只是&lsquo;查看&rsquo;原始的C＋＋代码。现存的C＋＋库对于只有header文件和二进制文件的第三方来说，已经是可封装的了。</p>
</div>
<div class="section" id="hello-boost-python-world">
<h1><a class="toc-backref" name="hello-boost-python-world" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id8">Hello Boost.Python World</a></h1>
<p>现在先来个Boost.Python的预览，看看她是如何改进Python的原有机制的。下面是我们可能要用于Python的函数：</p>
<pre class="literal-block">char const* greet(unsigned x){   static char const* const msgs[] = { &quot;hello&quot;, &quot;Boost.Python&quot;, &quot;world!&quot; };   if (x &gt; 2)        throw std::range_error(&quot;greet: index out of range&quot;);   return msgs[x];}</pre>
<p>使用 Python 的 &#8216;C&#8217;&nbsp; API 封装这个函数，我们需要这样做：</p>
<pre class="literal-block">extern &quot;C&quot; // all Python interactions use 'C' linkage and calling convention{    // Wrapper to handle argument/result conversion and checking    PyObject* greet_wrap(PyObject* args, PyObject * keywords)    {         int x;         if (PyArg_ParseTuple(args, &quot;i&quot;, &amp;x))    // extract/check arguments         {             char const* result = greet(x);      // invoke wrapped function             return PyString_FromString(result); // convert result to Python         }         return 0;                               // error occurred    }    // Table of wrapped functions to be exposed by the module    static PyMethodDef methods[] = {        { &quot;greet&quot;, greet_wrap, METH_VARARGS, &quot;return one of 3 parts of a greeting&quot; }        , { NULL, NULL, 0, NULL } // sentinel    };    // module initialization function    DL_EXPORT init_hello()    {        (void) Py_InitModule(&quot;hello&quot;, methods); // add the methods to the module    }}</pre>
<p>现在，这是使用 Boost.Python 的封装代码：</p>
<pre class="literal-block">#include &lt;boost/python.hpp&gt;using namespace boost::python;BOOST_PYTHON_MODULE(hello){    def(&quot;greet&quot;, greet, &quot;return one of 3 parts of a greeting&quot;);}</pre>
<p>这里演示了如何使用：</p>
<pre class="literal-block">&gt;&gt;&gt; import hello&gt;&gt;&gt; for x in range(3):...     print hello.greet(x)...helloBoost.Pythonworld!</pre>
<p>实际上&#8217;C&#8217; API的版本更冗长，it&#8217;s worth noting a few things that it doesn&#8217;t handle correctly:</p>
<ul class="simple">
<li>原始函数接受一个无符号整数参数，然而Python &#8216;C&#8217; API只提供了提取有符号整数的方式给我们。如果我们传递一个负数给<tt class="literal"><span class="pre">hello.greet</span>，</tt>Boost.Python 版本会抛出一个 Python 异常，但是另外一个版本将会执行下去，不管C＋＋的实现中在什么时候转换负整数到无符号数(通常封装成很大的数)，然后传递<strong>不正确的</strong>转换过的参数到被封装的函数。 </li>
<li>这带给了我们第二个问题：如果C＋＋的<tt class="literal"><span class="pre">greet()</span></tt>函数被一个比2大的参数调用，它会抛出一个异常。典型地，如果一个C＋＋异常通过&#8217;C'编译器生成的代码的边界进行传递，会引起崩溃(crash)。像你在第一个版本中看到的那样，那里没有阻止它(crash)发生的C＋＋机制。Boost.Python封装的函数自动包含了一个异常处理层，它能通过转换未捕获的C＋＋异常到对应的Python异常以保护Python用户。 </li>
<li>有点更微妙的限制是：使用Python &#8216;C&#8217; API进行参数转换的示例只能用一种方式取得整数<tt class="literal"><span class="pre">x</span></tt>。PyArg_ParseTuple 无法转换 Python 的 <tt class="literal"><span class="pre">long</span></tt> 对象(任意精度整数)它正好适合一个<tt class="literal"><span class="pre">unsigned</span> <span class="pre">int</span></tt> 而不是<tt class="literal"><span class="pre">signed</span> <span class="pre">long</span></tt>, 也不能通过一个封装的带有用户显式定义的<tt class="literal"><span class="pre">operator</span> <span class="pre">unsigned</span> <span class="pre">int()</span></tt> 的C＋＋类来转换。Boost.Python的动态类型转换注册(dynamic type conversion registry)允许用户添加任意的转换方法。 </li>
</ul>
<h1><a class="toc-backref" name="library-overview" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id9">Library Overview</a></h1>
<p>这一部分描述了库的主要特性。为了避免混乱，库的实现细节被省略了。</p>
<div class="section" id="exposing-classes">
<h2><a class="toc-backref" name="exposing-classes" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id10">导出Classes</a></h2>
<p>C＋＋类和结构是用同样简洁的接口导出的：</p>
<pre class="literal-block">struct World{    void set(std::string msg) { this-&gt;msg = msg; }    std::string greet() { return msg; }    std::string msg;};</pre>
<p>下面的代码会导出它到我们的扩展模块：</p>
<pre class="literal-block">#include &lt;boost/python.hpp&gt;BOOST_PYTHON_MODULE(hello){    <a href="http://www.donevii.com/post/tag/class" class="st_tag internal_tag" rel="tag" title="Posts tagged with class">class</a>_&lt;World&gt;(&quot;World&quot;)        .def(&quot;greet&quot;, &amp;World::greet)        .def(&quot;set&quot;, &amp;World::set)    ;}</pre>
<p>尽管这些代码有某种pythonic familiarity(译注：或许是Python风格的意思)，人们有时还是发现这种语法有点令人迷惑，因为它看上去不像他们过去使用的C＋＋代码。其实，这就是标准C＋＋的实现。由于他们的灵活的语法和操作符重载，C＋＋和Python在定义domain-specific (sub)languages (DSLs)上是非常出色的，那就是我们在Boost.Python里面做的。把它拆开看：</p>
<pre class="literal-block">class_&lt;World&gt;(&quot;World&quot;)</pre>
<p>构造一个未命名的<tt class="literal"><span class="pre">class_&lt;World&gt;</span></tt>类型的对象并且传递<tt class="literal"><span class="pre">&quot;World&quot;</span></tt> 到它的构造函数。这就在扩展模块里面创造了一个新的Python class叫作<tt class="literal"><span class="pre">World</span></tt> ，并且把它在Boost.Python类型转换注册(type conversion registry)里头和C＋＋类型<tt class="literal"><span class="pre">World</span></tt> 关联起来了。我们可能也会写下：</p>
<pre class="literal-block">class_&lt;World&gt; w(&quot;World&quot;);</pre>
<p>但是那会显得更冗长，因为我们不得不再次通过<tt class="literal"><span class="pre">w</span></tt> 去调用<tt class="literal"><span class="pre">def()</span></tt> 成员函数：</p>
<pre class="literal-block">w.def(&quot;greet&quot;, &amp;World::greet)</pre>
<p>在原来示例中的成员访问形式&mdash;&mdash;&lsquo;点&rsquo;(dot)没什么特别的：C＋＋允许在一个表达式的任何一边写下任何数量的空白，把&lsquo;点&rsquo;放在每行代码的开始允许我们连续的调用成员函数，因为我们喜欢统一形式的语法。另外一个关键的、允许实现链式语法的事实是<tt class="literal"><span class="pre">class_&lt;&gt;</span></tt> 成员函数都返回一个到 <tt class="literal"><span class="pre">*this</span> </tt>的引用(reference)。</p>
<p>所以这个示例等于：</p>
<pre class="literal-block">class_&lt;World&gt; w(&quot;World&quot;);w.def(&quot;greet&quot;, &amp;World::greet);w.def(&quot;set&quot;, &amp;World::set);</pre>
<p>这种形式偶尔是有用的，以便用这种方式分解 Boost.Python 的类封装，但是文章剩下的部分将会使用简洁的语法。</p>
<p>这里是封装类的使用：</p>
<pre class="literal-block">&gt;&gt;&gt; import hello&gt;&gt;&gt; planet = hello.World()&gt;&gt;&gt; planet.set('howdy')&gt;&gt;&gt; planet.greet()'howdy'</pre>
<div class="section" id="constructors">
<h3><a class="toc-backref" name="constructors" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id11">构造函数(Constructors</a>)</h3>
<p>由于我们的<tt class="literal"><span class="pre">World</span></tt> 类只是一个<tt class="literal"><span class="pre">struct</span></tt>, 它有一个隐式的无参数(空的)的构造函数。Boost.Python缺省的会公开这个构造函数(给Python)，所以我们可以这样写：</p>
<pre class="literal-block">&gt;&gt;&gt; planet = hello.World()</pre>
<p>然而，在任何语言里面的良好设计的类都会需要构造函数参数&mdash;&mdash;用于建立他们的不变量(invariants)。不像Python，她的<tt class="literal"><span class="pre">__init__</span></tt> 只是一个特定命名的方法，在C＋＋里构造函数不能像普通成员函数那样被掌控。特别地，我们不能取他们的地址：<tt class="literal"><span class="pre">&amp;World::World</span></tt> 是一个错误。(Boost.Python)库提供了一种不同的接口以指定构造函数，像这样：</p>
<pre class="literal-block">struct World{    World(std::string msg); // added constructor    ...</pre>
<p>我们可以像下面这样更改我们的封装代码：</p>
<pre class="literal-block">class_&lt;World&gt;(&quot;World&quot;, init&lt;std::string&gt;())    ...</pre>
<p>当然，一个C＋＋类可以有额外的构造函数，而且我们可以通过更多的<tt class="literal"><span class="pre">def()</span> <span class="pre">init&lt;...&gt;</span></tt> 实例把它们导出：</p>
<pre class="literal-block">class_&lt;World&gt;(&quot;World&quot;, init&lt;std::string&gt;())    .def(init&lt;double, double&gt;())    ...</pre>
<p>Boost.Python允许封装的函数、成员函数和构造函数被重载以反映他们在C＋＋中的重载关系(to be overloaded to mirror C++ overloading).</p>
</div>
<div class="section" id="data-members-and-properties">
<h3><a class="toc-backref" name="data-members-and-properties" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id12">数据成员和属性(Data Members and Properties</a>)</h3>
<p>任何public的C＋＋数据成员都可以容易地导出成<tt class="literal"><span class="pre">readonly</span></tt> 或 <tt class="literal"><span class="pre">readwrite</span></tt> 属性：</p>
<pre class="literal-block">class_&lt;World&gt;(&quot;World&quot;, init&lt;std::string&gt;())    .def_readonly(&quot;msg&quot;, &amp;World::msg)    ...</pre>
<p>也可以直接在Python内部使用：</p>
<pre class="literal-block">&gt;&gt;&gt; planet = hello.World('howdy')&gt;&gt;&gt; planet.msg'howdy'</pre>
<p>这不会造成在<tt class="literal"><span class="pre">World</span></tt> 实例内增加一个 <tt class="literal"><span class="pre">__dict__</span></tt>的结果，这么做可以在封装大型数据结构时节省内存。实际上，根本没有<tt class="literal"><span class="pre">__dict__</span></tt> 实例被创造除非显式地在 Python 里面给它增加属性。Boost.Python 把这种能力感激于Python 2.2 的类型系统，特别是描述符接口(descriptor interface)和 <tt class="literal"><span class="pre">property</span></tt> 类型。</p>
<p>在C＋＋里，具有public属性的数据成员被认为是一种糟糕的设计，因为它们破坏了封装性，并且风格指导通常指示使用&quot;getter&quot;和&quot;setter&quot;函数作为代替。在Python里， 对应<tt class="literal"><span class="pre">__getattr__</span>和</tt> <tt class="literal"><span class="pre">__setattr__</span></tt>，从2.2开始<tt class="literal"><span class="pre">property</span></tt> 意味着属性访问是一个程序员可用的，封装性更好的语法工具。Boost.Python通过使Python的<tt class="literal"><span class="pre">property</span></tt> 直接被创建并且对用户可用，弥合了这种语言习惯上的缝隙。即使<tt class="literal"><span class="pre">msg</span></tt> 是private的，我们还是可以把它作为属性(attribute)给Python使用，通过：</p>
<pre class="literal-block">class_&lt;World&gt;(&quot;World&quot;, init&lt;std::string&gt;())    .add_property(&quot;msg&quot;, &amp;World::greet, &amp;World::set)    ...</pre>
<p>上面的示例和Python 2.2+内使用properties的用法是一样的：</p>
<pre class="literal-block">&gt;&gt;&gt; class World(object):...     __init__(self, msg):...         self.__msg = msg...     def greet(self):...         return self.__msg...     def set(self, msg):...         self.__msg = msg...     msg = property(greet, set)</pre>
</div>
<div class="section" id="operator-overloading">
<h3><a class="toc-backref" name="operator-overloading" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id13">操作符重载(Operator Overloading</a>)</h3>
<p>具有编写针对用户定义数据类型的算术操作符(arithmetic operators)的能力已经成为一个数学计算语言主要的成功因素，像<a class="reference broken_link" href="http://www.pfdubois.com/numpy/">NumPy</a> 这样成功的包证明了在扩展模块里导出操作符的威力。Boost.Python提供了一种很简单的机制以实现封装操作符重载。下面的例子是一个Boost有理数库封装内部的代码片断：</p>
<pre class="literal-block">class_&lt;rational&lt;int&gt; &gt;(&quot;rational_int&quot;)  .def(init&lt;int, int&gt;()) // constructor, e.g. rational_int(3,4)  .def(&quot;numerator&quot;, &amp;rational&lt;int&gt;::numerator)  .def(&quot;denominator&quot;, &amp;rational&lt;int&gt;::denominator)  .def(-self)        // __neg__ (unary minus)  .def(self + self)  // __add__ (homogeneous)  .def(self * self)  // __mul__  .def(self + int()) // __add__ (heterogenous)  .def(int() + self) // __radd__  ...</pre>
<p>这里的魔法是应用一种简化的表达式模板(&quot;expression templates&quot;) <a class="citation-reference" id="id22" name="id24" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#veld1995">[VELD1995]</a>，一种原来用于开发high-performance matrix algebra expressions的技术。它的本质是利用重载的操作符构造一个类型以表示计算，而不是立即进行计算工作。In matrix algebra, dramatic optimizations are often available when the structure of an entire expression can be taken into account, rather than evaluating each operation &quot;greedily&quot;. Boost.Python 使用同样的技术构建一个适当的Python方法对象，这基于在表达式内包含<tt class="literal"><span class="pre">self</span></tt>。</p>
</div>
<div class="section" id="inheritance">
<h3><a class="toc-backref" name="inheritance" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id14">继承(Inheritance</a>)</h3>
<p>C++继承关系可以用Boost.Python描述，通过添加一个可选的<tt class="literal"><span class="pre">bases&lt;...&gt;</span></tt> 参数到<tt class="literal"><span class="pre">class_&lt;...&gt;</span></tt> 模板参数列表，像下面这样：</p>
<pre class="literal-block">class_&lt;Derived, bases&lt;Base1,Base2&gt; &gt;(&quot;Derived&quot;)     ...</pre>
<p>这有两种作用：</p>
<ol class="arabic simple">
<li>当类<tt class="literal"><span class="pre">class_&lt;...&gt;</span></tt> 被创建的时候，Boost.Python在注册项(registry)里面查找<tt class="literal"><span class="pre">Base1</span></tt> 和 <tt class="literal"><span class="pre">Base2</span></tt> 对应的Python类型对象，并且把他们作为新的Python <tt class="literal"><span class="pre">Derived</span></tt> 类型对象的基类，所以<tt class="literal"><span class="pre">Base1</span></tt> 和 <tt class="literal"><span class="pre">Base2</span></tt> 类型的方法自动成为<tt class="literal"><span class="pre">Derived</span></tt> 类型的成员。因为注册项(registry)是全局的，所以即使<tt class="literal"><span class="pre">Derived</span></tt> 是(和Base1/Base2)在不同的模块里头也有作用。 </li>
<li>从<tt class="literal"><span class="pre">Derived</span></tt> 到它的基类的转换也被添加的Boost.Python的注册项里。因而可以在每个包含了<tt class="literal"><span class="pre">Derived</span></tt> 实例的对象内部，调用 封装的C＋＋方法所需要(指向或引用到)的每个基类类型。class <tt class="literal"><span class="pre">T</span></tt> 的被封装的成员函数被看作有一个隐式的第一个参数<tt class="literal"><span class="pre">T&amp;</span></tt>,，所以那些用以允许基类方法被派生类调用的转换是必要的。 </li>
</ol>
<p>当然从封装的C＋＋类实例派生出新的Python对象也是可能的。因为Boost.Python使用new-style class system，他们和Python内建类型的工作方式很像。有一个重大的细节上的不同之处：内建类型通常通过<tt class="literal"><span class="pre">__new__</span></tt> 函数建立他们自己的不变量(invariants)，所以派生类在使用(基类的)方法前不需要调用基类的<tt class="literal"><span class="pre">__init__</span></tt> ：</p>
<pre class="literal-block">&gt;&gt;&gt; class L(list):...      def __init__(self):...          pass...&gt;&gt;&gt; L().reverse()&gt;&gt;&gt; </pre>
<p>因为C＋＋的对象构造是一个单步操作，C＋＋不能构造(对象)实例数据直到参数可用。在<tt class="literal"><span class="pre">__init__</span></tt> 函数里：</p>
<pre class="literal-block">&gt;&gt;&gt; class D(SomeBoostPythonClass):...      def __init__(self):...          pass...&gt;&gt;&gt; D().some_boost_python_method()Traceback (most recent call last):  File &quot;&lt;stdin&gt;&quot;, line 1, in ?TypeError: bad argument type for built-in operation</pre>
<p>它会出错，因为在D实例内部 Boost.Python 找不到<tt class="literal"><span class="pre"> SomeBoostPythonClass</span></tt> 的实例数据；<tt class="literal"><span class="pre">D </span></tt>的 <tt class="literal"><span class="pre">__init__</span></tt> 函数遮蔽了基类的构造。移除<tt class="literal"><span class="pre">D</span> </tt>的 <tt class="literal"><span class="pre">__init__</span></tt> 函数或者在<tt class="literal"><span class="pre"> SomeBoostPythonClass.__init__(...)</span></tt>内部显式的调用它都是正确的。</p>
</div>
<div class="section" id="virtual-functions">
<h3><a class="toc-backref" name="virtual-functions" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id15">虚函数(irtual Functions</a>)</h3>
<p>在Python里面，从扩展类型派生出新的类型不是有趣的事情，除非他们能从C＋＋被多态地使用。换句话说，Python方法的实现应当看上去是重载C＋＋虚函数的实现，当从C＋＋通过基类的指针/引用调用(这个虚函数)的时候。因为唯一的改变一个虚函数行为的办法是在派生类内重载它，用户必须创建一个特殊的派生类以<strong>转发</strong>(dispatch)<strong>实现</strong>这种虚函数的多态性：</p>
<pre class="literal-block">//// interface to wrap://class Base{ public:    virtual int f(std::string x) { return 42; }    virtual ~Base();};</pre>
<pre class="literal-block">int calls_f(Base const&amp; b, std::string x) { return b.f(x); }</pre>
<pre class="literal-block">//// Wrapping Code//// Dispatcher classstruct BaseWrap : Base{    // Store a pointer to the Python object    BaseWrap(PyObject* self_) : self(self_) {}    PyObject* self;    // Default implementation, for when f is not overridden    int f_default(std::string x) { return this-&gt;Base::f(x); }    // Dispatch implementation    int f(std::string x) { return call_method&lt;int&gt;(self, &quot;f&quot;, x); }};</pre>
<pre class="literal-block">...    def(&quot;calls_f&quot;, calls_f);    class_&lt;Base, BaseWrap&gt;(&quot;Base&quot;)        .def(&quot;f&quot;, &amp;Base::f, &amp;BaseWrap::f_default)        ;</pre>
<p>现在，这里是一些Python演示代码：</p>
<pre class="literal-block">&gt;&gt;&gt; class Derived(Base):...     def f(self, s):...          return len(s)...&gt;&gt;&gt; calls_f(Base(), 'foo')42&gt;&gt;&gt; calls_f(Derived(), 'forty-two')9</pre>
<p>关于<strong>转发类</strong>需要注意：</p>
<ul class="simple">
<li>The key element which allows overriding in Python is the <tt class="literal"><span class="pre">call_method</span></tt> invocation, which uses the same global type conversion registry as the C++ function wrapping does to convert its arguments from C++ to Python and its return type from Python to C++. </li>
<li>Any constructor signatures you wish to wrap must be replicated with an initial <tt class="literal"><span class="pre">PyObject*</span></tt> argument </li>
<li>The dispatcher must store this argument so that it can be used to invoke <tt class="literal"><span class="pre">call_method</span></tt> </li>
<li>The <tt class="literal"><span class="pre">f_default</span></tt> member function is needed when the function being exposed is not pure virtual; there&#8217;s no other way <tt class="literal"><span class="pre">Base::f</span></tt> can be called on an object of type <tt class="literal"><span class="pre">BaseWrap</span></tt>, since it overrides <tt class="literal"><span class="pre">f</span></tt>. </li>
</ul>
</div>
<div class="section" id="deeper-reflection-on-the-horizon">
<h3><a class="toc-backref" name="deeper-reflection-on-the-horizon" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id16">Deeper Reflection on the Horizon?</a></h3>
<p>Admittedly, this formula is tedious to repeat, especially on a project with many polymorphic classes. That it is neccessary reflects some limitations in C++&#8217;s compile-time introspection capabilities: there&#8217;s no way to enumerate the members of a class and find out which are virtual functions. At least one very promising project has been started to write a front-end which can generate these dispatchers (and other wrapping code) automatically from C++ headers.</p>
<p><a class="reference" href="http://www.boost.org/libs/python/pyste">Pyste</a> is being developed by Bruno da Silva de Oliveira. It builds on <a class="reference" href="http://www.gccxml.org/HTML/Index.html">GCC_XML</a>, which generates an XML version of GCC&#8217;s internal program representation. Since GCC is a highly-conformant C++ compiler, this ensures correct handling of the most-sophisticated template code and full access to the underlying type system. In keeping with the Boost.Python philosophy, a Pyste interface description is neither intrusive on the code being wrapped, nor expressed in some unfamiliar language: instead it is a 100% pure Python script. If Pyste is successful it will mark a move away from wrapping everything directly in C++ for many of our users. It will also allow us the choice to shift some of the metaprogram code from C++ to Python. We expect that soon, not only our users but the Boost.Python developers themselves will be &quot;thinking hybrid&quot; about their own code.</p>
</div>
</div>
<div class="section" id="serialization">
<h2><a class="toc-backref" name="serialization" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id17">序列化(Serialization</a>)</h2>
<p><em>序列化</em><em style="FONT-STYLE: normal">的的含义是把内存中的对象转换成能够存储到磁盘或者通过网络连接发送的形式。序列化后生成的对象(大多数时候是一种字符串)能被重新转化到原始对象。一个好的序列化系统会自动的转化整个对象体系。Python的</em><tt class="literal"><span class="pre">pickle</span></tt> 模块就是这样一个系统。它得益于这种语言强大的运行期内部处理(译注：instrospection)能力，几乎能序列化任意用户定义的对象。只需要通过加入一些简单 的、非打扰式的处理，这种强大机制就能够扩展到为封装的C++对象工作。下面是一个例子：</p>
<pre class="literal-block">#include &lt;string&gt;struct World{    World(std::string a_msg) : msg(a_msg) {}    std::string greet() const { return msg; }    std::string msg;};</pre>
<pre class="literal-block">#include &lt;boost/python.hpp&gt;using namespace boost::python;struct World_picklers : pickle_suite{  static tuple  getinitargs(World const&amp; w) { return make_tuple(w.greet()); }};</pre>
<pre class="literal-block">BOOST_PYTHON_MODULE(hello){    class_&lt;World&gt;(&quot;World&quot;, init&lt;std::string&gt;())        .def(&quot;greet&quot;, &amp;World::greet)        .def_pickle(World_picklers())    ;}</pre>
<p>现在，我们创建一个<tt class="literal"><span class="pre">World</span></tt> 对象并且把它放在磁盘上休息：</p>
<pre class="literal-block">&gt;&gt;&gt; import hello&gt;&gt;&gt; import pickle&gt;&gt;&gt; a_world = hello.World(&quot;howdy&quot;)&gt;&gt;&gt; pickle.dump(a_world, open(&quot;my_world&quot;, &quot;w&quot;))</pre>
<p>然后，可能是在不同的计算机上不同的操作系统的不同的一个脚本上，我们这样用：</p>
<pre class="literal-block">&gt;&gt;&gt; import pickle&gt;&gt;&gt; resurrected_world = pickle.load(open(&quot;my_world&quot;, &quot;r&quot;))&gt;&gt;&gt; resurrected_world.greet()'howdy'</pre>
<p>当然，使用<tt class="literal"><span class="pre"> cPickle</span></tt> (译注：cPickle是更高效率的一种pickle实现)模块可以更快速的处理。</p>
<p>Boost.Python 的 <tt class="literal"><span class="pre">pickle_suite</span></tt> 完全支持标准Python文档定义的<tt class="literal"><span class="pre">pickle</span></tt> 协议。像Python的__getinitargs__ 函数那样，pickle_suite 的 getinitargs() 函数负责创建argument tuple用以重建pickle过的对象。Python pickling 协议的其他元素， __getstate__ and __setstate__ 可以通过C++ getstate和setstate函数选择提供。C＋＋的静态类型系统允许库确保在编译期避免无意义的函数合并(例如：getstate 却没有 setstate)被应用。</p>
<p>使更复杂的C＋＋对象能够被序列化要比上面的示例需要更多的工作。幸运的是<tt class="literal"><span class="pre">object</span></tt> 接口(查看下一部分)在代码可管理性上非常地有帮助。</p>
</div>
<div class="section" id="object-interface">
<h2><a class="toc-backref" name="object-interface" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id18">Object 接口(Object interface</a>)</h2>
<p>有经验的C语言扩展模块接口作者应该很熟悉<tt class="literal"><span class="pre">PyObject*</span></tt>，手动引用计数(reference-counting)，而且需要记住哪个API返回&quot;新的&quot; (拥有的) 引用或者 &quot;借来的&quot; (raw) 引用。这些限制不仅仅是很麻烦，重要的这也是主要的错误源，特别是在异常的表示(presence of exceptions)上。</p>
<p>Boost.Python提供了一个<tt class="literal"><span class="pre">object</span></tt> <a href="http://www.donevii.com/post/tag/%e7%b1%bb" class="st_tag internal_tag" rel="tag" title="Posts tagged with 类">类</a>，能够自动进行引用计数并且提供从任意C＋＋对象到Python对象的转换。这对于想成为扩展模块作者的人来说，极大的减少了学习困难。</p>
<p>从任何其他类型创建一个<tt class="literal"><span class="pre">object</span></tt> 是非常简单的：</p>
<pre class="literal-block">object s(&quot;hello, world&quot;);  // s manages a Python string</pre>
<p><tt class="literal"><span class="pre">object</span></tt> 可以和所有其他数据类型进行模板化的交互(templated interactions )，并且能够自动完成到python的转换。这些都进行得非常自然以至于它很容易被忽略掉：</p>
<pre class="literal-block">object ten_Os = 10 * s[4]; // -&gt; &quot;oooooooooo&quot;</pre>
<p>在上面的示例里，<tt class="literal"><span class="pre">4</span></tt> 和 <tt class="literal"><span class="pre">10</span></tt> 在进行索引操作和乘法操作调用(indexing and multiplication operations)前，被转化为Python对象。</p>
<p><tt class="literal"><span class="pre">extract&lt;T&gt;</span></tt> class 模板能够用来转换Python对象到C＋＋类型：</p>
<pre class="literal-block">double x = extract&lt;double&gt;(o);</pre>
<p>如果任何一侧的转换不能进行，一个适当的exception将会在运行期被抛出。</p>
<p><tt class="literal"><span class="pre">object</span></tt> 类型与Python内建类型的&lsquo;副本&rsquo;如：<tt class="literal"><span class="pre">list</span></tt>, <tt class="literal"><span class="pre">dict</span></tt>, <tt class="literal"><span class="pre">tuple</span></tt>等等成为一套。这使得从C＋＋转换到这些高阶类型变得方便操作：</p>
<pre class="literal-block">dict d;d[&quot;some&quot;] = &quot;thing&quot;;d[&quot;lucky_number&quot;] = 13;list l = d.keys();</pre>
<p>它的工作方式和看上去的样子几乎和一般的Python代码一样，但是它是纯C＋＋的。当然我们可以封装接受或者返回<tt class="literal"><span class="pre">object</span></tt> 实例的C＋＋函数。</p>
</div>
</div>
<div class="section" id="thinking-hybrid">
<h1><a class="toc-backref" name="thinking-hybrid" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id19">混合地思考(Thinking hybrid</a>)</h1>
<p>由于在组合不同的编程语言时实际上的和心理上的困难，通常在开始先确定单独的一种语言。对于任何应用程序来说，性能上的考虑决定了在核心算法上使用编译语言(compiled language)。不幸的是，由于静态类型系统的复杂性，我们为运行期性能所付出的代价通常在开发期极大的增加。经验显示：相对于开发同等的Python代码来说，写出可维护的C＋＋代码通常需要更长时间和更多努力工作得来的经验。即使当开发者们用编译语言(compiled language)感觉很舒服的时候，他们也常常为他们的系统增加某种类型的脚本层，因为他们的用户可以获得同样的使用脚本语言的好处。</p>
<p>Boost.Python 让我们可以<em>混合地思考</em>。Python可以作为一些应用程序的快速原型；她的易用性和巨大的标准库给了我们到一个工作中的系统的一个开始。如果有必要，这些工作代码可以用来揭示热点比率(译注：意思是发现哪些代码运行最频繁或者占用时间/资源最多)。为了最大化提高性能，那些(热点)可以被C＋＋重新实现，然后用Boost.Python把他们绑定到现有的高阶过程(higher-level procedure)中。</p>
<p>当然，自上而下的过程不是那么吸引人，如果从开始就有许多代码不得不改成用C＋＋实现。幸运的是Boost.Python允许我们应用自下而上的过程。我们曾经应用这种过程非常成功地开发了一个科学软件的工具箱。这个工具箱的开始的时候主要是一个带有Boost.Python绑定的C＋＋类，过了一段时间，成长的部分主要集中在C＋＋的部分。然而由于这个工具箱越来越复杂，越来越多的新特性可以在Python内被实现。</p>
<p><img alt="python_cpp_mix.jpg" src="http://dev.gameres.com/Program/Abstract/python_cpp_mix.jpg" /></p>
<p>This figure shows the estimated ratio of newly added C++ and Python code over time as new algorithms are implemented. We expect this ratio to level out near 70% Python. Being able to solve new problems mostly in Python rather than a more difficult statically typed language is the return on our investment in Boost.Python. The ability to access all of our code from Python allows a broader group of developers to use it in the rapid development of new applications.</p>
</div>
<div class="section" id="development-history">
<h1><a class="toc-backref" name="development-history" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id20">开发历史(Development history</a>)</h1>
<p>The first version of Boost.Python was developed in 2000 by Dave Abrahams at Dragon Systems, where he was privileged to have Tim Peters as a guide to &quot;The Zen of Python&quot;. One of Dave&#8217;s jobs was to develop a Python-based natural language processing system. Since it was eventually going to be targeting embedded hardware, it was always assumed that the compute-intensive core would be rewritten in C++ to optimize speed and memory footprint <a class="footnote-reference" id="id2" name="id2" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#proto"><sup>1</sup></a>. The project also wanted to test all of its C++ code using Python test scripts <a class="footnote-reference" id="id3" name="id3" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#test"><sup>2</sup></a>. The only tool we knew of for binding C++ and Python was <a class="reference" href="http://www.swig.org/">SWIG</a>, and at the time its handling of C++ was weak. It would be false to claim any deep insight into the possible advantages of Boost.Python&#8217;s approach at this point. Dave&#8217;s interest and expertise in fancy C++ template tricks had just reached the point where he could do some real damage, and Boost.Python emerged as it did because it filled a need and because it seemed like a cool thing to try.</p>
<p>This early version was aimed at many of the same basic goals we&#8217;ve described in this paper, differing most-noticeably by having a slightly more cumbersome syntax and by lack of special support for operator overloading, pickling, and component-based development. These last three features were quickly added by Ullrich Koethe and Ralf Grosse-Kunstleve <a class="footnote-reference" id="id4" name="id4" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#feature"><sup>3</sup></a>, and other enthusiastic contributors arrived on the scene to contribute enhancements like support for nested modules and static member functions.</p>
<p>By early 2001 development had stabilized and few new features were being added, however a disturbing new fact came to light: Ralf had begun testing Boost.Python on pre-release versions of a compiler using the <a class="reference" href="http://www.edg.com/">EDG</a> front-end, and the mechanism at the core of Boost.Python responsible for handling conversions between Python and C++ types was failing to compile. As it turned out, we had been exploiting a very common bug in the implementation of all the C++ compilers we had tested. We knew that as C++ compilers rapidly became more standards-compliant, the library would begin failing on more platforms. Unfortunately, because the mechanism was so central to the functioning of the library, fixing the problem looked very difficult.</p>
<p>Fortunately, later that year Lawrence Berkeley and later Lawrence Livermore National labs contracted with <a class="reference" href="http://www.boost-consulting.com/">Boost Consulting</a> for support and development of Boost.Python, and there was a new opportunity to address fundamental issues and ensure a future for the library. A redesign effort began with the low level type conversion architecture, building in standards-compliance and support for component-based development (in contrast to version 1 where conversions had to be explicitly imported and exported across module boundaries). A new analysis of the relationship between the Python and C++ objects was done, resulting in more intuitive handling for C++ lvalues and rvalues.</p>
<p>The emergence of a powerful new type system in Python 2.2 made the choice of whether to maintain compatibility with Python 1.5.2 easy: the opportunity to throw away a great deal of elaborate code for emulating classic Python classes alone was too good to pass up. In addition, Python iterators and descriptors provided crucial and elegant tools for representing similar C++ constructs. The development of the generalized <tt class="literal"><span class="pre">object</span></tt> interface allowed us to further shield C++ programmers from the dangers and syntactic burdens of the Python &#8216;C&#8217; API. A great number of other features including C++ exception translation, improved support for overloaded functions, and most significantly, CallPolicies for handling pointers and references, were added during this period.</p>
<p>In October 2002, version 2 of Boost.Python was released. Development since then has concentrated on improved support for C++ runtime polymorphism and smart pointers. Peter Dimov&#8217;s ingenious <tt class="literal"><span class="pre">boost::shared_ptr</span></tt> design in particular has allowed us to give the hybrid developer a consistent interface for moving objects back and forth across the language barrier without loss of information. At first, we were concerned that the sophistication and complexity of the Boost.Python v2 implementation might discourage contributors, but the emergence of <a class="reference" href="http://www.boost.org/libs/python/pyste">Pyste</a> and several other significant feature contributions have laid those fears to rest. Daily questions on the Python C++-sig and a backlog of desired improvements show that the library is getting used. To us, the future looks bright.</p>
</div>
<div class="section" id="conclusions">
<h1><a class="toc-backref" name="conclusions" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id21">总结(Conclusions</a>)</h1>
<p>Boost.Python achieves seamless interoperability between two rich and complimentary language environments. Because it leverages template metaprogramming to introspect about types and functions, the user never has to learn a third syntax: the interface definitions are written in concise and maintainable C++. Also, the wrapping system doesn&#8217;t have to parse C++ headers or represent the type system: the compiler does that work for us.</p>
<p>Computationally intensive tasks play to the strengths of C++ and are often impossible to implement efficiently in pure Python, while jobs like serialization that are trivial in Python can be very difficult in pure C++. Given the luxury of building a hybrid software system from the ground up, we can approach design with new confidence and power.</p>
</div>
<div class="section" id="citations">
<h1><a class="toc-backref" name="citations" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id22">引用(Citations</a>)</h1>
<table id="veld1995" rules="none" frame="void" class="citation">
<colgroup>
<col class="label"></col>
<col></col>
</colgroup>
<colgroup>
<col></col>
</colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" name="veld1995" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id1">[VELD1995]</a></td>
<td>T. Veldhuizen, &quot;Expression Templates,&quot; C++ Report, Vol. 7 No. 5 June 1995, pp. 26-31. <a class="reference" href="http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html">http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html</a></td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="footnotes">
<h1><a class="toc-backref" name="footnotes" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id23">脚注(Footnotes</a>)</h1>
<table id="proto" rules="none" frame="void" class="footnote">
<colgroup>
<col class="label"></col>
<col></col>
</colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" name="proto" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id2">[1]</a></td>
<td>In retrospect, it seems that &quot;thinking hybrid&quot; from the ground up might have been better for the NLP system: the natural component boundaries defined by the pure python prototype turned out to be inappropriate for getting the desired performance and memory footprint out of the C++ core, which eventually caused some redesign overhead on the Python side when the core was moved to C++.</td>
</tr>
</tbody>
</table>
<table id="test" rules="none" frame="void" class="footnote">
<colgroup>
<col class="label"></col>
<col></col>
</colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" name="test" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id3">[2]</a></td>
<td>We also have some reservations about driving all C++ testing through a Python interface, unless that&#8217;s the only way it will be ultimately used. Any transition across language boundaries with such different object models can inevitably mask bugs.</td>
</tr>
</tbody>
</table>
<table id="feature" rules="none" frame="void" class="footnote">
<colgroup>
<col class="label"></col>
<col></col>
</colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" name="feature" href="http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm#id4">[3]</a></td>
<td>These features were expressed very differently in v1 of Boost.Python</td>
</tr>
</tbody>
</table>
</div>
<div class="section"></div>
<div class="section">转自<a href="http://dev.gameres.com">http://dev.gameres.com</a></div>
<p><!-- </div>
<p> &#8211;></p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/24.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

