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错误,但这将使子进程产生一些不可的后果.

2006年3月30日星期四

局域网上的点对点通信

  整理旧文档,发现了这篇很陈旧的论文,这是我十年前写的第一篇论文,也是我第一篇在杂志上发表的论文,同时也是我大学的毕业设计论文。

  十年前,我写毕业设计论文的时候,为了写这篇论文也花费了我不少的时间和精力,整天都泡在图书馆里。今天再看这篇文章,竟然感觉如同隔世的感觉,那时候什么是网络呢?Windows95刚刚发布,WindowsNT和Windows2000都没有普及,网络在那时还是一个神秘而高深的技术,那时我们建立局域网用的一律都是Novell系统,没有图形环境,设置非常繁琐复杂。而现在,这些东西完全都过时了,那时候先进的TCP/IP现在面临其协议不安全、有漏洞的指责,NETBIOS和IPX就早已失传了,十年时间,竟然整个网络技术发生了如此天翻地覆的变化,慨叹,自己都已经快跟不上这个时代了。

  这篇文章还是重新发布一下,以做纪念。

 

局域网上的点对点通信

 

   摘要:本文讨论了在局域网络环境下,实现工作站之间的实时通信的三种方法.重点介绍了基于NetBIOS 及TCP/IP协议实现工作站之间的点对点通信(Peer to Peer), 并给出了设计的应用程序实例.

   关键词:局域网 点对点通信 NetBIOS TCP/IP IPX/SPX

 

一  引 言

   在信息化社会里,人们都希望以快速简的方法获取信息,计算机网络的出现,使人们的这个想法得以实现.通过计算机网络,人们可以方便地实现通讯和共享资源:计算机网络使信息传播和信息处理加工的设备和工具空前紧密地结合在一起,这种技术的进步和发展对提高人类社会信息化水平有着巨大的推动作用.

   但在实际的计算机网络中,往往需要互连来自不同厂家的机器,要具备异 种机的互联能力.由于各厂家的机器有其各自的总线结构,文件系统,输入输出系统和采用的字符集等,因而使这种互联成为一件十分困难的事情.

   另外,从局域网的运行情况来看,以Novell Netware网络为例,文件服务器是网络的核心,其上运行Netware操作系统软件,为网上工作站提供共享资源与服务.因此,文件服务器的好坏对网络的性能极其重要.随着网络的扩大,连接的工作站增多,服务请求也迅速增加,服务器的负载也相应加重,服务器有可能成为网络工作的"瓶茎".

   针对上述情况,本文利用网络上的点点通信思想,在不使用服务器的情况下实现不同工作站之间的文件传输和共享打印.

 

