2006年4月7日星期五

百度的秘密-关于MP3搜索

  百度的MP3搜索隐藏着一个大多数人都没有注意到的秘密。

  众所周知,在国外法律健全的国家,一个网站如果搞MP3下载,肯定会因为版权纠纷而面临法律的制裁,最终不得不关闭这项服务。

  而在中国这样法律不健全的国家,每个人都知道MP3搜索肯定有很大流量,但做还是不做,对于一家网络企业来说可以有多种选择:

  1、Google的选择,无论美国和中国都不做MP3搜索,不做侵犯知识产权的事情。

  2、Yahoo的选择,在美国不做MP3搜索,但在中国的搜索引擎上做MP3搜索。

  3、百度的选择,宁可和国内唱片公司打官司也要做MP3搜索。

  根据ALEXA的统计显示,百度的MP3搜索流量巨大,成为仅次于常规网页搜索的第二大搜索,占其中流量的16%。因此也不难理解,百度宁可和国内唱片公司打官司也不能不做这种侵犯版权的搜索。

  然而,百度并非是完全肆无忌惮,它还是有所顾忌的,最主要的是害怕被国外的唱片公司指控。因为百度是在美国上市的,美资超过51%的企业,百度知道如果陷入这种法律纠纷会给自己带来什么后果,因此,百度就自作聪明地在MP3搜索上做了一个小伎俩,使得只有中国地用户才能正常使用百度的MP3搜索。

  为了证实这个说法,大家可以做一个简单的试验进行验证:

  先以正常方式在百度的MP3上搜索一首英文歌曲,比如Titanic(电影泰坦尼克号歌曲),则百度搜索出1,460个结果,如下图所示。

  然后在IE里设置一个国外的代理服务器,使得你的IP地址变成国外的IP地址,这时候再上百度搜索一下这首歌,你会发现搜索不到任何歌曲,如下图所示。

  由此我们可以得到一个结论,对于英文歌曲的MP3搜索,只有中国的IP才能进行,使用外国IP无法搜索,百度在对所有外国人进行“信息封锁”。

  当然,不可否认,这种明知故犯的侵犯知识产权的行为,在中国是比比皆是的,这也给中国的对外贸易和国际关系造成严重的不良影响,中美知识产权摩擦不断升级,中国每年约有70%左右的出口企业遭遇到国外技术型贸易壁垒的限制,在这些技术壁垒中,大多与知识产权有关。如果中国的企业不好好保护知识产权的话,美国很可能会采取各种制裁行动,包括阻止某些中国产品进入美国市场,或者向世贸组织提起诉讼。

  然而,百度做为一家知名的上市网络公司,不想着如何减轻政府的负担,却只顾自己赚钱,钻法律的空子,明知故犯地侵犯知识产权,专门给国家和政府制造麻烦,影响中国的国际形象,最终得到的结果是,以美国为首的西方国家每年都不断对中国知识产权保护不力进行指责,使得中国政府在经济和外交上处于一种非常被动的局面,中国企业在走向国际化的道路上也遇到很多不公平的待遇,这些都是我们不想看到的结果。

2006年4月6日星期四

美国电影协会推荐最惊心动魄的100部电影

  美国电影协会(American Film Institute ,AFI )2001年6月12日晚发布了 《AFI 100部最惊心动魄的美国电影》(AFI’s 100 Years…100 Thrills)的名单。 该名单由美国电影界的名流选出,这些人士包括艺术家,影评家和历史专家, 达1400余人。候选电影有四百部,横跨各历史年代,包括各式类型电影。

  1. Psycho (1960) 惊魂记
  2. Jaws (1975) 大白鲨
  3. The Exorcist (1973) 驱魔人
  4. North by Northwest (1959) 谍影疑云
  5. The Silence of the Lambs (1991) 沉默的羔羊
  6. Alien (1979) 异形
  7. The Birds (1963) 群鸟
  8. The French Connection (1971) 法国贩毒网
  9. Rosemary's Baby (1968) 魔鬼怪婴
  10. Raiders of the Lost Ark (1981) 夺宝奇兵
  11. The Godfather (1972) 教父
  12. King Kong (1933) 金刚
  13. Bonnie and Clyde (1967) 雌雄大盗
  14. Rear Window (1954) 后窗
  15. Deliverance (1972) 激流四勇士
  16. Chinatown (1974) 唐人街
  17. The Manchurian Candidate (1962) 谍影迷魂
  18. Vertigo (1958) 迷魂记
  19. The Great Escape (1963) 大逃亡
  20. High Noon (1952) 正午
  21. Clockwork Orange, A (1971) 发条桔子
  22. Taxi Driver (1976) 的士司机
  23. Lawrence of Arabia (1962) 阿拉伯的劳伦斯
  24. Double Indemnity (1944) 双重保险
  25. Titanic (1997) 泰坦尼克
  26. The Maltese Falcon (1941) 枭巢喋血战
  27. Star Wars (1977) 星球大战
  28. Fatal Attraction (1987) 致命的吸引力
  29. The Shining (1980) 闪灵
  30. The Deer Hunter (1978) 猎鹿人
  31. Close Encounters of the Third Kind (1977) 第三类接触
  32. Strangers on a Train (1951) 列车上的陌生人
  33. The Fugitive (1993) 亡命天涯
  34. The Night of the Hunter (1955) 猎人的夜晚
  35. Jurassic Park (1993) 侏罗纪公园
  36. Bullitt (1968) 警网铁金刚
  37. Casablanca (1942) 卡萨布兰卡
  38. Notorious (1946) 美人计
  39. Die Hard (1988) 虎胆龙威
  40. 2001: A Space Odyssey (1968) 2001太空漫游
  41. Dirty Harry (1971) 警探哈里
  42. The Terminator (1984) 终结者
  43. The Wizard of Oz (1939) 绿野仙踪
  44. E.T. the Extra-Terrestrial (1982) 外星人E.T.
  45. Saving Private Ryan (1998) 拯救大兵瑞恩
  46. Carrie (1976) 卡丽
  47. Invasion of the Body Snatchers (1956) 天外魔花
  48. Dial M for Murder (1954) 电话情杀案
  49. Ben-Hur (1959) 宾虚
  50. Marathon Man (1976) 霹雳钻
  51. Raging Bull (1980) 愤怒的公牛
  52. Rocky (1976) 洛奇
  53. Pulp Fiction (1994) 低俗小说
  54. Butch Cassidy and the Sundance Kid (1969) 虎豹小霸王
  55. Wait Until Dark (1967) 盲女惊魂记
  56. Frankenstein (1931) 科学怪人
  57. All the President's Men (1976) 惊天大阴谋
  58. The Bridge on the River Kwai (1957) 桂河大桥
  59. Planet of the Apes (1968) 人猿世界
  60. The Sixth Sense (1999) 灵异第六感
  61. Cape Fear (1962) 海角惊魂
  62. Spartacus (1960) 斯巴达克斯
  63. What Ever Happened to Baby Jane? (1962) 婴儿简出了什么事
  64. Touch of Evil (1958) 历劫佳人
  65. The Dirty Dozen (1967) 十二金刚
  66. The Matrix (1999) 黑客帝国
  67. The Treasure of the Sierra Madre (1948) 碧血金沙
  68. Halloween (1978) 月光光心慌慌
  69. The Wild Bunch (1969) 日落黄沙
  70. Dog Day Afternoon (1975) 炎热的下午
  71. Goldfinger (1964) 金手指
  72. Platoon (1986) 野战排
  73. Laura (1944) 罗娜秘记
  74. Blade Runner (1982) 银翼杀手
  75. The Third Man (1949) 第三者
  76. Thelma & Louise (1991) 末路狂花
  77. Terminator 2: Judgment Day (1991) 终结者 2
  78. Gaslight (1944) 煤气灯下
  79. The Magnificent Seven (1960) 七侠荡寇志
  80. Rebecca (1940) 蝴蝶梦
  81. The Omen (1976) 天魔
  82. The Day the Earth Stood Still (1951) 地球停顿记
  83. The Phantom of the Opera (1925) 歌剧魅影
  84. Poltergeist (1982) 吵闹鬼
  85. Dracula (1931/I) 吸血鬼
  86. The Picture of Dorian Gray (1945) 格雷的画像
  87. The Thing From Another World (1951) 魔星下凡
  88. 12 Angry Men (1957) 十二怒汉
  89. The Guns of Navarone (1961) 纳瓦隆大炮
  90. The Poseidon Adventure (1972) 海神号遇险记
  91. Braveheart (1995) 勇敢的心
  92. Body Heat (1981) 体热
  93. Night of the Living Dead (1968) 恶夜活跳尸
  94. The China Syndrome (1979) 中国综合症
  95. Full Metal Jacket (1987) 全金属外壳
  96. Blue Velvet (1986) 蓝色夜合花
  97. Safety Last! (1923) 最后安全
  98. Blood Simple. (1984) 血迷宫
  99. Speed (1994) 生死时速
  100. The Adventures of Robin Hood (1938) 罗宾汉历险记

美国电影协会推荐最惊心动魄的100部电影

  来源:美国电影协会(American Film Institute

2006年4月4日星期二

Perl、PHP、ASP、JSP技术比较

  本文将对目前最常用的四种动态网页语言Perl(Practical Extraction and Report Language)、PHP(Hypertext Preprocessor)、ASP(Active Server Pages)、JSP(JavaServer Pages)进行一些技术性的比较。

  Perl

  Perl(Practical Extraction and Report Language)是一种很古老的脚本语言。最初的Web应用大多是用Perl编写的,Perl很像C语言,使用非常灵活,对于文件操作和处理具有和C语言一样的方便快捷。

  也正是因为Perl的灵活性和“过度”的冗余语法,也因此导致许多Perl程序的代码令人难以阅读和维护,因此使用的人在逐渐减少,并且目前有被Python替代的可能。

  另外Perl对于CPU的消耗似乎较高,效率似乎有一些不足。

  Perl开发的成功案例:

  Movable Type — 世界上使用最多的Blog系统之一,功能强大的足以和一个CMS系统相比拟。

  Awstats — 非常经典的日志系统,速度极快,功能也非常强大。

  结论:Perl在部分应用中能发挥很大优势,但其维护性差使得其普及变得很困难。

  PHP

  PHP(Hypertext Preprocessor)是一种嵌入HTML页面中的脚本语言。它大量地借用C和Perl语言的语法, 并结合PHP自己的特性,使Web开发者能够快速地写出动态产生页面。

  PHP是完全免费的开源产品,不用花钱,Apache和MYSQL也是用样免费开源,在国外非常流行,PHP和MYSQL搭配使用,可以非常快速的搭建一套不错的动态网站系统,因此国外大多数主机系统都配有免费的APACHE+PHP+MYSQL。通常认为这种搭配的执行效率比IIS+ASP+ACCESS要高,而后者的使用还必须另外交钱给微软。

  PHP的语法和Perl很相似,但是PHP所包含的函数却远远多于Perl,PHP没有命名空间,编程时候必须努力避免模块的名称冲突。一个开源的语言虽然需要简单的语法和丰富的函数,但PHP内部结构的天生缺陷导致了PHP不适合于编写比中小型业余网站更大的网站。

  PHP开发的成功案例:

  MediaWiki — 著名的维基百科(Wiki)程序,如此庞大的条目居然只用PHP+MYSQL就能够支持,真是不可思议。

  WordPress — 著名的Blog系统,功能上丝毫不输于Movable Type,不少用户都纷纷从Movable Type转移到了WordPress。

  结论:PHP语法简单,非常易学易用,很利于快速开发各种功能不同的定制网站,PHP因为结构上的缺陷,使的PHP在复杂的大型项目上的开发和维护都比较困难。

  ASP

   ASP(Active Server Pages)微软的Windows IIS系统自带的脚本语言,利用它可以执行动态的Web服务应用程序。ASP的语法非常类似Visual BASIC,学过VB的人可以很快上手,ASP也是这几种脚本语言中最简单易学的开发语言。但ASP也是这几种语言中唯一的一个不能很好支持跨平台的语言。

  因为ASP脚本语言非常简单,因此其代码也简单易懂,结合HTML代码,可快速地完成网站的应用程序。

  ASP在国内异常流行,因为国内大多使用的是盗版的Windows和盗版的SQLServer,而ASP+COM+SQLServer实际上也是一种不错的搭配,其性能也不输于PHP+MYSQL,特别是Windows系统和SQLServer都有图形界面,比APACHE和MYSQL易于维护,因此对于不重视知识产权的国家来说也是一种不错的选择。

  不过,正因为ASP很简单,所以单纯使用ASP所能完成的功能也是有限的,好在COM(Component Object Model)技术拯救了ASP,微软提供了COM/DCOM技术,极大拓宽了ASP的应用范围,使得ASP几乎具有无限可扩充性。

  结论:和PHP一样,ASP简单而易于维护,很适合小型网站应用,通过DCOM和MTS技术,ASP甚至还可以完成小规模的企业应用,但ASP的致命缺点就是不支持跨平台的系统,在大型项目开发和维护上非常困难。

  JSP

  JSP(JavaServer Pages)是Sun公司推出的一种动态网页技术。JSP技术是以Java语言作为脚本语言的,熟悉JAVA语言的人可以很快上手。

  JSP本身虽然也是脚本语言,但是却和PHP、ASP有着本质的区别。PHP和ASP都是由语言引擎解释执行程序代码,而JSP代码却被编译成Servlet并由Java虚拟机执行,这种编译操作仅在对JSP页面的第一次请求时发生。因此普遍认为JSP的执行效率比PHP和ASP都高。

  JSP是一种服务器端的脚本语言,最大的好处就是开发效率较高,JSP可以使用JavaBeans或者EJB(Enterprise JavaBeans)来执行应用程序所要求的更为复杂的处理,但是这种网站架构因为其业务规则代码与页面代码混为一团,不利于维护,因此并不适应大型应用的要求,取而代之的是基于MVC的Web架构。MVC的核心思想是将应用分为模型、视图和控制器三部分。模型是指应用程序的数据,以及对这些数据的操作;视图是指用户界面;控制器负责用户界面和程序数据之间的同步。通过MVC的Web架构,可以弱化各个部分的耦合关系,并将业务逻辑处理与页面以及数据分离开来,这样当其中一个模块的代码发生改变时,并不影响其他模块的正常运行,所以基于MVC的Web架构更适应于大型应用开发的潮流。

  因此,不少国外的大型企业系统和商务系统都使用以上的MVC架构,能够支持高度复杂的基于Web的大型应用。

  结论:JSP对于网站开发来讲不像PHP和ASP那样易学易用,支持JAVA的主机也少于支持PHP的主机,这从一定程度上限制了Java技术在网站上的发展,不过在企业软件应用上来讲,MVC还是拥有相当大的优势的,虽然其配置和部署相对其他脚本语言来说要复杂一些,但对于跨平台的中大型企业应用系统来讲,基于JAVA技术的MVC架构几乎成为唯一的选择。

2006年4月3日星期一

深圳人均GDP之谜

  深圳多年来一直是人均GDP最高的中国城市,但其GDP到底是多少,却有几个不同的说法。

  2004年,深圳全市GDP达到3422亿元(第一次全国经济普查后修改为4282亿),人均GDP为7000美元,官方公布的深圳市年末常住人口597万。

  2005年,深圳GDP为4926亿元,全年经济增长速度为15%,这是一个基本准确的数字,但2005年深圳有多少人口呢?

  深圳常住人口有多少?这是一个谜。金心异曾经写过一篇专门的文章《深圳人口之谜》,按照2000年中国第五次全国人口普查,深圳市总人口为700万人。但是深圳官方政府却一直按照自己的数据进行统计深圳的总人口:2001年底深圳常住人口468万人,其中户籍人口132万人。两者数据竟然相差了高达200多万。

  深圳政府统计的人口包括户籍人口与暂住人口之和,暂住人口只计算了办了暂住证的人口,没有办理暂住证的没有计算,相信这200多万就是没有办理暂住证的人口。

  以错误的人口数据计算出来的人均GDP当然是错误的,很多地方(包括英文的维基百科)都引用了一个错误的数据-深圳2001年人均GDP为136,071人民币(16,430美元),这显然是一个荒谬的数据,16,430美元?这意味着2001年深圳的人均GDP就超过了韩国和台湾,并直逼香港和新加坡了,可能吗?当然不可能,这个数据显然是将深圳GDP除以一百多万户籍人口得到的这个夸张的数据,不过之后的深圳政府似乎就不再使用户籍人口做为数据统计了。

  根据深圳官方的数据,深圳市2004年年末常住人口597万,这个人口数据应该比深圳的实际人口数字少。2005年广东和中央对深圳的人口数据进行了调整,在2005年11月份,广东省公布的数据中就提到深圳的常住人口为827万,据称“省里和北京(中央)就认这个数”,可见深圳调整常住人口数据并非完全主动,也是被迫的。不过827万这个数字应该和深圳实际人口比较接近。

  目前深圳官方已经确认2005年末深圳人口是827万,并且今后深圳常住人口将按这个口径对外公布,各类经济指标的测算也以此为依据。

  因此用这个人口数字,计算出来的深圳2005年人均GDP为7300美元。人均可支配收入21000多元人民币,比上年增长8.7%。

  当然,深圳政府对于经济的发展是雄心勃勃的,并制定了目标,2010年人均GDP要达到1.2万美元。

  如果只是从数据上看,只要年均增长超过13%,的确可以达到这个目标,并且可以预计深圳将在2008年,成为人均GDP首次超过1万美元的中国内地城市。广州和上海也预计将在2010年达到人均GDP超过1万美元的目标。

  人均GDP超过1万美元是一道门槛,这意味着什么呢?

  按照世界银行的衡量标准,人均GDP超过1万美元是公认的从发展中状态进入发达状态的标志线。日本人均GDP是在1984年超过了1万美元,香港、新加坡、台湾和韩国的人均GDP分别是在1987年、1989年、1992年和1995年超过了1万美元。也就是说,2年之后,深圳人终于可以和24年前的日本人一样进入“发达地区”的状态了。

  2005年日本的人均GDP是36,486美元,这大概是个难以逾越的数字了,而整个中国2005年的人均DGP为1703美元,不知道什么时候中国人能够达到日本目前的这个数字。

  附录:2005年世界人均GDP排名(美元)

  1 卢森堡 69,056
  2 挪威 53,465
  3 瑞士 49,246
  4 爱尔兰 46,335
  5 丹麦 45,015
  6 冰岛 44,133
  7 美国 42,076
  8 瑞典 38,451
  9 英国 36,977
  10 日本 36,486
  11 奥地利 35,861
  12 荷兰 35,393
  13 芬兰 35,242
  14 比利时 34,081
  15 卡塔尔 33,586
  16 法国 33,126
  17 德国 33,099
  18 加拿大 32,073
  19 澳洲 29,761
  20 意大利 29,648
  21 新加坡 25,176
  22 西班牙 24,627
  23 香港 24,581
  24 新西兰 23,276
  25 阿拉伯联合酋长国 20,960
  26 科威特 19,288
  27 塞浦路斯 19,008
  28 希腊 18,995
  29 巴哈马 18,190
  30 斯洛文尼亚 17,660
  31 荷兰属地 17,435
  32 以色列 16,987
  33 葡萄牙 16,658
  34 韩国 14,649
  35 汶莱 14,366
  36 台湾 13,926
  37 巴林 13,764
  38 马耳他 13,144
  39 安提瓜和巴布达 11,790
  40 匈牙利 10,896
  41 沙特阿拉伯 10,795
  42 巴布达 10,747
  43 捷克 10,708
  44 阿曼 10,292
  45 特立尼达和多巴哥 10,117
  46 塞舌尔群岛 8,892
  47 爱沙尼亚 8,885
  48 圣基茨和尼维斯 8,546
  49 斯洛伐克 7,963
  50 克罗地亚 7,764
  51 立陶宛 6,796
  52 墨西哥 6,566
  53 波兰 6,373
  54 赤道几内亚 6,235
  55 拉脱维亚 6,150
  56 智利 5,742
  57 博茨瓦纳 5,713
  58 黎巴嫩 5,434
  59 毛里求斯 5,421
  60 利比亚 5,317
  61 加蓬 4,911
  62 巴拿马 4,806
  63 俄国 4,750
  64 马来西亚 4,701
  65 格林那达 4,692
  66 土耳其 4,637
  67 格斯达里加 4,484
  68 阿根廷 4,132
  69 伯利兹 4,120
  70 圣卢西亚岛 4,095
  71 委内瑞拉 4,014
  72 南非 3,886
  73 乌拉圭 3,874
  74 多米尼加 3,772
  75 圣文森特和格林纳丁斯 3,719
  76 保加利亚 3,325
  77 巴西 3,311
  78 罗马尼亚 3,277
  79 卡扎克斯坦 3,185
  80 突尼斯 3,052
  81 牙买加 3,003
  82 白俄罗斯 2,992
  83 塞尔维亚和黑山共和国 2,820
  84 泰国 2,807
  85 苏里南 2,785
  86 土库曼 2,784
  87 伊朗 2,608
  88 阿尔及利亚 2,601
  89 马其顿共和国 2,570
  90 阿尔巴尼亚 2,434
  91 秘鲁 2,379
  92 马尔代夫 2,355
  93 纳米比亚 2,333
  94 汤加 2,226
  95 斐济 2,199
  96 厄瓜多尔 2,168
  97 波斯尼亚和黑塞哥维那 2,167
  98 佛得角 2,161
  99 哥伦比亚 2,119
  100 萨尔瓦多 2,063
  101 斯威士兰 2,043
  102 多米尼加共和国 2,014
  103 乔丹 1,988
  104 危地马拉 1,966
  105 萨摩亚 1,821
  106 中华人民共和国 1,703
  107 乌克兰 1,589
  108 安哥拉 1,580
  109 摩洛哥 1,576
  110 瓦努阿图 1,440
  111 刚果共和国 1,401
  112 叙利亚 1,386
  113 阿塞拜疆 1,237
  114 巴拉圭 1,170
  115 玻利维亚 1,137
  116 埃及 1,118
  117 印度尼西亚 1,093
  118 菲律宾 1,084
  119 洪都拉斯 1,062
  120 斯里南卡 1,052
  121 圭亚那 1,035
  122 佐治亚 927
  123 亚美尼亚 868
  124 卡麦隆 860
  125 象牙海岸 859
  126 不丹 859
  127 吉布提 822
  128 尼加拉瓜 794
  129 基里巴斯 768
  130 塞内加尔 745
  131 摩尔多瓦 665
  132 巴布亚新几内亚 660
  133 印度 652
  134 海地 650
  135 苏丹 643
  136 比宁 583
  137 巴基斯坦 577
  138 乍得 567
  139 科摩罗 554
  140 也门 553
  141 蒙古 547
  142 莱索托 546
  143 所罗门群岛 534
  144 越南 528
  145 尼日利亚 528
  146 肯尼亚 489
  147 赞比亚 461
  148 毛里塔尼亚 452
  149 加纳 451
  150 马里 435
  151 布基纳法索 424
  152 老挝 421
  153 孟加拉国 418
  154 吉尔吉斯斯坦 413
  155 东帝汶 400
  156 乌兹别克斯坦 376
  157 基尼 375
  158 圣多美及普林西比 372
  159 多哥 357
  160 中非共和国 356
  161 柬埔寨 327
  162 坦桑尼亚 323
  163 乌干达 296
  164 莫桑比克 294
  165 冈比亚 284
  166 津巴布韦 277
  167 塔吉克斯坦 275
  168 尼日尔 273
  169 马达加斯加 263
  170 尼泊尔 246
  171 塞阿里昂 207
  172 几内亚比绍 204
  173 卢旺达 189
  174 马拉维 174
  175 厄立特里亚 157
  176 缅甸 135
  177 民主党刚果共和国 122
  178 埃塞俄比亚 121
  179 布隆迪 103

  2005年GDP总量排名(按名义汇率计算) 单位:百万美元
  
  来源:国际货币基金组织,世界经济前景数据库。
  
  1 美国 12,486,624
  2 日本 4,663,823
  3 德国 2,730,109
  4 英国 2,227,551
  5 法国 2,054,880
  6 中华人民共和国 1,772,724
  7 意大利 1,709,668
  8 加拿大 1,034,532
  9 西班牙 1,019,024
  10 印度 719,819
  11 韩国 714,219
  12 墨西哥 692,961
  13 俄国 671,815
  14 澳洲 612,800
  15 巴西 587,784
  16 荷兰 581,318
  17 瑞士 366,986
  18 比利时 350,326
  19 瑞典 348,137
  20 土耳其 332,546
  21 台湾 323,410
  22 奥地利 293,407
  23 沙特阿拉伯 264,010
  24 挪威 246,873
  25 波兰 246,213
  26 印度尼西亚 245,073
  27 丹麦 243,398
  28 希腊 209,712
  29 爱尔兰 188,367
  30 南非 187,339
  31 芬兰 184,231
  32 泰国 183,868
  33 伊朗 181,187
  34 香港 172,615
  35 葡萄牙 170,297
  36 阿根廷 161,899
  37 马来西亚 122,005
  38 以色列 114,313
  39 新加坡 110,596
  40 捷克 109,411
  41 匈牙利 106,351
  42 委内瑞拉 106,098
  43 阿拉伯联合酋长国 98,099
  44 哥伦比亚 97,730
  45 新西兰 94,604
  46 智利 93,470
  47 菲律宾 91,356
  48 巴基斯坦 89,551
  49 阿尔及利亚 85,306
  50 埃及 78,105
  51 尼日利亚 77,325
  52 乌克兰 75,143
  53 罗马尼亚 72,697
  54 秘鲁 69,808
  55 孟加拉国 63,557
  56 科威特 52,756
  57 摩洛哥 51,944
  58 卡扎克斯坦 47,388
  59 越南 43,749
  60 斯洛伐克 43,068
  61 斯洛文尼亚 35,213
  62 克罗地亚 34,940
  63 卢森堡 31,763
  64 利比亚 31,488
  65 突尼斯 30,936
  66 厄瓜多尔 30,700
  67 卡塔尔 28,065
  68 危地马拉 26,978
  69 叙利亚 25,839
  70 保加利亚 25,788
  71 白俄罗斯 25,779
  72 阿曼 24,979
  73 安哥拉 24,349
  74 塞尔维亚和黑山共和国 23,550
  75 立陶宛 23,504
  76 苏丹 22,747
  77 斯里南卡 21,620
  78 黎巴嫩 20,699
  79 格斯达里加 19,375
  80 多米尼加共和国 18,151
  81 象牙海岸 16,574
  82 肯尼亚 16,106
  83 塞浦路斯 15,400
  84 卡麦隆 15,352
  85 巴拿马 14,893
  86 拉脱维亚 14,426
  87 也门 14,339
  88 萨尔瓦多 14,212
  89 土库曼 13,988
  90 乌拉圭 13,244
  91 冰岛 13,045
  92 特立尼达和多巴哥 13,023
  93 爱沙尼亚 12,194
  94 坦桑尼亚 12,123
  95 乔丹 11,507
  96 巴林 11,010
  97 阿塞拜疆 10,404
  98 乌兹别克斯坦 9,860
  99 玻利维亚 9,657
  100 加纳 9,413
  101 博茨瓦纳 9,046
  102 埃塞俄比亚 8,819
  103 阿尔巴尼亚 8,657
  104 波斯尼亚和黑塞哥维那 8,495
  105 牙买加 8,155
  106 塞内加尔 7,972
  107 乌干达 7,909
  108 洪都拉斯 7,812
  109 缅甸 7,464
  110 刚果民主党共和国 7,328
  111 巴拉圭 7,281
  112 赤道几内亚 6,850
  113 加蓬 6,697
  114 毛里求斯 6,681
  115 尼泊尔 6,655
  116 巴哈马 5,783
  117 莫桑比克 5,727
  118 海地 5,680
  119 马里 5,434
  120 布基纳法索 5,405
  121 汶莱 5,357
  122 赞比亚 5,351
  123 马其顿共和国 5,304
  124 马耳他 5,193
  125 纳米比亚 4,976
  126 乍得 4,799
  127 佐治亚 4,737
  128 柬埔寨 4,729
  129 马达加斯加 4,719
  130 刚果共和国 4,694
  131 尼加拉瓜 4,587
  132 比宁 4,340
  133 巴布亚新几内亚 3,924
  134 基尼 3,576
  135 尼日尔 3,432
  136 亚美尼亚 3,307
  137 津巴布韦 3,207
  138 荷兰属地 3,063
  139 巴布达 2,964
  140 老挝 2,523
  141 摩尔多瓦 2,416
  142 吉尔吉斯斯坦 2,144
  143 斯威士兰 2,117
  144 多哥 1,999
  145 马拉维 1,984
  146 斐济 1,937
  147 塔吉克斯坦 1,887
  148 卢旺达 1,817
  149 中非共和国 1,462
  150 蒙古 1,400
  151 莱索托 1,362
  152 毛里塔尼亚 1,346
  153 苏里南 1,300
  154 塞阿里昂 1,128
  155 伯利兹 1,104
  156 佛得角 1,029
  157 安提瓜和巴布达 803
  158 马尔代夫 788
  159 圭亚那 782
  160 不丹 751
  161 塞舌尔群岛 745
  162 圣卢西亚岛 731
  163 布隆迪 730
  164 厄立特里亚 729
  165 吉布提 708
  166 格林那达 481
  167 冈比亚 429
  168 圣基茨和尼维斯 419
  169 圣文森特和格林纳丁斯 418
  170 科摩罗 359
  171 萨摩亚 334
  172 东帝汶 332
  173 瓦努阿图 314
  174 几内亚比绍 280
  175 多米尼加 270
  176 所罗门群岛 257
  177 汤加 227
  178 基里巴斯 72
  179 圣多美及普林西比 62
 

2006年4月2日星期日

深圳梅林水库后山游

  今天和同事一起去梅林水库爬山。

  我们大约1点半从梅林家乐福出发,不久就到了梅林水库门口。

  接着是一路上山,开始的路还可以,但很快我发现道路越来越难走。

  从半山腰可以俯瞰梅林的全景,景象还是挺好看的。

  道路已经比较难走了,很少见到有登山的水泥阶梯,也没有任何围栏,林间的树木看起来有些诡异,一个人走到这里的话还是慢有些紧张的。

  山路已经变得崎岖陡峭了,特别是从一座山爬到另一座山,下山的道路很惊险。

  这样的路走了很长,累得我们半死,带再身上的2瓶水都喝完了,山路似乎越走越长,越来越难走,不知道走了多长时间,终于看到好走的石子道路了,我们似乎感觉到这次可怕的爬山历程终于快要结束了。

  口渴的不行了,水却没有了,我感觉我嗓子眼快要冒烟了,突然前方发现了一处山泉,我们像发现新大陆一样,赶快冲上去。

  山泉的水看起来很干净,喝起来很冰冷,我一下连喝了2瓶水,实在太爽了。

  终于快到山口了,而时间已经接近6点半了,我们几乎爬了5个小时的山,对于我这种平时缺少锻炼的人来说,实在太累了。

  这时太阳已经快下山了,夕阳将云霞染的通红,看起来很壮观。

  我们坐在水库上,看着太阳下山。然后就去吃饭回家。

  这次的经验教训:水带的太少,应该在天气凉爽的时候爬这么长的山,爬山最好量力而行,这次爬的山实在路程太长了。

2006年4月1日星期六

微软卫星地图

  微软终于也耐不住寂寞,推出了Beta版的微软卫星地图(Windows Live Local),用以对抗日益强大的Google卫星地图

  这是微软在本地搜索与地图服务方面对Google的一次反击。去年年初,Google推出了自己的卫星地图服务,在业界可算风头出尽,并且引起了世界各国军方和政府的关注。

  微软于是也不甘落后,推出了新版的Windows Live Local微软地图),其实也是基於地理资讯服务的一个地图查询系统。新版的微软地图美化了界面,显得比以前漂亮了不少,另外,地图界面也显得更加详实,清晰。

  值得注意的是,微软的这个地图不仅仅是卫星图片,还增加了鸟瞰的功能,图片数据据说来源于高清晰航拍照片,这样微软地球就能够提供比Google Earth更高解析度和更高品质的图像。用户可以把图像放的更大,可以旋转视图从东西南北4各不同方向观看地貌。这些航空照片品质非常高,解析度已经小於0.1米,视角高度距地面最小近约23米(25yds),也就如同站在20多米的楼顶看地面的效果,立体感的效果是卫星照片无法比拟的。