二  局 域 网 概 述

   随着微型计算机技术的迅猛发展和日益成熟,微型计算机的价格在不断下降,因此人们有条件的将十几台微机,外设依网络通信协议连接起来,形成局域网(Local Area Network).它具有以下几个特点:

   1) 采用基带传输,传输速度较高.

   2) 网络覆盖地域较小,可不用调制解调器.

   3) 传输误码率低.

   局域网的功能概括起来可归为以下几点:

   1) 资源共享.包括大容量硬盘,高速打印机,数据及软件.

   2) 电子邮件系统.

   3) 使用分布处理实现负载均衡.

   机算机网络中对于各种约定做了如下定义:将机算机网络同等层间的通信约定称为网络协议.将不同层的通信约定称为接口.到目前为止最有代表性的网络分层模型有两种.其一为国际标准化组织(ISO)所提出的开放系统互连(OSI)七层协议参考模型,其二为美国电气与电子工程师学会(IEEE)802委员会所提出的参考模型.

   (一) ISO/OSI七层协议及参考模型

   OSI参考模型的七层分层结构如图1所示.该模型是按逻辑组合功能来分层的,上一层是建立在下一层的基础上,较高层向较低层提供服务请求,而较低层为较高层提供服务.所谓开放系统是指按照这种模型所构成的网络是可以互连的,是彼此开放的,从而便于世界各地的网络互连.

   OSI模型各层定义如下:

    应用层       网中的网络应用软件在此层运行.

    表示层       辅助用户执行诸如文间传送,程序运行等任务.

    会话层       管理低层与用户之间的连接,是用户到网络的接口.

    传输层       检查网络数据的完整性,必要时将数据分组调整到正确的位   置.设置分组题头,以便将数据组发送到目的地.

    网络层       以分组形式,选择路径发送数据.各分组要穿过两个低层到达目的地.

    数据链路层     管理网络接口处的输入/输出.对原始数据进行组织和检察.

    物理层       定义在网络电缆连接及接线中用的规则与协议.包括例行联络处理及传输规范,还定义了使用的电缆类型及连接器.

   (二) IEEE 802标准局域网络参考模型

   IEEE 802标准遵循ISO/OSI参考模型的原则,解决了最低两层----物理层和数据链路层的功能以及与网络层的接口服务,网际互连有关的高层功能,IEEE 802 LAN 参考模型与ISO/OSI 参考模型的对应关系如图3所示.

   1 IEEE 802 的五个标准文件

    IEEE ( Institute of Electical and Electronics Engincers ),即电气和电子工程师学会,它是一个专业性质的学会.它对OSI模型的低两层即物理层及数据链路层的协议标准进行了大量的研究.IEEE 802标准制定目的是为了在不同的厂商所制造的设备间具有兼容性,从而为使用该网络的用户和设备制造者在付出较小的代价后就能顺利地在这些设备间进行通信.该学会在经过多年的研究和修订,于1984年正式提出了局域网标准的五个标准文件.

   IEEE 802.1     它阐述了802方案与ISO互连参考模型间的关系.

   IEEE 802.2     逻辑链路控制标准.

   IEEE 802.3     采用CSMA/CD访问的总线结构标准.

   IEEE 802.4     采用令牌访问方法的总线结构标准.

   IEEE 802 各标准间的关系如图2所示.

   2 IEEE 802 LAN 标准局域络参考模型 

   从对ISO参考模型的讨论中以然清楚的了解到物理层,数据链路层及网络层共同完成了报文分组的传输功能,因此物理层,数据链路层是必不可少的.但考虑到局域网络的特点,IEEE 802对OSI参考模型作了修正.IEEE 802将数据链路层分为两个子层,即逻辑链路子层(LLC)和介质访问控制子层(MAC).在MAC子层中CSMA/CD,令牌总线(Token Bus),令牌环(Token Ring)等几种介质访问控制方式.在数据链路层同网络层的接口设置了服务访问点(SAP).

 

三  网 络 通 信 及 实 例

   (一) 进程通信

   进程,指程序的一次执行.进程通信指各进程之间共享资源,相互进行数据传输的信息交换方式.OSI的传输层为进程通信提供了服务.

   进程通信的实现方法:

   1) 建立和拆除进程间的连接

   2) 信息传递与控制

   (二) 点对点通信

   从OSI参考模型的应用层来看,可认为网络是由工作站和服务器组成的,但从传输层和网络层的角度看,工作站和服务器没有本质的区别,它们都是连接到网络上的一台机器,都可以用网络地址或名称来代替.它们之间的通信,就是所谓的点对点通信,也叫对等通信.在局域网上,点点通信意味着两个工作站可以直接对话而不用经过文件服务器中转.

   (三) 实例:  Windows 95的点对点网络通信功能:

   Windows 95操作系统的Network Neighborhood(网络邻居)的三个重要的部分是:Netware的客户服务,点对点对等服务,Internet或/TCP/IP服务.

   在Windows 95内建的点对点对等网络功能,可以很容易地在一个小 工作组内共享文间和打印机,而不用文件服务器.Windows 95 比Windows for workgroup3.11最具特色的功能之一是:它有一个大大改进的安全方案,每个用户即可以在用户级又可以在资源级共享文件和打印机等资源.

   在Windows 95下,点对点的对等网络具有更大的灵活性,因为它可在Netware多用户(运行于IPX/SPX或TCP/IP协议下)之间建立点对点对等连接.Windows 95 能做Windows for workgroup 客户能做的每件事,还可以做得更好.

   无论用户选用什么样的平台,他们都可以利用Network Neighborhood非常方便地浏览网络资源.用户选中工作台面上的一个图标即可直接进入Network Neiborhood工作窗口,此后,用户不关心网络连接,驱动器映像,打印机队列等工作,即可连接到任意类型的网络服务器,浏览服务器中的文件或其它共享资源.

   安装对等网络服务功能具体是这样的,从Control Panel中打开Network对话窗口,移动其中的Configuration标签,点中add按扭后,在弹出窗口中选择Client.此后,会弹出一个Select Network Client(选择网络客户)的对话窗口,选中其中的Client for Microsoft Network后,点OK按扭.重新启动机器后,在Network Neighbour hood中将显示同一工作组中共享文件的所有客户.同时,在Network Neighborhood中也列出了网络中的Microsoft,Warp Connect以及IBM LAN Server域名,Microsoft工作组和Netware通过使用全局命名规则(Universal Naming Convention,UNC)而不是通过驱动器映射到的Netware网络服务器.

   文件共享在Configuration标签中设置File and Print Sharing(文件与打印共享)选择项,然后在Access Control(访问控制)标签中选中Share Level Access Control项,为了配置共享选择项,必须返回到Desk top或Explorer中,用鼠标右键在准备共享资源(如键盘,光驱)上点一下.此后,会弹出一共享设置Sharing对话框.如使用Netware网络,那么结果是:要么网络中其他用户都可以访问你的共享文件,要么无人可访问.

 