自由女神像鸟瞰图,清晰地令人震惊

纽约曼哈顿岛的一角,汽车和行人都依稀可见

  然而,这些鸟瞰图片是不连贯的,仅仅也覆盖了美国主要的地址,没有中国的鸟瞰图(估计中国政府也不会让微软去拍),中国的卫星图片的解析度也很低,不如Google的卫星图片,可以说,对于中国用户来说用处还是不大的。

  这种鸟瞰图的成本一定很高,微软为了和Google竞争也是花了血本了。希望微软也推出类似Google Earth的客户端软件,那样用起鸟瞰功能可能会感觉好一些,速度应该也会快一些。

  微软地图的地址是:http://local.live.com

2006年3月31日星期五

计算机病毒的通用清除技术

  这篇文章是我十年前写的第二篇在杂志上发表的文章。发表在微电脑世界1997年的第三期上。

  那个年代我对计算机病毒也非常感兴趣。在九二年我刚上大学时候,对计算机病毒其实一点概念也没有,只是感觉计算机病毒是很神秘很高深的东西。对于病毒程序能够在不同电脑之间传播,那时感觉很不可思议。

  那的确是个很古老的时代,我们用的操作系统是DOS 3.31,学的是TRUE BASIC,电脑是33M主频的PC/AT,286是当时最先进的机器。那时候的电脑病毒也很有意思,比如小球病毒,就是一个活蹦乱跳的小圆点,不停地运动,当碰到屏幕边沿就立刻反弹。雨点病毒则是一些下落的雨点或字符。64/Bloody病毒则是在屏幕上显示血红的Bloody文字。

  计算机系的大学老师们对病毒其实也很感兴趣,记得一个老师曾经指着小球病毒的汇编代码跟我们说:整个中国会编这个病毒的人不超过10个。

  最开始的病毒破坏力都很小,在现在看来,甚至有些可爱。我估计都是一些高手在编写病毒,写病毒的目的大概是为了炫耀自己的编程能力。DOS病毒几乎全是用汇编写的代码,汇编语言其实和二进制机器语言差不多,用那个东西写程序可真是一场噩梦啊,我曾经写过一个八百多行的汇编程序,写的我头晕脑涨,我知道,用汇编来写一个病毒的确不是一件容易的事情,特别是一些病毒甚至还有自身加密、变种的功能,因此,那些人也的确值得炫耀一下的。不过现在,汇编语言我都快忘光了,原因很简单,用机器代码写程序的可维护性很差,自然用的人也肯定会越来越少。

  大学毕业后的几年,我逐渐对这些失去了兴趣,主要因为一些计算机业的害群之马影响了我的心情,CIH病毒开了一个恶劣的开头,对电脑用户的资料信息甚至硬件进行恶性破坏,而后的病毒似乎在比谁更不要脸,现在互联网的普及,以及一些脚本语言的流行,编写木马病毒门槛非常低了,菜鸟都可以写木马病毒了,而现在的木马病毒清一色全是恶性病毒,不是偷密码、弹广告就是改IE,甚至还出了HAO123这样依靠木马病毒发家的“成功案例”,但这些病毒的编写目的都令我感到恶心,对于那些低劣的病毒编写者,我只觉得他们可怜,让他们继续为了他们那低劣的理想和愿望而编写病毒吧,我还有更重要的事情要做呢。

  下面是我写的论文,其目前已经没有实际意义,因为外部环境发生了巨大变化,我写那篇论文的前提是“计算机病毒大部分不是恶性病毒”的基础上,甚至执行病毒代码来还原恢复原始程序,现在的环境下这已经不可能了,现在是什么世道?谁敢运行病毒啊!

 