四  点 对 点 通 信 的 实 现

   局域网中工作站之间的通信程序的开发一般通过四种途径:第一种是通过改造网络原有通信软件来实现.但这种改造必须以对该软件充分了解为基础,否则改造后很难保证不影响网络的整体性能,甚至会造成系统运行不可靠,而改造后的通信质量不一定理想.第二种是利用Novell网本身的网络协议IPX/SPX来实现,由于这种方法开发比较麻烦,采用的并不多.第三种是通过NetBIOS功能调用来实现,NetBIOS是PC LAN的通信接口标准,广泛适用于多种微机网络,使得以它为基础的设计和应用开发可移植性好.它不依赖于任何网络硬件,是一个介于网络硬件和用户应用程序之间的接口协议.其通信原理是:两个要进行通信的工作站通过名字建立一个虚电路,然后向相应的虚电路号发送或接收信息,这样通过虚电路实现了两个工作站之间的对等通信.利用NetBIOS实现工作站之间的实时通信,功能比较强,编程实现比较容易,所以应用比较广泛.第四种是通过TCP/IP协议来实现.下面我们将详细讨论各种技术的实现.

   (一) 基于IPX/SPX 的实现技术

   由于IPX/SPX不能支持多协议之间的通信,因此本文略之.

   (二) 基于NetBIOS的编程接口

   NetBIOS是Network Basic Input/Output System 的缩写,即网络基本输入输出系统,它是一种应用程序的接口.用户可以调用各种NetBIOS功能,而无需涉及到各种最低层的通信协议,从而实现数据源地与数据目的地之间的信息交换.

   1 NetBIOS概述

   NetBIOS是IBM公司于1984年首次推出的.它可以支持各种著名的通信协议,如TCP/IP,MAP/TOP,XNS,IEEE和OSI等,不仅适用于DOS环境,还可以用在UNIX,OS/2,WINDOWS环境.

   NetBIOS作为一种网络支撑软件,在ISO的开放系统互联(OSI)模型中的位置如图3所示.

   2 NetBIOS的基本概念

   命令

   NetBIOS的功能是由执行一系列命令来完成的.有Wait和No_wait两种形式.

   名字

   NetBIOS是一种按名字工作的系统,每一网络工作站和服务器都有一个(或几个)名字,每个节点还有一个永久节点名,它是在网络适配卡上的6字节网络地址前面再添上10个字节0构成.

   数据报和会话

   数据报是一种无连接的服务,即各个数据报之间互相独立,单独传送.在网络上任意两个名字之间可以建立一个会话,或多个会话.

   网络控制块(NCB)

   应用程序调用NetBIOS命令,必须先构造一块网络控制块(NCB),然后执行一次5CH中断.

   信息帧

   在网络中传递的信息是以帧的形式组织的.NetBIOS根据用户的命令,NCB以及它所知道的有关会话和名字的情况自动生成和管理信息帧,用户不必直接过问.

   服务器报文块

   3 NetBIOS设计要点

   在设计两个或多个工作站之间对话的时候,要注意处理好以下几个问题:

   1) 选择通信方式

   网络中的通信可以采用数据报方式,也可以采用会话方式.

   会话方式的特点是由通信协议保证每一报文能够正确地送到目的地.如果报文在传送过程中发生了差错,则通信协议会自动地进行重发,加以改正.而且,如果你发出的报文不止一个,那么通信协议还能够保证接收到的报文次序和发送时的次序一致.这些保证都是对用户应用程序透明地进行的,用户完全不需操心.但是,会话方式的主要缺点是过程比较复杂,在发送报文之前先要建立会话,送完报文之后又要撤除会话.因此,会话方式比较适合于点到点的多次往复式的对话.

   数据报的特点正相反.它是把每一个报文作为一个独立的数据报处理,从而免除了建立和撤除会话的麻烦.但正因如此,它不能保证接收到的报文次序和发送次序一致,甚至不能保证每一个报文都能够正确无误地达到收方.在报文丢失或发生错误时,系统不向发送方提供出错信息.如果你所设计的对话环境由一系列互不相关的报文组成,或者每次对话都很简单,那么采用数据报传送可以大大加快对话的速度.另外,如果用数据报传送比较重要的报文,为了防止差错和丢失,可以在应用程序中为报文加上查错和序号功能.

   2) 选择命令返回方法

   执行NetBIOS命令可以采用等待方式和非等待方式.对于非等待方式,又可以有两种不同的做法:一种是轮询方法,即循环检查网络控制块(NCB)中的最终返回代码字段,当它的值从0xFF变为其它值时,表示该命令执行完毕. 另一种是异步事件处理方法,即告诉NetBIOS,在当前命令执行完毕后存放在NCB的POST程序地址字段中的程序指针,继续执行一个指定的程序段.需要指出的是,这两种做法虽然难易程度不同,但都是在后台进行.对于前后操作,都是立即返回用户程序,不必等待命令完成.它们的主要差别在于对网络负荷的影响.比如,一个工作站发出一条命令,要求另一个工作站执行一项比较费时的任务.如果这个工作站采用轮询方式,持续不断地询问对方是否完成,就会极大地增加网络的负荷.这时,尽管轮询比较容易编程,那也不是一种好的选择.

   4 NetBIOS基本程序

   1)调用NetBIOS

    要调用一NetBIOS功能,需要做以下三件事:

       (1) 构造一个NCB,包含所有需要告诉NetBIOS的信息.

 

#define USGC unsigned char

#define USGI unsigned int

#define USGL unsigned long

 

struct NCB  {

   USGC NcbCommand;

   USGC NcbRetCode;

   USGC NcbLsn;

   USGC NcbNum;

   char * NcbBufferOffset;

   USGI NcbBufferSegment;

   USGI NcbLength;

   char NcbCallName[16];

   char NcbName[16];

   USGC NcbRto;

   USGC NcbSto;

   char * NcbPostRtnOffset;

   USGI NcbPostRtnSegment;

   USGC NcbLanaNum;

   USGC NcbCmdCplt;

   char NcbReseredArea[14];

} ZeroNcb;

 

       (2) 把网络控制块地址写入ES:BX寄存器,作为指向该NCB的远程地址指针.

       (3) 执行5CH中断.执行中断时,NetBIOS自动进入ES:BX寄存器指定的地址,读出网络控制块,得知一切有关该操作的信息. 下面是设置指针和执行中断的程序段:

void NETBIOS  (struct NCB *NcbPtrNear)

 

{

   union REGS InRegs,OutRegs;

   struct NCB far *NcbPtrFar=(struct NCB far*)NcbPtrNear;

 

   segread(&SegRegs);

   SegRegs.es=FP_SEG(NcbPtrFar);

   InRegs.x.bx=FP_OFF(NcbPtrFar);

 

   int86x(NetbiosInt5c,&InRegs,&OutRegs,&SegRegs);

 

}

  

   2)定义NetBIOS命令

   在程序段中还包括对所有NetBIOS命令(包括WAIT和NO_WAIT)

   3) POST程序

   在执行非等待命令时,可以把一个POST程序的地址告诉NetBIOS,然后直接返回前台操作.当后台命令完成时,它会自动转去执行POST程序.从这段描述可以看出,我们必须把POST程序编成一个中断处理程序.

 

unsigned  es_reg,bx_reg,msg_received_flag;

NCB far *posted_ncb_ptr;

void interrupt POST (void)