计算机病毒的通用清除技术

 

摘要   本文就当前流行的文件型病毒出发,分析介绍了从文件结构特性入手清除计算机病毒的一种技术.

关键字   病毒  传染  加载执行(EXEC)  文件前缀段(PSP)  进程

 

第一章  引言

   计算机病毒的发展历史悠久,从80年代中后期广泛传播开来.时至今日,据统计世界上已存在的计算机病毒有5000余种,并且每月以平均几十种的速度增加.计算机病毒的发展一定程度上影响了反病毒产品的发展,原有的反病毒技术在新型病毒面前显得陈旧而无能为力.病毒检测产品是以病毒的特征码为基础的针对具体病毒的判断技术,因此,病毒的变种以及未知病毒给检测软件带来较大的困难.病毒的清除是建立在病毒检测的基础上,目前病毒的清除实际上是针对已知病毒.这种被动式的方法使反病毒技术总是落后于病毒技术,虽然这类反病毒产品对病毒的抑制是不容忽视的,但它所暴露出来的漏洞却越来越多.新一代的开放式反病毒技术应运而生,这种开放式反病毒技术将病毒的结构用一个统一的数据结构加以描述,用户可以根据自身对病毒进行分析,并具有更加灵活的升级优势,对于新一代具有反跟踪,加密技术的多维变异病毒,这种方法显示出其灵活及高效的特色,这种广谱型的查毒杀毒系统将逐渐成为反病毒产品的发展趋势.

   下面,本文将介绍一种基于可执行文件结构特性的通用杀毒技术.