{

    es_reg=_ES;

    bx_reg=_BX;

    posted_ncb_ptr=MK_FP (es_reg,bx_reg);

    msg_received_flag=TRUE;

}

 

   4)数据报服务

   假定A工作站和B工作站之间以数据报方式通信,其主要步骤如下:

    工作站A               工作站B

   增加名字A              增加名字B

   发送报文给B  ----------->      收到一个报文

   收到一个报文     <------------  发送报文给A

   删除名字A               删除名字B

   5)会话服务

   A工作站和B工作站之间以会话方式通信步骤如下:

    工作站A               工作站B

   增加名字A               增加名字B

   Listen                Call  A站

   发送报文给B  ----------->      收到一个报文

   收到一个报文     <------------  发送报文给A

   Hang up  B站             Hang up  A站

   删除名字A               删除名字B

 

    5 Windows 通信程序的特点

   在Windows中,由于它是非抢先多任务,所以NetBIOS最好用异步方式(非等待式),CPU发出NetBIOS调用后,处理其他消息, 当NetBIOS完成后会自动执行后置例程POST, POST 通过 PostMessage 把一条用户定义的消息放到合适的队列中.Windows 应用程序接到该消息后再处理接收到的网络数据.

   其次,由于Windows的代码段和数据段可移动,这对异步NetBIOS是致命的,当异步NetBIOS命令发出后,如果代码段或数据段移动,命令完成后,NCB所指示的缓冲区已发生变化.解决的方法是使代码段和数据段不可移动.在DEF文件中定义如下:

     CODE   PRELOAD   FIXED

     DATA   PRELOAD   FIXED   SINGLE

 

   6 点对点通信程序源代码. (基于NetBIOS)

   完整的源程序见附录.

 

   (三) 基于TCP/IP协议的编程接口

   1 TCP/IP简介

   TCP/IP的历史要追溯到70年代中期,当时ARPA为了实现异种网之间的互连(interconnection)与互通(intercommunication),大力资助网间网技术的研究和开发,于1977年到1979年推出目前形式的TCP/IP体系结构和协议规范.到今天,TCP/IP技术以及Internet网间网已经为广大计算机工作者,机算机厂商和机算机用户所接受.据统计,到1990年,Internet以包含遍布欧美的五千个活动网络,超过三十万台机算机.作为一种事实上的工标准,TCP/IP技术方兴未艾.

   2 TCP/IP的网络分层结构

   对TCP/IP协议来说,TCP提供传输层服务,IP提供网络层服务.TCP/IP协议组(或Internet协议组)的分层结构及其与OSI模型的对应关系如图4所示.图中有关协议的名称及其基本含义如下:

   (1) TCP.  为传输控制协议(Transmission Control Protocol).它是提供给用户进程的一个可靠的全双工字节流的面向连接的协议.大多数Internet应用程序使用TCP.因为TCP使用IP,所以整个Internet协议组也常称为TCP/IP协议组.

   (2) UDP. 为用户数据报协议 (User Datagram Protocol).

   (3) ICMP. 为网间报文控制协议 (Internet Control Message Protocol).

   (4) IP. 网间协议 (Internet Protocol). IP协议是为TCP,UDP和ICMP提供分组发送服务协议.

   (5) ARP. 地址转换协议.

   (6) RARP. 反向地址转换协议.

   3 Socket编程界面

   (1) Socket 原理

   Socket编程界面由4BSD UNIX首先提出,目的是解决网间网进程通信问题.Socket接口为进程间通信提供了一种新的手段,它不但能用于同一机器中的进程之间的通信,而且支持网络通信功能.Socket具有类型,反应了对用户透明的通信特性.

   一个完整的Socket连接用一个相关描述:

       { 协议,本地地址,本地端口,远地地址,远地端口 }

   Socket 是面向客户-服务器模型而设计的,针对客户和服务器程序提供不同的Socket系统调用.

   (2) Socket系统调用

   不管Socket内部机制如何,它提供给应用程序员的最终界面是一组系统功能调用.下面,我们一一给出重要的Socket系统调用.

     1. 创建 Socket ----- socket()

     调用格式如下:

       sockid = socket (af,type,protocol)

    af : 地址族,指本socket所用地址类型.

    type :  类型,指创建socket的应用程序所希望的通信服务器类型.

    protocol : 协议,指本socket请求的协议.

     2. 指定本地地址 ---- bind()调用

     bind()将本地socket地址与所创建的socket联系起来,即将本socket地址赋予socket,以指定本地半相关.bind()的作用相当于给socket命名,调用格式为:

         bind (sockid,localaddr,addrlen)

     sockid : socket号.

     localaddr : 本地socket地址.

     addrlen : 地址长度.

     3. 建立socket连接 ---- connect () 与 accept ()调用

     这两个系统调用用于完成整个相关的建立.其中connect用于建立连接 .调用格为:

         connect (sockid,destaddr,addrlen)

     destaddr : 指向对方socket地址(信宿地址)结构的指针.

     accept : 用于面向连接的服务器,其调用格式为:

         newsock = accept (sockid,clientaddr,paddrlen)

     clientaddr : 指向客户socket地址指针.

     paddrlen : 客户socket地址长度.

     4. listen() 调用

     此调用用于面向连接服务器,表明它愿意接收连接,listen()在accept()之前调用,格式为:  

         listen (sockid,quelen)

      quelen : 请求队列长度.

     5. 发送数据 ---- write(),writev(),send()与sendto(),sendmsg()

     用于socket数据发送的系统调用一共有五个,其中三个,write(),writev()和send()用于面向连接传输,其余两个用于无连接传输.面向连接的调用可以不指定信宿地址,而无连接的调用必须指定.假如无连接socket的双方均调用过connect(),可以认为是建立有连接的socket,也可以面向连接调用发送数据.

     三个面向连接调用三者的格式大致相同:

     write (sockid,buff,bufflen) : 缓冲发送

     writev (sockid,iovector,vectorlen) : 集中发送

     send (sockid,buff,bufflen,flags) : 可控缓冲发送

     其中buff指向发送缓冲区的指针,bufflen是发送缓冲区大小.

     用于无连接数据发送的调用有两个:

     sendto (sockid,buff,bufflen,flags,dsadd,addrlen)

     sendmsg (sockid,message,flags):可控集中无连接发送.

     6. 接收数据 ---- read(),readv(),recv()与recvfrom(),recvmsg()

     接收数据与发送数据系统调用是一一对应的,两者参数的最大区别是,前者buffer是一个指针,其所指单元初值为欲读数据长度,调用后的值是实际读出的值.

   4 客户--服务器模型的Socket实现框架

     1)客户--服务器模型时序图

     下图是面向连接客户--服务器模型的典型时序图

       服务器                 客户

       socket()                socket()

       bind()                bind()

       listen()                

      accept()   等待客户连接请求      

     阻塞   <━━━━━━━━━━━━━━━ connect()

       read() <━━━━━━━━━━━━━━━> write()

 

     2)服务器socket地址的确定

     在客户--服务器模型中,所有的作用者都是客户首先发起的(如连接请求,服务请求等),因此客户必须要知道服务器socket地址,另外,客户调用服务器之前,可以在命令行中给出服务器所在主机的域名,根据域名可以获得服务器主机的地址,系统调用为:hp=gethostbyname(host).其中host可以是服务器主机域名,返回hp是一个指向主机地址结构的指针.

 

五  结 论

   综上所述,TCP/IP对于异种机具有极强的互连能力,很可能成为未来网络协议的标准,其通信编程有一整套方便实用的工具.因此,用其开发通信软件方便,容易,可升级.

   而NetBIOS是一种可加载模块,其特点是可方便地实现不同协议之间的通信,其通用性极强,可方便地在不同局域网间移植.

   以上两种方法各侧重点不同,而近年来由于Internet的兴起,TCP/IP逐渐变得重要了。TCP/IP使得互连UNIX终端,WINDOWS终端以至MAC终端成为现实。成为世界上最大的网络。目前,世界上各大公司正争先恐后的开发Internet上的资源.因此可以预见在不久的将来,以TCP/IP为基础的点点通信必将成为网络通信的重要手段.

  

                参 考 文 献

1. 顾隽修 等编著   <<计算机局域网络原理与应用>>   中国广播电视出版社   1993

2. 陈洛资 等编著   <<计算机网络软件设计,开发与编程>>   科学出版社   1994

3. 汤毅坚 编著    <<计算机实用网络编程>>   人民邮电出版社   1993

4. 张公忠 等编著  <<Novell 网组网原理与实用技术>>   清华大学出版社   1992

5. 徐建平 岳东 编著  <<Novell 网络原理,操作及开发指南>>  电子工业出版社  1994

6. 汤岳清 编著   <<Novell 网络及其互联技术>>   电子工业出版社   1992

7. 周明天 编著   <<TCP/IP网络原理,操作及开发指南>>   清华大学出版社   1993

8. Tim Farrell,Runnoe Connally  <<Windows 3.1 编程指南>>   清华大学出版社  1994

9. Daniel Appleman  <<Visual Basic 与 Windows API 接口大全>>   电子工业出版社  1995