第二章 计算机病毒的机理

   首先,我们先了解一下计算机病毒的结构特点以及其工作原理.

   计算机病毒的结构决定了计算机病毒的特点,大致归纳如下:

   (1) 计算机病毒是一段可执行的程序

   计算机病毒和其它合法程序一样,是一种可存储可执行的非法程序,它可以直接或间接地运行,可以隐蔽在可执行程序和数据文件中而不易被人们察觉和发现.在病毒程序运行时,其与合法程序争夺系统的控制权.

   (2) 计算机病毒的广泛传染性

   由于病毒一词来源于“生物学”,传染也相应成为计算机病毒的一个重要特性.传染性是衡量一种程序是否为病毒的首要条件.计算机病毒的传染性是计算机病毒的再生机制,病毒程序一旦进入系统与系统中的程序接在一起,它就会在运行这一被传染的程序之后开始传染其它程序.这样一来,病毒就会很快地传染到整个计算机系统.

   (3) 计算机病毒的潜伏性

   计算机病毒的潜伏性是具有依附于其它媒体而寄生的能力.一个编制巧妙的计算机病毒程序,可以在几周或者几个月甚至几年内隐藏在合法文件之中,对其它系统进行传染,而不被人们发现.计算机病毒的潜伏性于传染性相辅相成,潜伏性越好,其在系统中存在的时间就会越长,病毒的传染范围也就会越大.

   (4) 计算机病毒的可触发性

   计算机病毒一般都有一个触发条件:或者触发其传染,或者在一定条件下激活计算机病毒的表现部分或破坏部分.触发实质上是一种条件控制,一个病毒程序可以按照设计者的要求,在某个点上激活并对系统发起攻击.

   (5) 计算机病毒的针对性

   现在世界上出现的计算机病毒,并不是对所有计算机系统都进行传染的.例如,有针对IBM PC及其兼容机的,有针对APPLE公司的Macintosh的以及针对Unix操作系统的.现在流行的绝大多数计算机病毒都是针对基于MS DOS系统的IBM PC及其兼容机的.

   (6) 计算机病毒的衍生性

   由于计算机病毒本身是一段计算机系统可执行的文件(程序),所以这种程序反映了设计者的一种设计思想.同时,又由于计算机病毒本身也是由几部分组成的,如安装部分,传染部分和破坏部分等,因此这些模块很容易被病毒本身或其它模仿者所修改,使之成为一种不同于原病毒的计算机病毒.[1]

   计算机病毒按链接方式可分为以下几类:

   (1)源码型病毒 (Source Code Virus) (2)入侵型病毒 (Intrusive Virus) (3)操作系统病毒 (Operating System Virus)  (4)外壳型病毒 (Shell Virus).

   (1)(2)攻击的是高级语言编写的源文件及目标文件,在微机上很少见, (3)即引导区病毒,主要攻击计算机的Boot区,其诊治方法较为简单,一般用DEBUG或NU等工具就能方便地清除.本文所提的病毒专指目前在PC在机上流行最广的攻击可执行文件的外壳型病毒.

   计算机外壳型病毒是将其自己包围在主程序的四周,对原来的程序不作修改.外壳型病毒易于编写,也较为常见,但诊治却较为麻烦.

   外壳型病毒具有以下特点:

   自身复制在目标文件外围(即文件尾部);不修改原来正常文件[2];运行时病毒抢先进入内存.病毒执行完后,转回原文件入口运行(隐蔽性).

   在基于DOS操作系统PC机上,外壳型病毒主要攻击的目标是两类可执行文件:COM文件与EXE文件.COM文件结构比较简单,解毒比较容易.而广泛流行的EXE文件相对复杂,但操作却更灵活,适合于超过64K的程序,更易与将来的操作系统兼容,因此得到广泛的使用.

第三章 COM病毒的清除

一  实现原理

   COM文件是DOS的一种二进制代码的可执行文件,COM文件结构比较简单,加载过程十分迅速.整个程序只有一个段.因此全部代码长度必须小于64K,其入口代码地址是CS:100H. DOS装入COM文件时,先在内存建立一个长度为100H的程序前缀段(PSP,由DOS建立,是DOS用户程序和命令行之间的接口),然后将整个文件装载于PSP上端,不进行重定位操作,接着将四个段地址寄存器DS(Data Segment),CS(Code Segment),SS(Stack Segment),ES(Extra Segment)初始化为程序前缀段(PSP)的段地址,最后将程序的控制权交于CS:100H处.如表1所示.

                表1:  COM文件的装入执行

地址 内容  
XXXX:0000 PSP ← CS,DS,ES,SS
XXXX:0100 程序代码 ← IP
  数据  
  堆栈 ← SP

   寄生于COM文件的病毒,大部分是采用保存文件头若干字节,并将第一条指令改为”JMP 病毒入口”,以确保病毒最先执行,也有部分病毒附加在文件首部,病毒执行完后恢复寄生程序原先的状态,并用JMP FAR等指令使程序再次回到CS:100H处,以确保寄生程序与PSP的一致.

   可见,病毒执行完后,必将会恢复并运行原文件,以便传播,当其将原文件参数全部恢复后,会将控制权交于CS:100H处.因此,判别COM文件的真正入口的标准是:最后一次在CS:100H处执行的程序段(CS=当前PSP段地址,IP=100H).

   于是,可以设想出这样一种跟踪器,每执行一条指令,便判断上述条件是否满足,如果满足,则此时CS:100H处的代码便是原文件的影像,由于COM文件只有一个段,因此此时内存的影像既是磁盘文件的内容.将CS:100H处的代码写回原文件,此病毒即被消除了,如果知道病毒的长度,还可将文件尾的无用代码去掉,这样病毒就物理上消除了.

二  实现方案

   设想的跟踪器的实现是核心问题,也是主要的难点.事实上单步陷阱中断(INT 1)完全符合跟踪器的条件,但由于目前的计算机病毒广泛采取破坏单步断点的技术,因此这种跟踪器在具体实现上还有一定难度.

   目前有一种比较方便的替代方法,即DOS的EXEC(INT 21H的功能4BH,加载执行)功能,此功能有一个有趣的现象,即执行完加载程序后,它会将所有寄存器恢复到执行前的状态,并且它不清除内存,此方法易于实现,操作简便,但对所处理的文件有一定的要求及限制.

   具体实现是,先保存中断向量表,然后在分配一块内存,调用DOS的EXEC功能执行被感染的COM文件.执行结束后,重写中断向量表以清除内存中的病毒,然后将内存偏移100H上的代码写入文件,文件长度为原文件长度,最后,在知晓病毒长度的情况下去掉文件尾的病毒代码,清除工作结束.

   这种技术可以对付任何一种文件型病毒,但对于COM文件却有一定的要求:即文件在执行过程中不可以修改代码段的内容,未被加密或压缩的文件一般均可满足此条件.

四  使用调试器DEBUG.COM的EXEC功能

   更简单的方法是用DEBUG来实现,先用L命令装入一个文件,再用G命令运行,EXEC功能结束后,返回寄存器与运行前完全一样,此时用W命令存盘,这时病毒便被清除了.(全过程只用了三条命令)

 

第四章 EXE病毒的清除

一  实现原理

   EXE文件是DOS系统最为常见且灵活的可执行文件,其应用十分广泛.但EXE文件的结构要比COM文件复杂得多.EXE文件由文件头(Header)和装入模块(Load Module)两大部分组成.文件头由格式化区(Format Area)和重定位表(Relocation Table)组成.装入模块为程序代码部分,从位移量100H字节开始.DOS系统在调用EXE文件时,先在内存块底部建立一个程序前缀段(PSP),再将装入模块读入内存指定区域(PSP上方),DS和ES初始化为PSP段地址,CS,IP,SS,SP由文件头格式化区确定,并通过重定位参数调整.然后根据重定位项修改代码数据,最后将程序的控制权由CS:IP传递给目标程序. (如表2所示)

                表2:  EXE文件的装入执行