10. 陈佳海 等编著   <<Visual C++ 程序开发指南>>   科学出版社  1995

11. 唐文卫 鲍敏   Novell 网上的点对点通信   <<微计算机应用>>   1995(6)

12. 邱勇攀   基于IPX的工作站实时通信的实现   <<微计算机应用>>   1995(2)

2006年3月29日星期三

生成Feed的代码进行了修改

  今天我将主要的几个网站的Feed生成代码都进行了一些修改。

  我也是不得不这么做。因为我发现现有的Z-BLog写的TAG始终无法被technorati获取,然而别人用WordPress写的Blog里的TAG却可以被technorati获取,我自己也手动Ping了technorati,但发现也没有用,只好仔细分析其中的原因了。

  我仔细分析了一下WordPress和Z-Blog的代码,我发现在Feed生成上有一点不同,Z-Blog缺少了几个东西,有可能和这个有关,于是我就修改了一下Z-Blog的rss相关代码,生成和WordPress类似的feed,早上修改的代码,没想到晚上立刻就生效了,新发布的日志的TAG都被收录了,看来我修改的是正确的,只可惜过去一年多的日志里面的TAG都没有被收录。不过我也想到了补救办法,我打算自己再写一个程序,在以后的10天内分别将以前的四百多篇日志提交到technorati上。可惜啊,要是我一早发现这些原理,就不用这么麻烦了。

  另外我给我另外的网站也生成了Feed。Write100的feed原先是使用OBlog 3.12自带的,地址是http://feeds.feedburner.com/write100,但我发现OBlog的Feed生成代码根本写的就有问题,日期的格式不是RFC-822的日期格式,feed合法性校验都无法通过,我只好在手动修改一下里面的代码,同时也不由地感叹,国内地一些开发者总是在开发一些花里胡哨的东西,却在一些最基本的功能上马马虎虎,没有国外开发团队的那种专业性,这样只能和国外的系统比如WordPress差距越来越大。

  当然,对于feed能够产生的实际功效,很多人也在怀疑,而且feed是否是广告商的恶梦,是否能带来更大的流量,也是一个有争议的话题,不过,只要feed不给我的网站带来负面影响,我也是乐于将原先的WEB 1.0的网站增加上feed的。

  最后,介绍一个校验feed合法性的网站:http://feedvalidator.org/ ,用这个地址可以校验feed语法是否正确。

2006年3月27日星期一

祭父

  今天是我父亲的两周年祭日,两年前的今天,父亲突然瘁死在交大附属二院。

  我父亲做了几十年的大学老师,是一个典型的知识分子。具有知识分子的清高和自负。晚年工作上很不顺心,因为我父亲的正直,看不惯单位里的一些头头私设小金库,侵吞国有资产,而成为某些人心中的眼中钉。知识分子对于官场的黑暗和邪恶往往估计不足,我父亲吃了很多亏,心情十分不好。

  我父亲对自己身体太自信了,当一只眼暂时失明的时候才住进医院,住院才一星期,就花费了父亲数个月的工资,可惜的是医院依然没有放过我父亲,就在住院的第六天,我父亲就突然瘁死在病房中,终年59岁。我永远也忘不了那个医院-西安交大附属二院,从某种意义上来讲,西安交大附属医院和我有杀父之仇。

  我想不通,这世界发疯了吗?这些医院知道赚来的钱是沾满鲜血的吗?他们对得起自己的良心吗?他们感觉不到死尸的沉重吗?他们不怕这世界有报应吗?

  我们国家的很多改革都很不对劲,教育产业化让穷人上不起大学,医疗产业化让普通人看不起病。我父亲的命运也真验证了那句话:“小病忍、大病挨、重病才往医院抬”,“辛辛苦苦几十年,一病回到解放前”。医疗产业化所引发的种种问题,不得不让我们质疑:医院的存在究竟是为了救人还是为了杀人

  这的确是个邪恶的世界,什么样的魔鬼才能创造这样的邪恶帝国?恐怕撒旦也会自愧莫如,他们的灵魂是魔鬼缔造的,他们在毁灭我们几千年的中华文明,我们却无能为力。但人总有一死,那些双手沾满鲜血的刽子手们迟早难逃一死,希望那些老东西们快些下地狱吧。我们还有后代,我们不能让我们的后代也像我们这样生活,在谎言、欺骗、恐惧的白色恐怖下度过这一生。