地址 内容  
XXXX:0000 PSP ← DS,ES
XXXX:0100 数据  
  程序代码 ← CS:IP
  堆栈 ← SS:SP

   对于EXE文件而言,计算机病毒主要是附着于宿主文件的尾部,由于它必须首先获得程序的控制权,因此它必须对文件头进行修改.一般来说,只要恢复了正确的文件头,便可达到杀毒的目的.

   EXE文件被加载时,系统根据EXE文件头的CS:IP参数确定第一条执行语句,因此病毒只需将CS:IP地址指针修改,便可首先执行,事实上,大多数病毒仅仅只修改了文件头,而未修改原文件内容.这便为完整地恢复原程序代码提供了条件.

   从上面的分析可知,感染病毒的EXE文件尾部形成明显的层次,CS:IP指向病毒体,不管病毒采取什么样的措施,它最终必定会在内存中恢复宿主程序所有的真实参数,并且用一条长跳转指令返回原程序.这时,我们便可直接提取出正确的CS:IP和SS:SP参数指针,用它修改文件头后,再将外层病毒代码去掉,这便彻底地恢复了原EXE文件.

   问题在于如何找到EXE文件的正确入口.判断EXE文件的真正入口是十分复杂的,但对于基于DOS系统的病毒来说,其编写语种基本上是汇编语言,因此便具有一些独特的特点.经过大量分析看出,一般情况下,当EXE病毒执行到真正的文件开头时,其CS和DS均要改变,并且DS内容必定是PSP段地址,SS:SP指针被初始化,对于不修改重定位表的病毒来说,CS:IP指针应处于重定位区域内.

   于是,可以再设想出这样一种跟踪器,每执行一条指令,便判断上述条件是否满足,如果满足,则此时CS:IP处的代码便是原文件的影像,根据CPU各个寄存器的内容便可正确地恢复EXE文件头,以达到杀毒的目的.

二  实现方案

   同COM文件杀毒一样,这种理论上的跟踪器实际上是很难奏效的.因此,我们又要求助于我们的老朋友--EXEX功能.

   MS DOS的功能4B有两个重要的子功能:4B00为装入并执行,4B01为装入不执行(未公开的文档功能),4B00用于执行所有的可执行程序,4B01则用于DEBUG调试器中的装入功能.(关于4B01功能的具体参数见附录1).

   由于问题的关键在于如何找到原程序的第一条指令,也就是说在执行到原程序的第一条指令时发生中断,因此我们可以人为地将第一条指令改为中断指令.为了完成这种功能,只需用4B01功能来仿真4B00功能.

   具体是这样做的,当系统调用加载执行功能4B00时,先用功能4B01加载,并初试化所有参数,这时内存的影像应如表3所示.

               表3:  EXE 染毒程序内存影像

地址 内容
  原程序代码区
  CS:IP→ 病毒代码区

   假定病毒的第一条指令处于病毒代码的最前端,原程序的内存影像应为PSP:100~CS:IP(病毒的第一条指令),将这部分区域全部用ASCII码CD填充.这样,原程序的每一条指令都变成了中断指令INT CD(不用INT 3断点中断是因为大部分病毒都具有破坏单步断点中断的功能),也就是说,无论从原程序的任何地址开始运行,所执行的第一条指令都是INT CD.这样,一旦病毒代码执行完毕,打算用长跳转指令返回原程序执行时,都会触发软中断INT CD,而通过INT CD的中断服务程序便可取得EXE文件头真正的初始化CS:IP和SS:SP指针.

   另外值得注意的是,修改后的INT 21必须是可递归的,因为有些病毒(如新世纪病毒)是通过第二次加载原程序来返回的,因此,内存填充要进行两次.4B01也被调用了两次.

   此方法的效率和准确度要远远高于用DEBUG等工具逐步跟踪分析的手工杀毒法.可以为各种染上已知或未知病毒的文件去除病毒外壳.与RCOPY等去壳程序不同的是,这种方法对EXE程序的恢复是全真的恢复,它并不改变原EXE文件的任何内容.它所恢复的EXE程序代码应与原EXE程序代码完全一样.另外,此法由于采用了剥壳还原法,因此还可以用来清除交叉感染的病毒,方法是从外到内逐层脱壳,最后彻底恢复最内层的宿主文件.

 

第五章 结论

   本文所论述的这种清除病毒的方法的实现原理是非常独特的.当然,文中所给出的实现方案并不能清除所有的计算机病毒,但它却给出了一种思想,即抛弃以前那种一个杀毒算法只能杀一个病毒,而是一个算法可以杀一类病毒.根据这种思想,笔者已用C语言和汇编语言编写出这个通用杀病毒程序,并且用大量的病毒对它进行了测试,效果良好.当然,病毒是五花八门的,因此一个统一的病毒对抗软件应接受广泛的考验.其具体的功效还需要多方面的验证,笔者也仅仅希望这种思想能够在反病毒领域发挥出积极的作用.

 

参考文献

1.  李向宇 著   <<计算机病毒概论>>      IDG国际数据集团  1990

2.  Ray Dancan  <<高水平MS DOS程序设计>>   电子工业出版社  1988

   Ray Dancan  Advanced MS-DOS Programing   Microsoft Press  1988

3 . Ray Dancan   <<MS DOS百科全书>>     电子工业出版社  1990

   Ray Duncan  the MS-DOS Encyclopedia    Microsoft Press  1990

  附录:MS-DOS EXEC功能详解

  翻译人:William Long 于1996年 译自:MS DOS百科全书(Ray Duncan: the MS-DOS Encyclopedia)

  MS-DOS系统的加载,即把磁盘上的COM及EXE文件装入内存并执行,可以被任何程序使用MS-DOS功能(功能4BH,加载执行)产生.DOS的命令解释程序COMMAND.COM使用EXEC装入它的外部命令,如CHKDSK,或其它应用程序.许多流行的商业软件,例如数据库和字处理,都使用EXEC执行辅助程序(例如拼写检查),或是装入COMMAND.COM的另一个副本,这就允许用户在不失去当前工作上下文时运行一个辅助程序或打入MS-DOS命令.

  当EXEC被一个程序(父进程)调用并加载另一个程序(子进程),父进程可以通过一串字符即环境块,命令行及两个文件控制块,来传输一定的信息给子进程.子进程同样继承了父进程的MSDOS标准设备及其它父进程打开的设备的句柄(除非打开的操作有"非继承性"的选择).任何操作都可被子进程的继承句柄执行,例如定位或文件输入输出,而且还影响着与父进程句柄联系着的文件指针.子进程也可装入另一程序,如此循环直至系统内存溢出.

  因为MSDOS并非一个多任务的操作系统,子进程直到运行结束才交出系统控制权,父进程此时被挂起,这种进程操作有时也叫做同步执行.当子进程中止,父进程得到控制权并可用另一个系统功能调用(INT 21H功能4DH)取回子进程的返回码并检查子进程的中止是否正常,或是一个重大的硬件错误,比如用户按了Ctrl-C.

  除了装入子进程外,EXEC还可以被用来装入由于用汇编或高级语言写成而不能包含在其库文件中的子程序或应用程序的覆盖文件,这种类型的覆盖文件不能单独运行,多数需要主程序的段内的"帮助"工作或数据.

  EXEC功能仅存在MSDOS 2.0版以上,在MSDOS 1.X版中,父进程可以用INT 21H的功能26H建立一个子进程的程序前缀段,但必须自己完成装载,重定位,执行代码的过程,而不是依靠操作系统的帮助.

  EXEC是怎样工作的

  当EXEC功能接到一个执行程序的请求时,它首先试图打开并定位指定的程序文件.如果文件没有找到,EXEC立刻失败并返回调用者一个错误码.

  如果文件存在,EXEC打开此文件,确定它的大小,并检查文件的首块.如果块的头两个字节是ASCII码MZ,文件便设定为一个EXE装入模式.程序代码段,数据段,堆栈段的大小可以从文件头获得.否则,整个文件便设定为一个决对装入影像(COM程序).实际的文件名后缀(COM或EXE)在这个测试中被忽略.

  此时,内存所需要装入程序的大小是知道的,假如有足够的空间装入程序,EXEC便在内存分配两个块:一个包括新程序的环境块,另一个包括程序的代码段,数据段和堆栈段.不同类型的程序实际分配的大小不同.COM程序得到系统中全部的空余内存(除非内存空间过早形成碎块),而分配给EXE程序的空间大小是由文件头的两个字段控制,MINALLOC和MAXALLOC,它是由LINK设置的.

  EXEC接着将父进程的环境块拷入子进程的环境块,在子进程内存块的底部建立一个程序前缀段(PSP).并将命令行及缺省文件控制块拷入PSP.以前的终止地址(INT 22H),Ctrl-C(INT 23H)

  及严重错误(INT 24H)中断向量的目录存入新的PSP,终止地址向量被更新,以便子进程终止或失败时控制能够返回到父进程.

  接着子进程的实际代码和部分数据便由磁盘文件读到新PSP结构上方的程序内存块.如果子程序是一个EXE文件,文件头的重定位表常用于在程序里定位参考段以便反映出它实际的装入地址.

  最后,EXEC功能建立为程序的CPU寄存器和堆栈并将控制传给程序.COM文件的入口指针常是程序内存块中偏移100H(PSP后第一个字节).而EXE文件的入口地址由文件头指定,可以在程序中任何位置.

  当EXEC用于装入并执行一个覆盖文件而不是子程序时,它的操作会比上述更为简单.对于覆盖文件,EXEC并不试图分配内存或建立PSP及环境块,它只简单地将文件的内容装入调用文件所指定的地址,并执行一些必要的重定位(如果覆盖文件有一个EXE文件头).使用的段值也是由调用者提供.EXEX接着并不是将控制传给最新装入文件的代码,而是返回所产生的程序,请求程序负责在适当的位置调用覆盖.

  使用EXEC装入程序

  当一个程序装入并执行另一个程序时,它必须执行以下几步:

  1.确认有足够的空闲内存来装入子进程的代码,数据和堆栈.

  2.建立EXEC和子进程所需要的信息.

  3.调用MSDOS的EXEC功能运行子进程.

  4.恢复并测试子进程的结束及返回码.

  分配内存

  MSDOS典型地分配给被加载的COM或EXE文件所有可用的内存.一个不常见的例外是当一个由/CPARMAXALLOC开关联接或被EXEMOD修改的EXE程序会由它先前驻留的数据或代码分裂一个短小的程序块.所以,当一个程序要装入另一个程序之前,它必须释放所有它本身代码数据堆栈所不用的内存.

  释放多余的内存是调用MSDOS的重分配内存块功能(INT 21H,功能4AH).此时,ES寄存器置父进程的PSP段地址,BX寄存器置程序自身必须使用的内存块数,如预期的父进程是COM程序,且它减少它的内存分配数低于64K时,它必须移动它的堆栈到一个安全的空间.

  准备EXEC的参数

  当使用装入和执行一程序时,必须提供EXEC功能两条参数:

  1.子程序路径名的地址.

  2.参数块地址.

  参数块依次包括子程序所需信息的地址.

  程序名

  子程序的路径名必需是明确的,零结尾(ASCIIZ),规定文件名(没有非识别字符).如果没有包含路径,便在当前目录下寻找程序,如果无驱动器名,则使用默认驱动器.

  参数块

  参数块包括四个数据项地址:

  1. 环境块

  2. 命令行

  3. 二个缺省文件控制块(FCBs)

  在参数块中为环境块指针准备的空间只有两个字节,包括一个段地址.这是因为环境块总是排在段落上(它的地址总可以被16整除).值0000H表示子进程的环境应被毫不改变地继承.余下的三个地址全是双字节地址,是标准的Intel格式,一个低字的段偏移,一个高字的段地址.

  环境块

  一个环境块总是从一个边界段开始,包含一系列的以0结尾的字符串(ASCIIZ),形式如下:

  name = variable   全部字符串的结尾以一个附加的0表示.

  如果在参数块中的环境块指针提供给一个EXEC的调用包含0,那么子进程只需简单地拷贝父进程的环境块.父进程能够提供一个不同或是增长一组字符串的段指针.另一方面,在MSDOS 3.0

  以后的版本里,EXEC使子程序的环境块具有完整的路径名.环境块最大为32字节.通过这种途径,这么大的信息也可被程序识别.

  最初的(或主控的)系统环境块属于系统接通或重新启动后的命令处理程序(通常是COMMAND.COM)所装入的.COMMAND.COM将字符串PATH,SHELL,PROMPT和SET命令的结果写入系统的主环境块.前两个通常使用的是默认值.例如,一个MSDOS 3.2版的系统从C驱启动,在AUTOEXEC.BAT文件中无PATH命令,CONFIG.SYS文件中也无SHELL命令,则主环境块将下面两行字符串写入:

  PATH =

  COMSPEC = C: COMMAND.COM

  COMMAND.COM为运行"外部"命令而寻找这些说明清单,同时也为了找到自身在磁盘上的可执行文件以便它能在必要的时候重新装入它的暂态部分.当PROMPT字串存在时(先前的PROMPT或SET PROMPT命令产生的结果),COMMAND.COM它来修订用户的提示显示.

  环境块中的其它字符串仅仅为了特殊程序提供信息,它不影响操作系统的操作.例如,Microsoft C 编译器和 Microsoft Object 连接器在环境块中寻找INCLUDE,LIB和TMP字符串,以确定头文件,库文件,临时文件的指定位置.图2给出了一个典型的环境块的十六进制显示图.

  命令行

  命令行是传给子进程的,它包括一字节指明余下命令行的长度,紧接着的ASCII字符串是以ASCII码回车(0DH)为结束的.回车码并不包含在长度值里.命令行可包括子进程可以检查到的所有开关,文件名,以及其它参数,用以影响程序的操作.命令行被拷贝到子进程PSP偏移80H处.

  当COMMAND.COM使用EXEC运行一个程序时,它的命令行包括除程序名或重定向参数外所有用户打下的命令.I/O的重定向是在COMMAND.COM内部处理的,它表明子进程继承了标准设备句柄的活动.其它程序使用EXEC来运行子进程必须自己做一些必要的重定向而且必须提供一个合适的命令行,以便子进程表现得如同被COMMAND.COM装入一样.

  确省的文件控制块

  EXEC参数块的二个确省的FCBs指向拷贝到子进程PSP的偏移5CH和6CH.

  当前只有极少数应用程序使用FCB作为文件和记录的I/O.这是因为FCBs不支持目录树结构.但有些程序检查确省的文件控制块作为分离前二个开关或其它命令行参数的快速的方法.然而,使它自己本身对子进程透明,父进程应该仿效COMMAND.COM那样把命令行前二个参数装入确省的文件控制块.这能使MSDOS的分析文件名功能(INT 21H,功能29H)能方便地使用.

  如果子进程不需要这二个确省的文件控制块,应用程序内存中的参数块中正确的地址会初始化指向二个空FCBs,这些空FCBs是由1字节0和11字节ASCII码空格(20H)组成.

  运行子进程

  当父进程构造完所必要的参数后,它就可以通过中断21H来调用EXEC,各寄存器设置如下:

  AH = 4BH

  AL = 00H (EXEC子功能,装入并执行程序)

  DS:DX = 程序路径名的段地址:偏移址

  ES:BX = 参数块的段地址:偏移址

  从以上软件中断返回后,父进程必须要测试一下进位标志,以此来检测子进程是否实际运行过.如果进位清楚,则成功装入并控制了子进程.如果进位置位,则EXEC功能失败,错误码返回在AX中,可检测原因.通常的原因是:

  指定文件没有找到

  文件找到,但没有足够的内存装入

  其它不常见的服务错误可以从整个系统感到其特征(如磁盘文件或内存中的MSDOS被损坏),使用MSDOS 3.0以后的版本,可以通过调用INT 21H功能59(取扩展错误信息)来获得EXEC更详细的失败原因.

  总的来说,提供给EXEC参数块一个无效地址或参数块本身地址无效并不会引起EXEC错误,但这将使子进程产生一些不可的后果.