今天无意当中又点到了Crash这部电影,随便拖着回顾了一下,感觉还是那么不错。

这部电影是在2004年9月10日就上映的了,但是在今年的OSCAR上才获奖。是不是今年导演才想起来把它拿到OSCAR来试试啊?呵呵。

这是一部非常写实的电影,讲述了M国严重的种族歧视问题。比如白人就是认为黑人就是造成社会不稳定的各种因素,导致犯罪率升高等等。本片由围绕几个人物的几个事件通过Crash串起来,向我们讲述了各种各样的社会问题。我觉得这是一部非常值得看的电影,它获得OSCAR奖的话真是理所当然的,它值这个奖,呵呵。片中的各种音乐也非常不错,很有震撼的感觉。

post-328914-1135814769.jpg

导演:保罗·哈吉斯 Paul Haggis
主演:桑德拉·布洛克 Sandra Bullock
    唐·齐德尔 Don Cheadle
马特·狄龙 Matt Dillon
布兰登·费舍尔 Brendan Fraser
威廉·菲德内尔William Fichtner
类型:剧情/犯罪/悬念
级别:R
片长:107分钟
上映:2004年09月10日
对白:英语
字幕:

简介:

  故事是发生在洛杉矶–这个多民族、多文化聚集的大城市。影片的开始就是一起看似普通的撞车事件,以及几个与这个事件有关的人。然后,镜头将我们带到这次撞车事件发生的前一天,并分别向我们展示了这几个主要人物在这几十个小时中所发生的事情。

  那个洛杉矶警察局的警察(马特·狄龙饰),希望能给自己患病的老父亲找到更好的医疗救助,但是,在HMO,任凭他如何的请求,负责处理这件事情的黑人职员就是不签署文件,以允许他父亲去找别的医生。随后,这名警察在处理交通堵塞的时候,将自己心中的怨气通通的爆发在一对黑人夫妻的身上。地区检察官(布兰登·费舍尔饰)与地位显赫的妻子简(桑德拉·布洛克饰)被两个年轻的黑人用枪指着头,只能无奈地看着他们抢走自己的越野吉普。回到家之后,心中的恐惧仍未消退的简,无缘无故地对上门为他们换锁的墨西哥裔修锁匠丹尼尔(迈克尔·佩纳饰)大发光火。可怜老实的丹尼尔在当天的晚上,又一次让一名阿拉伯裔的商店店主夺去了他的尊严。

  黑人侦探格雷厄姆焦急地在寻找着他走失的弟弟,但又不得不受上司的威胁,去面对黑洞洞的枪口……一个又一个的角色在观众吃惊的目光地注视下,由正义到邪恶、由被伤害者到施暴者不断的转换着。

演员表:

桑德拉·布洛克 Sandra Bullock …. Jean
瑞安·菲利普 Ryan Phillippe …. Hansen
唐·钱德尔 Don Cheadle …. Graham
马特·狄龙 Matt Dillon …. Ryan
布兰登·弗雷泽 Brendan Fraser …. Rick
Tony Danza …. Fred
威廉·菲德内尔 William Fichtner …. Flanagan
特伦斯·霍华德 Terrence Dashon Howard …. Cameron
詹森·艾萨克 Jason Isaacs …. Det. Carr
拉伦兹·泰特 Larenz Tate …. Peter
Sean Cory …. Motorcycle Cop
Daniel Dae Kim …. Park
基恩·大卫 Keith David …. Lt. Dixon
洛雷塔·戴维尼 Loretta Devine …. Shaniqua
詹妮弗·艾斯波西多 Jennifer Esposito …. Ria

    提起家庭影院,大家都会想到几只大音箱和一个大功放。不错,传统的家庭影院音箱一般较大—特别是一对主音箱,大的是落地式的,小一点的也是书架式的。而目前,一种小巧的迷你家庭影院开始风靡市场。

    市场发展迅速

    “在市场上,迷你家庭影院销售形势非常好,销量增长也很迅速。”大中电器碟机事业部尚燕来告诉记者。他说:“迷你家庭影院的兴起还是这两年的事情。从 2003年开始已经有不少厂家推出了各具特色的迷你家庭影院,不过那时候厂家推出产品多以展示为主,销量也比较一般。而到了2004年,迷你家庭影院却成了各家企业的重头戏,产品品种不断增加,档次也逐步拉开。”

    很早就涉足迷你家庭影院的上海广电数码科技有限公司经理王利君有几分感慨地说:“在2000年,国内仅有几家企业销售迷你家庭影院,但经过了几年的发展,迷你家庭影院的销量正在攀升。而且近年来品牌和产品也在逐渐增多,竞争趋于白热化。”

    据悉,2000年就涉足迷你家庭影院市场的上广电到目前为止已经销售了总共180多万套迷你家庭影院。是什么原因让消费者倾向选择迷你家庭影院的呢?

    迷你家庭影院产品主销国外的步步高公司营销部有关负责人介绍,国内审美观念的变化和国内居民住房面积的增加,是小型化的家庭影院受到国内消费者欢迎的主要原因。迷你家庭影院在国外很受欢迎,欧美地区消费者喜欢在自己的房间看电影。因此除了客厅里面有一套家庭影院以外,在其他房间还会选购一套小型化的家庭影院系统,这使国外市场对适合卧室或者书房等小房间使用的迷你家庭影院的需求较大。在国内,消费者对家庭影院的需求也已经开始从“高大威猛型”向“小巧精致性”转变。

    尚燕来也认为,消费者的选择趋向正在变化,随着超薄等离子、液晶电视的逐渐兴起,人们更愿意组成一套小巧化的影音系统,因此迷你家庭影院的火爆也顺应了目前影音家电向小型化发展的趋势。

    产品特点各异

    尽管都是迷你家庭影院,但市场上的产品无论在设计上以及造型上都有着很大区别。

     目前,迷你家庭影院系统整合有两种方案:一种是将功放机与DVD播放机整合在一起,另一种是将功放机与超重低音箱整合在一起。两种整合方式相差不大,将功放机与超重低音箱整合在一起的音响,整套系统显得小巧玲珑。而将DVD机和功放机整合在一起的音响系统,机器体积与单独的DVD机相比较大。不过也有特例 —比如将DVD机和功放机整合到一起的索尼迷你家庭影院,由于使用了S-Master纯数码功放技术,DVD机部分也做得非常小巧。而就在最近,索尼还推出了具有无线环绕扬声器的迷你家庭影院。

    除了功放整合的方式不同以外,迷你家庭影院的音箱也不尽相同,从样式上可以分为两类。一类是卫星式音响,这种音响除了重低音箱,其他音箱都只有拳头大小,特别适合小面积的房屋使用。这类机型主要有安桥的L-MS30、三洋的DC-TS780等。而另一种音箱设计是立柱式的,相比传统家庭影院的落地式主音箱,迷你家庭影院的两个主音箱和两个环绕式音箱更薄、更细、更小巧,比卫星式音响更时尚。

    总的来说,这两种音箱分别适合不同人的需要。而特别值得一提的是飞利浦的LX3700D,虽然是卫星式音箱,但是加上两对立柱后,摇身一变,马上就可以成为立柱式音箱。可以说,这种结合也正体现了厂家独具匠心的设计。

    在功能上,迷你家庭影院都具备欣赏DVD碟片,播放VCD、超级VCD和CD碟片的功能。大部分都内置了杜比数码和DTS解码器,有的还可以兼容音效更好的HDCD盘片。另外,还有一些迷你家庭影院把调谐器也整合进去,能接收AM和FM广播,还有的拥有磁带卡座。比如售价6000元的松下SC-TH883 音响就将DVD、卡座、收音都集合到了一起。

    性价差异不小

    据了解,大多数迷你家庭影院都以看电影、唱卡拉OK、听音乐为主要功能,而且这些方面的技术比较成熟,功能也比较相似,因此,选择迷你家庭影院时特别注重功能的消费者并不多。尚燕来告诉记者,迷你家庭影院的主要卖点还是音质和外观。

    记者注意到,同是迷你家庭影院,不同品牌或者相同品牌不同型号的产品价格相差很大。便宜的仅1000多元一套,贵的要上万元。

    在价格方面,国内品牌有着明显的优势,单套售价大概在2000元~3000元。而国外品牌价格普遍较贵。不过与2003年相比,国外品牌机价格已经下调很多,如索尼、松下等品牌的第一代迷你家庭影院系统原来要6000多元一套,现在的价格为4000元左右。

    由于采用迷你音箱,相应的功放电路也没有那么考究,所以迷你音响的音质不能用HiFi标准来要求。当然,在音质音色方面,也有高低之分,很容易听出来,这自然也在价格上体现出来。

    什么是好的音质呢?这个问题回答起来并不容易—上佳的音质并不是一个放之四海皆准的标准,每个人都有各自的鉴定品位,对于家庭消遣用的迷你家庭影院来说,能够充分表现澎湃的动感和身临其境的环绕感是首当其冲的要素,而前者要求低音的表现力,后者要求从单元到功放整套系统的良好配合。

    可以说,愈来愈成熟的技术也让卫星式扬声器的声音品质提升。只要与系统搭配的主动式超低音在音频的连接上有足够的水准,形成的音响空间一样是可以有高度的立体性以及震撼性。

    而从记者在市场里试听的不同价位迷你家庭影院来看,售价在1800元以上的机型都能够达到满意的低音效果,看高质量的电影完全能够胜任。但是如果要求更好的音乐效果,则需要更好中音以及高音的效果。通常一两千元价位的机型的主音箱多使用了全频段扬声器,很少使用两分频或者三分频技术,因此音乐效果就很勉强。

    除了音质,产品的外观以及品牌也成为消费者购买迷你家庭影院的主要因素。据王利君介绍,购买迷你家庭影院的主要消费者大多数是年轻人,他们更容易接受新事物,而且对外观小巧、美观的产品格外喜欢。此外,品牌也是影响消费者在选择迷你家庭影院的决定性因素。安桥、索尼等外资品牌仍然深受消费者依赖。因此对国内企业来说,提高品牌美誉度是相当重要的。

    玩音响玩得精的,被称之为“发烧友”,他们把器材、碟片当作了生活中的重要伴侣。与之相比,一般弄套音响,听听音乐、看看DVD的人,则可称之为“菜鸟”。但菜鸟有菜鸟的好处,听音乐看家庭影院,无非作为生活的调料,既无需将器材研究得很深,也不必把买一套音响看得非常复杂,只要抓住几点要素,就可以选购到与自己匹配的音响。匹配,非常要紧。

  要素1:面对家居面积

  多大的块头,穿多少尺码的衣服。一套音响与其听音环境面积大小的关系也类似。如果面积小,而扬声器“大”了,其实是浪费,所以够用是原则。

  一般讲,20平方米以下的,可以选小型的书架式扬声器,就完全够用了。书架式扬声器各种好的品牌都有,便宜的,一对在3000元至5000元;中等价格在5000元至10000元左右;当然,还有万元以上的,这要根据自己的经济条件。

  20平方米到35平方米之间的,可以选中小型落地音箱,便宜的一对在4000元至8000元,中等价格在8000元至15000元,当然,还有更贵的。

  35平方米以上的,应选择大型落地音箱,一对的价格一般应在7000元以上。

  要素2:听音乐类型

  欧洲古典音乐、流行音乐、爵士音乐、摇滚音乐、轻音乐、人声歌唱等,音箱都有偏向性,品牌音箱都各有擅长,以满足不同的音乐的要求。一百样都行的音箱,是杂烩,哪一样都不精彩。

    所以要了解自己主要喜欢听哪一类音乐。

    美国品牌,如JBL、M&K(米勒·凯乐)等,比较擅长爵士乐、摇滚乐、现场音乐;

  英国品牌,如天朗、KEF、美声等,比较适合古典音乐、弦乐、人声歌唱;

  丹麦品牌,如尊宝、皇冠、DALI等,适合流行音乐及轻音乐;
  德国品牌,如MBL、柏林之声、意力等,适合古典音乐,特别是交响乐;

  日本品牌,如YAMAHA、天龙、安桥等,主要讲究多功能影院效果。
  说得再细一些,如果是喜欢大动态、偏向低音效果的,像迪士科、摇滚,应选大口径单元音箱,这每个品牌都有,但宜偏向选择美国品牌的;喜欢细腻、甜美、温柔一点的,像小提琴、人声歌剧(特别是女声),宜选择英国品牌;如果想兼顾家庭影院,又想唱唱卡拉OK的,选丹麦品牌与日本品牌。

  要素3:资金分配合理

  一套音响系统,主要由音箱、功放、碟机组成。三者资金的合理比例,音箱应占系统的50%-60%,功放占30%,碟机占10%。
  在7000元-12000元之间的,推荐几个价格与效果比较合适的组合:
  丹麦原装达尼C6主音箱与雅马哈550功放,价格约在6000多元;
  天朗SENSYS2主音箱与天龙1905功放,价格约在8000多元;
  法国原装劲浪725主音箱与天龙1604功放、中置环绕,约在万元。

  购配卖场推荐

  配音响,很多人图便宜,也不懂,随便找地方买,往往弄回家一堆大箱子。
  建议到专业的音响大卖场选购,产品及售后服务可以得到保证。上海比较大的卖场有:淮海中路香港新世界大厦的佳音视听广场、徐家汇美罗城的国际音响广场及中百一店的音响广场等。

  菜鸟AV选购秘方

  AV就是视听唱系统,也就是常说的家庭影院。现在的AV设计上比较前卫,科技含量越来越高,操作简单而且人性化。

  作为菜鸟,选购AV,宜套装为主要选择,就是功放、主音箱、中置、环绕、影碟机整个系统一体化,一个品牌的,甚至连屏幕都是同一个品牌的。这有个相当重要的好处,售后服务可以统一做,免得功放说是因为音箱有问题,而音箱又推说影碟机不匹配。

  几点注意:誗品牌与质量、服务很有关系,宜选大品牌;誗要仔细察看标识,功放的面板上是否标出DTS、AC-3、3C认证等标识;

   誗注意采用的音效系统,AC-3、DTS、DTS-ES等,音效系统越来越先进,而且这些音效系统向下兼容,向上不兼容。现在市面上AC-3的碟片居多,但可能越来越多的新片子采用DTS甚至DTS-ES,如果只有AC-3的机器,看DTS的片子效果就出不来。

  如果一定要自己配音箱,无论5.1声道、6.1声道,所有的箱子都要等功率。比如主音箱是100W的,那么环绕、中置也应该是100W的,不要贪便宜环绕弄个50W的,不然后面没有效果,比如炮弹炸响,前方声音正常,而后方声音却像闷枪。

  一点要求:售后服务,要求商家和厂家都能够上门安装、调试。

名称

数据格式

客户端

网址

备注

公司

国外
Google Earth 卫星影像 http://earth.google.com 估计是java技术 Google
Microsoft Live Local 卫星影像、栅格 http://preview.local.live.com   Microsoft
WorldWind 卫星影像 http://worldwind.arc.nasa.gov 智能客户端技术 NASA
Google Map 栅格地图 http://maps.google.com 可叠加卫星影像,提供API Google
http://www.google.com/apis/maps/
Yahoo 栅格地图 http://developer.yahoo.net/maps/ 提供API Yahoo
MSN Virtual Earth 未知   http://www.virtualearth.com   Microsoft
feedmap 栅格地图 http://www.feedmap.net/BlogMap/    
国内
Go2Map 栅格地图 http://www.go2map.com/down/freemap/ 提供城市地图服务和API Sohu
新浪爱问 栅格地图 http://local.sina.com.cn 地图搜索服务 Sina
Mapabc 栅格地图 http://www.mapabc.com 地图搜索服务,提供地图名片  
Mapbar 栅格地图 http://www.mapbar.com 地图搜索服务,提供博客地图  
我要地图 栅格地图 http://www.51ditu.com 地图搜索服务  
搜狗地图 栅格地图 http://map.sogou.com Sohu收购Go2Map后推出的地图搜索服务 Sohu  
baidu 栅格地图 http://map.baidu.com MapBar为baidu提供地图服务  

    关于Access97的密码破解,在很多的网站和杂志上都有过介绍。在这里我简单重复一下。

 

在mdb文件第0x42字节处的13个字节分别与0x86,0xfb,0xec,0x37,0x5d,0x44,0x9c,0xfa,0xc6,0x5e,0x28,0xe6,0x13异或后即可得到数据库的密码。但在Access 2000和2002的版本里密钥不再是固定的13个字节.而且加密的方式也有了变化。

 

经过ccrun用一下午的时间研究,终于将Access2000的加密方式搞清楚了。嘿嘿。在此将偶的心得发布,希望对大家有用。

 

我用的分析工具是UltraEdit32 v10.00,编程工具是C++ Builder 6.0。

 

经过用UltraEdit32分析,发现Access2000和Access2002的数据库加密方式相同,所以以下只针对Access2000的mdb文件。还有就是我用的是16进制的数表示,所以前面加了0x,如果你用的是VB或其他,要注意数值哦。

 

首先用AccessXP创建了一个空密码的数据库文件db1.mdb,包含一个表,其中有一个字段,没有填任何数据。保存退出然后复制一份为db2.mdb,以独占方式打开2.mdb,并加上密码1324567890123 保存退出。

 

用UltraEdit32打开这两个数据库,并进行比较。我比较的方法也很简单。在UltraEdit32中,快速的来回点击被打开文件的选项卡(就是在两个文件间来回切换,呵呵。笨办法吧),发现从文件头开始0x42字节处发生变化。

 

 

db1.mdb
00000040h:BC 4E BE 68 EC 37 65 D7 9C FA FE CD 28 E6 2B 25 ;
00000050h:8A 60 6C 07 7B 36 CD E1 DF B1 4F 67 13 43 F7 3C ; 


00000060h:B1 33 0C F2 79 5B AA 26 7C 2A 4F E9 7C 99 05 13 ;
db2.mdb
00000040h:BC 4E 8F 68 DE 37 56 D7 A8 FA CB CD 1E E6 1C 25 ;
00000050h:B2 60 55 07 4B 36 FC E1 ED B1 7C 67 13 43 F7 3C ;

00000060h:B1 33 0C F2 79 5B AA 26 7C 2A 4F E9 7C 99 05 13 ;

 

为了看的清楚些,我把不同的字节加了颜色。看出门道了吧,Access97以后的版本里,密码字节不再是连续存放,而是隔一个字节存一个。并且经过加密。到于解密的方法嘛,还是用老办法“异或”!0xBE ^ 0x8F = 0x31,这正好是Ascii码"1"哦。下一个0xEC ^ 0xDE = 0x32 正好是Ascii码"2",呵呵。一直到最后一个不同的0x4F ^ 0x7C =0x33,将取得的字符合成字符串,便是密码明文“1234567890123",千万不要以为这样就收工了。因为这一次是正好碰对了。呵呵。我刚开始也以为就这么简单,于是用CB做了个小程序,试着解了几个mdb密码都还行,可是试到动网论坛的mdb文件时发现取出来的密码不对,晕了。于是用另外一个取mdb密码的工具看了一下,发现人家的就可以正确的取出密码,是Access2000的格式,于是感觉微软加密的方式还是没研究完。继续工作,用UltraEdit32打开动网论坛的数据库dvbbs.mdb,和我前面的加过密的数据库做比较,发现不同的地方很多。只好一个字节一个字节的试。。。。nnn次以后发现第0x62处的这个字节起着关键作用,暂称之为加密标志。

 

 

db1.mdb //空密码
00000040h:BC 4E BE 68 EC 37 65 D7 9C FA FE CD 28 E6 2B 25 ;
00000050h:8A 60 6C 07 7B 36 CD E1 DF B1 4F 67 13 43 F7 3C ;

00000060h:B1 33 0C F2 79 5B AA 26 7C 2A 4F E9 7C 99 05 13 ;

db2.mdb //密码为:1234567890123
00000040h:BC 4E 8F 68 DE 37 56 D7 A8 FA CB CD 1E E6 1C 25 ;
00000050h:B2 60 55 07 4B 36 FC E1 ED B1 7C 67 13 43 F7 3C ;

00000060h:B1 33 0C F2 79 5B AA 26 7C 2A 4F E9 7C 99 05 13 ;

dvbbs.mdb //密码为:yemeng.net

00000040h:BC 4E DB 6A 89 37 14 D5 F9 FA 8C CF 4F E6 19 27 ;

00000050h:E4 60 15 05 0F 36 D1 E3 DF B1 53 65 13 43 EB 3E ;

00000060h:B1 33 10 F0 79 5B B6 24 7C 2A 4A E0 7C 99 05 13 ;

 

怎么试呢,还是异或。取0x42处开始的字节0xDB与空密码文件的0x42处字节异或,取0x62处的加密标志与空密码文件0x62处字节异或,然后再把取得的两个值相异或:

 

(0xDB^0xBE)^(0x10^0x0C)=0x79 嘿嘿。这个值是Ascii的"y",然后取下一个字节(记得隔一个字节取一个)

 

(0x89^0xEC)^(0x10^0x0C)=0x79 咦,本来这个字节应该是"e"的,怎么变成"y"了?试着不与后面的两个异或值相异或,只计算0x89^0xEC=0x65 得到"e",哈。这下对了。下一个

 

(0x14^0x65)^(0x10^0C)=0x6D 得到"m",下一个

 

(0xF9^9C)=0x65 得到"e",注意这里只是这两个数异或。后面的大家可以自己试。

 

这样就总结出规律来了。

 

解密时,先取出加密文件从文件头开始0x62处的字节,与空密码数据库文件第0x62处相异或,得到一个加密标志。

 

再从0x42处开始每隔一个字节取一个字节,取得13个加密后的密码字节,分别与空密码数据库文件0x42处每隔一个字节取得的13个字节想异或,得到13个密码半成品。为什么说是半成品呢,因为还要将13个字节的密码每隔一个字节,就与加密标志相异或,最后得到的13个字节才是真正的密码。当然,如果中间有0x0的字节,则说明密码位数不够13位。直接show出来就可以了。

 

另外我发现加密标志会随着时间或机器不同而不同,所以也没有万能的,不过有一个参照的就可以了。以下代码是我在写这个程序的时候取得的数,和我写这篇文章不是一个时间,所以数值不一样,但最终解密的结果是一样的。大家可以参考一下。

 

对了,还有个重要的就是先得判断数据库的版本,我用了个简单的办法,取0x14处的字节,如果为0就判断为是Access97,如果为1就认为是Access2000或2002的。只是目前没有研究出判断2000和2002的办法,如果哪位知道的话,请指点。

 

代码:

 

//这里定义的是13个字节作为Access2000异或的源码。与之相对应的加密标志是0x13,ccrun特此注明

 

//当然你可以用这一组:BE EC 65 9C FE 28 2B 8A 6C 7B CD DF 4F 与这一组相对应的加密标志是0x0c

 

//呵呵.程序有些乱,希望大家能看的懂。

 

 

char PassSource2k[13]=
{0xa1,0xec,0x7a,0x9c,0xe1,0x28,0x34,0x8a,0x73,0x7b,0xd2,0xdf,0x50}; //Access97的异或源码 char PassSource97[13]=
{0x86,0xfb,0xec,0x37,0x5d,0x44,0x9c,0xfa,0xc6,0x5e,0x28,0xe6,0x13};   void __fastcall TMainForm::GetMdbPass() { char PassStrTemp[26],Ver,EncrypFlag,t1; int FileHandle; String MdbPassword,MdbVersion,MdbFileName; FileHandle=FileOpen(MdbFileName,fmOpenRead); if(FileHandle<0) { ShowMessage("文件打开错误!"); return; } //取得数据库版本 FileSeek(FileHandle,0x14,0); FileRead(FileHandle,&Ver,1); //取得加密标志 FileSeek(FileHandle,0x62,0); FileRead(FileHandle,&EncrypFlag,1); //读取加密后的密码到缓冲区 FileSeek(FileHandle,0x42,0); FileRead(FileHandle,&PassStrTemp,26); FileClose(FileHandle); if(Ver<1) { MdbVersion="Access 97"; if(int(PassStrTemp[0]^PassSource97[0])==0) MdbPassword="密码为空!"; else { MdbPassword=""; for(int i=0;i<13;i++) MdbPassword=MdbPassword+char(PassStrTemp^PassSource97); } } else { MdbVersion="Access 2000 or 2002"; MdbPassword=""; for(int i=0;i<13;i++) { if(i%2==0) t1=char(0x13^EncrypFlag^PassStrTemp[i*2]^PassSource2k); //每隔一个字节就与加密标志相异或。这里的加密标志为0x13 else t1=char(PassStrTemp[i*2]^PassSource2k); MdbPassword=MdbPassword+t1; } } if(MdbPassword[1]<0x20||MdbPassword[1]>0x7e) MdbPassword="密码为空!"; EditMdbFileName->Text=MdbFileName; EditMdbPassword->Text=MdbPassword; EditMdbVersion->Text=MdbVersion; }


影响共享软件发展的因素很多,被非法破解可以说是共享软件的头号大敌。那么造成共享软件生存困难的cracker们到底用了那些武器呢?今天就让我让带您去看看神秘的cracker常用的十类软件,它们就是共享软件的十大杀手!

  一. 调试类工具soft-ice和trw2000

  soft-ice是目前公认最好的跟踪调试工具。使用soft-ice可以很容易的跟踪一个软件、或是监视软件产生的错误进行除错,它有dos、window3.1、win95/98/nt/2000/各个平台上的版本。这个本是用来对软件进行调试、跟踪、除错的工具,在cracker手中变成了最恐怖的破解工具;trw2000是中国人自己编写的调试软件,完全兼容soft-ice各条指令,由于现在许多软件能检测soft-ice存在,而对trw2000的检测就差了许多,因此目前它成了很多cracker的最爱。trw2000专门针对软件破解进行了优化,在windows下跟踪调试程序,跟踪功能更强;可以设置各种断点,并且断点种类更多;它可以象一些脱壳工具一样完成对加密外壳的去除,自动生成exe文件,因此它的破解能力更强,在破解者手中对共享软件的发展威胁更大。它还有在dos下的版本,名为tr。

  二. 反汇编工具wdasm8.93黄金版和hiew

  cracker常将soft-ice和trw2000比作屠龙刀,将wdasm8.93则比作倚天剑。wdasm8.93可方便地反汇编程序,它能静态分析程序流程,也可动态分析程序。在原有的普通版的基础上,一些破解者又开发出了wdasm8.93黄金版,加强了对中文字符串的提取。对国产共享软件的威胁也就更大了。例如开心斗地主这个很好玩的共享软件,用黄金版对其反汇编可以直接看到注册码,普通版不能,您说它厉害不?hiew是一个十六进制工具,它除了普通十六进制的功能外,它还有个特色,能反汇编文件,并可以用汇编指令修改程序, 用它修改程序,方便快捷!这也是cracker们常用的静态反汇编工具。

  三. visual basic程序调试工具smartcheck

  这是专门针对visual basic程序的调试程序,由于vb程序执行时从本质上讲是解释执行,它们只是调用 vbrunxxx.dll 中的函数 ,因此vb 的可执行文件是伪代码,程序都在vbxxx.dll 里面执行。若用soft-ice跟踪调试只能在vbdll里面用打转转,看不到有利用价值的东西,而且代码质量不高,结构还很复杂。当然只要了解其特点用soft-ice也可破解 ,但smartcheck的出现,大大方便了cracker。smartcheck 是 numega 公司出口的一款出色的调试解释执行程序的工具,目前最新版是v6.03。它非常容易使用,你甚至于不需要懂得汇编语言都能轻易驾驭它。它可将vb程序执行的操作完全记录下来,使破解者轻而易举的破解大部分vb程序。

  四. 十六进制编辑器ultraedit

  十六进制编辑器可以用十六进制方式编辑文件,修改文件的内容。虽然hiew就是一款是十六进制工具,但它是dos界面,因此很多破解者又准备了一款windows下的工具,这样的工具很多,如:ultraedit、winhex、hex workshop 等,其中ultraedit比较有特色,操作方便,更有汉化版可用,它是非常出色的十六进制编辑器,建议您也找一个用用。

  五. 注册表监视工具

  主要有regshot、regmon或regsnap等。在微软操作系统中,众多的设置都存放在注册表中,注册表是windows的核心数据库,表中存放着各种参数,直接控制着windows的启动、硬件驱动程序的装载以及一些windows应用程序的正常运行。在应用软件安装时,有可能将一些必要的信息放进去,如安装时间、使用次数、注册码等。regshot、regmon或regsnap就是监视注册表变化的工具,通过它可以了解、监视应用程序在注册表中的动作,破解者常利用它们来监视应用程序在注册表中的变化。

六. 文件监视工具filemon

  可监视系统中指定文件运行状况,如指定文件打开了哪个文件,关闭了哪个文件,对哪个文件进行了数据读取等。通过它,任何您指定监控的文件有任何读、写、打开其它文件的操作都能被它监视下来,并提供完整的报告信息。破解者经常利用filemon监控文件系统,以便了解程序在启动、关闭或验证注册码时做了哪些手脚,并由此进行相应的解密。

  七. 脱壳工具procdump

  现在许多软件都加了壳,“壳”是一段专门负责保护软件不被非法修改或反编译的程序。它们一般都是先于程序运行,拿到控制权,然后完成它们保护软件的任务。经过加壳的软件在跟踪时已无法看到其真实的十六进制代码,因此可以起到保护软件的目的。procdump就是个对付软件加壳的脱壳工具,它可剥去许多种壳,还文件本来面目,这样再修改文件内容就容易多了。由于它还允许使用者自己编写脚本文件,因此利用它能脱去新版加壳软件的壳。它同时还是一款优秀的pe格式修改工具,是脱壳必备工具!

  八. 侦测文件类型工具

  这样的工具有typ、gtw、fileinfo和冲击波2000等。它们被用来侦测软件被加壳类型,其中冲击波2000能轻易的找到任何加密壳的入口点,包括asprotect以及幻影的加密壳都可以。这类软件一般是配合procdump和调试软件使用的,用它们找到程序加壳类型,用procdump或soft-ice、trw2000脱壳。

  九. 资源修改器 exescope

  exescope是一个可以修改软件资源的工具,功能强大。 exescope能在没有资源文件的情况下分析、显示不同的信息,重写可执行文件的资源,包括(exe,dll,ocx)等。它可以直接修改用 vc++ 及 delphi 编制的程序的资源,包括菜单、对话框、字串表等,是汉化软件的常用工具。在破解者手中,它常被用来修改文件资源中的菜单、对话框、字串表等,用以显示破解者需要的信息(例如更改版权信息等),以此达到修改软件的目的。

  十. api调用查询工具api spy

  顾名思义,这个程序是用来侦测软件都调用了哪些api。 api就是windows程序执行时所呼叫的函数,跟dos下的int(中断)差不多,windows 提供了很多这样的函数让程序设计者套用,主要目的是为了节省软件开发的时间,方便大家开发软件。api spy就是这样一个监控api调用的软件,它可以查看应用程序调用了哪些api,从而得出对破解者有用的api调用信息,通过这些api调用来设定断点,达到破解软件的目的。它可以工作在windows95/98/nt/2000平台下。

  好了,共享软件的十大杀手为您介绍完了,如何对付它们就是您的事了。需要说明的一点是,以上提到的软件都是“正当”软件,只是在不同的使用者手中发挥了不同的用途。就犹如一把枪,在人民军队手中就是保家卫国的武器,在为非作歹的坏人手中就是一把凶器了,千万不能此就对这些软件产生成见哦!

How to Create RHEL-4 DVD from CDs Reply with quote
*Setting up the build directory:*

The first thing to do is to copy all the cdrom ISOs to one location:
mkdir -p /mnt/disk{1,2,3,4}
mount -o loop RHEL4-U1-i386-AS-disc1.iso /mnt/disk1
mount -o loop RHEL4-U1-i386-AS-disc2.iso /mnt/disk2
mount -o loop RHEL4-U1-i386-AS-disc3.iso /mnt/disk3
mount -o loop RHEL4-U1-i386-AS-disc4.iso /mnt/disk4

We now copy all the files from the directories to a single directory:
mkdir -p /data/isobuild
rsync -rv /mnt/disk{4,3,2,1}/* /data/isobuild/

We also need to copy across the .diskinfo file that is not caught by our *:
cp /mnt/disk1/.diskinfo /data/isobuild/

The .diskinfo file identifies the CD as being a correct Red Hat Installer disk
and is checked by anaconda during the start of the install.

We could now build the DVD as it is but we really should have a fiddle first Smile

*Adding more software to the DVD*
We could add some of our own rpms to /data/isobuild/RedHat/RPMS; however by just
doing this does not make them available at install time. There is an XML file
that is read and ensures that the packages are installed in the correct order.

So let us throw a few random packages into the mix:

Add some java:
cp jre-1_5_0_03-linux-i586.rpm /data/isobuild/RedHat/RPMS/

Some encryption for GAIM:
cp gaim-encryption-2.36-3.rf.i386.rpm /data/isobuild/RedHat/RPMS/

*Updating the comps.xml file*
We need to ensure that the host computer has anaconda and anaconda-runtime installed:
up2date anaconda anaconda-runtime

Before we update the XML dependency file we need to sort out package orders.
If you have added a lot of new packages you may need to remove some old
packages that you have replaced with newer versions to stop conflicts.

So the first command is:
PYTHONPATH=/usr/lib/anaconda /usr/lib/anaconda-runtime/pkgorder /data/isobuild/ i386 > /data/isobuild/xander-pkgorder

This creates a list of files in the order it needs to install them
in the file /data/isobuild/xander-pkgorder. Sometimes an occasional
RPM will not provide the information anaconda needs. You can edit
the file manually and insert your RPMs at the end.

Next we need to generate the dependency file:

/usr/lib/anaconda-runtime/genhdlist –fileorder /data/isobuild/xander-pkgorder /data/isobuild/

You will probably have a few hiccoughs the first time you run these commands.
Most may be resolved by adding the missing entries to the pkgorder file or
deleting duplicate packages.

*Creating an automated installer*
We could *now* if we wanted to build our DVD; however we can make an
automated installer.

So crack open system-config-kickstart and create a kickstart file with
all the packages and partitioning etc you need for your systems.

copy the resulting file to /data/isobuild/ks.cfg

we can now edit the file /data/isobuild/isolinux/isolinux.cfg

copy or change the three lines:
label linux
kernel vmlinuz
append initrd=initrd.img ramdisk_size=8192

to
label xander
kernel vmlinuz
append initrd=initrd.img ramdisk_size=8192 ks=cdrom:/ks.cfg

Then change the default at the top of the file to xander. This means that
the default action is to install directly from the DVD using your kickstart file.

*Building the DVD iso*
Now to build the iso:

cd /data/isobuild

chmod a+w isolinux/isolinux.bin

mkisofs -r -T -J -V "Custom RHEL4 Build" -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o /data/custom-RHEL4-dvd.iso /data/isobuild/

*Buring the DVD*
Now we can burn the image to the CD. I assume the CD writer is already
set up on your system. We use cdrecord below, but you can use other
programs as well. The command is invoked as:

cdrecord -v speed=4 dev=0,0,0 /data/custom-RHEL4-dvd.iso

The speed and dev options depend on your system. The device for the dev
argument can be determined by using the -scanbus option to cdrecord:

cdrecord -scanbus

Using the DVD

Once the image is burned onto the DVD, insert the DVD into the target
machine and boot the machine. You should get the custom message that
you created earlier. At this point, you can either press Enter at the
boot prompt or let it timeout. When it times out it uses the default
label, which we specified as ks (Kickstart).

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace BaseStationPDA
{
 class GPS
 {

  public string PortNum;
  public int BaudRate;
  public byte ByteSize;
  public byte Parity; // 0-4=no,odd,even,mark,space
  public byte StopBits; // 0,1,2 = 1, 1.5, 2
  public int ReadTimeout;
  
  //comm port win32 file handle
  private int hComm = -1;
  
  public bool Opened = false;
  
  //win32 api constants
  private const uint GENERIC_READ = 0x80000000;
  private const uint GENERIC_WRITE = 0x40000000;
  private const int OPEN_EXISTING = 3;  
  private const int INVALID_HANDLE_VALUE = -1;
  
  [StructLayout(LayoutKind.Sequential)]
   public struct DCB
  {
   //taken from c struct in platform sdk
   public int DCBlength;           // sizeof(DCB)
   public int BaudRate;            // 指定当前波特率 current baud rate
   // these are the c struct bit fields, bit twiddle flag to set
   public int fBinary;          // 指定是否允许二进制模式,在windows95中必须主TRUE binary mode, no EOF check
   public int fParity;          // 指定是否允许奇偶校验 enable parity checking
   public int fOutxCtsFlow;      // 指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起。 CTS output flow control
   public int fOutxDsrFlow;      // 指定CTS是否用于检测发送控制 DSR output flow control
   public int fDtrControl;       // DTR_CONTROL_DISABLE值将DTR置为OFF, DTR_CONTROL_ENABLE值将DTR置为ON, DTR_CONTROL_HANDSHAKE允许DTR"握手" DTR flow control type
   public int fDsrSensitivity;   // 当该值为TRUE时DSR为OFF时接收的字节被忽略 DSR sensitivity
   public int fTXContinueOnXoff; // 指定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止。TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出XoffChar字符中止接收字节之后,发送继续进行。 FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之后,发送继续进行。XOFF continues Tx
   public int fOutX;          // TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始 XON/XOFF out flow control
   public int fInX;           // TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去 XON/XOFF in flow control
   public int fErrorChar;     // 该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误的接收字符 enable error replacement
   public int fNull;          // eTRUE时,接收时去掉空(0值)字节 enable null stripping
   public int fRtsControl;     // RTS flow control
   /*RTS_CONTROL_DISABLE时,RTS置为OFF
            RTS_CONTROL_ENABLE时, RTS置为ON
            RTS_CONTROL_HANDSHAKE时,
            当接收缓冲区小于半满时RTS为ON
             当接收缓冲区超过四分之三满时RTS为OFF
            RTS_CONTROL_TOGGLE时,
            当接收缓冲区仍有剩余字节时RTS为ON ,否则缺省为OFF*/

   public int fAbortOnError;   // TRUE时,有错误发生时中止读和写操作 abort on error
   public int fDummy2;        // 未使用 reserved
   
   public uint flags;
   public ushort wReserved;          // 未使用,必须为0 not currently used
   public ushort XonLim;             // 指定在XON字符发送这前接收缓冲区中可允许的最小字节数 transmit XON threshold
   public ushort XoffLim;            // 指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数 transmit XOFF threshold
   public byte ByteSize;           // 指定端口当前使用的数据位 number of bits/byte, 4-8
   public byte Parity;             // 指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY  0-4=no,odd,even,mark,space
   public byte StopBits;           // 指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS  0,1,2 = 1, 1.5, 2
   public char XonChar;            // 指定用于发送和接收字符XON的值 Tx and Rx XON character
   public char XoffChar;           // 指定用于发送和接收字符XOFF值 Tx and Rx XOFF character
   public char ErrorChar;          // 本字符用来代替接收到的奇偶校验发生错误时的值 error replacement character
   public char EofChar;            // 当没有使用二进制模式时,本字符可用来指示数据的结束 end of input character
   public char EvtChar;            // 当接收到此字符时,会产生一个事件 received event character
   public ushort wReserved1;         // 未使用 reserved; do not use
  }

  [StructLayout(LayoutKind.Sequential)]
   private struct COMMTIMEOUTS
  { 
   public int ReadIntervalTimeout;
   public int ReadTotalTimeoutMultiplier;
   public int ReadTotalTimeoutConstant;
   public int WriteTotalTimeoutMultiplier;
   public int WriteTotalTimeoutConstant;
  }  

  [StructLayout(LayoutKind.Sequential)] 
   private struct OVERLAPPED
  {
   public int  Internal;
   public int  InternalHigh;
   public int  Offset;
   public int  OffsetHigh;
   public int hEvent;
  } 
  
  [DllImport("coredll.dll")]
  private static extern int CreateFile(
   string lpFileName,                         // 要打开的串口名称
   uint dwDesiredAccess,                      // 指定串口的访问方式,一般设置为可读可写方式
   int dwShareMode,                          // 指定串口的共享模式,串口不能共享,所以设置为0
   int lpSecurityAttributes, // 设置串口的安全属性,WIN9X下不支持,应设为NULL
   int dwCreationDisposition,                // 对于串口通信,创建方式只能为OPEN_EXISTING
   int dwFlagsAndAttributes,                 // 指定串口属性与标志,设置为FILE_FLAG_OVERLAPPED(重叠I/O操作),指定串口以异步方式通信
   int hTemplateFile                        // 对于串口通信必须设置为NULL
   );
  [DllImport("coredll.dll")]
  private static extern bool GetCommState(
   int hFile,  //通信设备句柄
   ref DCB lpDCB    // 设备控制块DCB
   ); 
  [DllImport("coredll.dll")]
  private static extern bool BuildCommDCB(
   string lpDef,  // 设备控制字符串
   ref DCB lpDCB     // 设备控制块
   );
  [DllImport("coredll.dll")]
  private static extern bool SetCommState(
   int hFile,  // 通信设备句柄
   ref DCB lpDCB    // 设备控制块
   );
  [DllImport("coredll.dll")]
  private static extern bool GetCommTimeouts(
   int hFile,                  // 通信设备句柄 handle to comm device
   ref COMMTIMEOUTS lpCommTimeouts  // 超时时间 time-out values
   ); 
  [DllImport("coredll.dll")] 
  private static extern bool SetCommTimeouts(
   int hFile,                  // 通信设备句柄 handle to comm device
   ref COMMTIMEOUTS lpCommTimeouts  // 超时时间 time-out values
   );
  [DllImport("coredll.dll")]
  private static extern bool ReadFile(
   int hFile,                // 通信设备句柄 handle to file
   byte[] lpBuffer,             // 数据缓冲区 data buffer
   int nNumberOfBytesToRead,  // 多少字节等待读取 number of bytes to read
   ref int lpNumberOfBytesRead, // 读取多少字节 number of bytes read
   ref OVERLAPPED lpOverlapped    // 溢出缓冲区 overlapped buffer
   );
  [DllImport("coredll.dll")] 
  private static extern bool WriteFile(
   int hFile,                    // 通信设备句柄 handle to file
   byte[] lpBuffer,                // 数据缓冲区 data buffer
   int nNumberOfBytesToWrite,     // 多少字节等待写入 number of bytes to write
   ref int lpNumberOfBytesWritten,  // 已经写入多少字节 number of bytes written
   ref OVERLAPPED lpOverlapped        // 溢出缓冲区 overlapped buffer
   );
  [DllImport("coredll.dll")]
  private static extern bool CloseHandle(
   int hObject   // handle to object
   );
  [DllImport("coredll.dll")]
  private static extern uint GetLastError();
  
  public void Open()
  {
  
   DCB dcbCommPort = new DCB();
   COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS(); 
    
   // 打开串口 OPEN THE COMM PORT.
   hComm = CreateFile(PortNum ,GENERIC_READ | GENERIC_WRITE,0, 0,OPEN_EXISTING,0,0);
   // 如果串口没有打开,就打开 IF THE PORT CANNOT BE OPENED, BAIL OUT.
   if(hComm == INVALID_HANDLE_VALUE)
   {
    throw(new ApplicationException("非法操作,不能打开串口!"));
   }
  
   // 设置通信超时时间 SET THE COMM TIMEOUTS.
   GetCommTimeouts(hComm,ref ctoCommPort);
   ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;
   ctoCommPort.ReadTotalTimeoutMultiplier = 0;
   ctoCommPort.WriteTotalTimeoutMultiplier = 0;
   ctoCommPort.WriteTotalTimeoutConstant = 0; 
   SetCommTimeouts(hComm,ref ctoCommPort);
  
   // 设置串口 SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
   GetCommState(hComm, ref dcbCommPort);
   dcbCommPort.BaudRate=BaudRate;
   dcbCommPort.flags=0;
   //dcb.fBinary=1;
   dcbCommPort.flags|=1;
   if (Parity>0)
   {
    //dcb.fParity=1
    dcbCommPort.flags|=2;
   }
   dcbCommPort.Parity=Parity;
   dcbCommPort.ByteSize=ByteSize;
   dcbCommPort.StopBits=StopBits;
   if (!SetCommState(hComm, ref dcbCommPort))
   {
    //uint ErrorNum=GetLastError();
    throw(new ApplicationException("非法操作,不能打开串口!"));
   }
   //unremark to see if setting took correctly
   //DCB dcbCommPort2 = new DCB();
   //GetCommState(hComm, ref dcbCommPort2);
   Opened = true;
  }
  
  public void Close()
  {
   if (hComm!=INVALID_HANDLE_VALUE)
   {
    CloseHandle(hComm);
   }
  }
  
  public byte[] Read(int NumBytes)
  {
   byte[] BufBytes;
   byte[] OutBytes;
   BufBytes = new byte[NumBytes];
   if (hComm!=INVALID_HANDLE_VALUE)
   {
    OVERLAPPED ovlCommPort = new OVERLAPPED();
    int BytesRead=0;
    ReadFile(hComm,BufBytes,NumBytes,ref BytesRead,ref ovlCommPort);
    try
    {
     OutBytes = new byte[BytesRead];
     Array.Copy(BufBytes,0,OutBytes,0,BytesRead);
    }
    catch
    {
     return BufBytes;
    }
    
   }
   else
   {
    throw(new ApplicationException("串口未打开!"));
   }
   return OutBytes;
   //   return BufBytes;
  }
  
  public void Write(byte[] WriteBytes)
  {
   if (hComm!=INVALID_HANDLE_VALUE)
   {
    OVERLAPPED ovlCommPort = new OVERLAPPED();
    int BytesWritten = 0;
    WriteFile(hComm,WriteBytes,WriteBytes.Length,ref BytesWritten,ref ovlCommPort);
   }
   else
   {
    throw(new ApplicationException("串口未打开!"));
   }  
  }

  public string GetGPS(string strGPS,string strFind)
  {
   ///从GPS中读取的数据中,找出想要的数据
   ///GPSstring原始字符串,
   ///strFind要查找的内容,X:经度,Y:纬度,T:时间,V:速度,是数字从1开始,即以“,”分隔的位置
   ///返回查找到指定位置的字符串
   string handerStr="$GPRMC";//GPS串头
   int findHander=strGPS.IndexOf(handerStr);//看是否含有GPS串头
   if (findHander<0)
   {
    return "-1";
   }
   else
   {
    strGPS=strGPS.Substring(findHander,strGPS.Length-findHander);
    string[] ArryTmp=strGPS.Split(",".ToCharArray());
    try
    {
     if(ArryTmp[2]=="V")
     {
      return "V";//没有信号
     }
     else
     {
      switch(strFind)
      {
       case "X":
        return DM2DD(ArryTmp[5]);
        
       case "Y":
        return DM2DD(ArryTmp[3]);
        
       case "T":
        return T2Time(ArryTmp[9],ArryTmp[1]);
        
       case "V":
        return Convert.ToString(Convert.ToDouble(ArryTmp[7])* 1.852);
        
       default:
        return "V";
        
      }
     }
    }
    catch
    {
     return "V";
    }
   }
  }

  public string T2Time(string strDate,string strTime)
  {
   string dT="20"+strDate.Substring(4,2)+"-"+strDate.Substring(2,2)+"-"+strDate.Substring(0,2);
   string TT=Convert.ToString(Convert.ToInt32(strTime.Substring(0,2)))+":"+strTime.Substring(2,2)+":"+strTime.Substring(4,2);
   DateTime T=Convert.ToDateTime(dT+" "+TT);
   T=T.AddHours(8);
   return T.ToString();
  }

  public string DM2DD(string DegreeMinutes)
  {
   //转换NMEA协议的“度分”格式为十进制“度度”格式
   string sDegree;
   string sMinute;
   string sReturn="";
   if(DegreeMinutes.IndexOf(".")==4)
   {
    //DegreeMinutes = Replace(DegreeMinutes, ".", "")
    //DM2DD = CDbl(Left(DegreeMinutes, 2)) + CDbl(Left(CStr(CDbl(Right(DegreeMinutes, Len(DegreeMinutes) – 2)) / 60), 8)) / 10000
    DegreeMinutes=DegreeMinutes.Replace(".","");
    double sDegree1=Convert.ToDouble(DegreeMinutes.Substring(0,2));
    double sDegree2=Convert.ToDouble(DegreeMinutes.Substring(2,DegreeMinutes.Length-2));
    string sTmp=Convert.ToString(sDegree2/60);
    sDegree2=Convert.ToDouble(sTmp.Substring(0,sTmp.Length));
    sDegree2=sDegree2/10000;
    sDegree=Convert.ToString(sDegree1+sDegree2);
    if(sDegree.Length>11)
     sDegree=sDegree.Substring(0,11);
    sReturn=sDegree;
   }
   else if(DegreeMinutes.IndexOf(".")==5)
   {
    //DegreeMinutes = Replace(DegreeMinutes, ".", "")
    //DM2DD = CDbl(Left(DegreeMinutes, 2)) + CDbl(Left(CStr(CDbl(Right(DegreeMinutes, Len(DegreeMinutes) – 2)) / 60), 8)) / 10000
    DegreeMinutes=DegreeMinutes.Replace(".","");
    double sMinute1=Convert.ToDouble(DegreeMinutes.Substring(0,3));
    double sMinute2=Convert.ToDouble(DegreeMinutes.Substring(3,DegreeMinutes.Length-2));
    string sTmp=Convert.ToString(sMinute2/60);
    sMinute2=Convert.ToDouble(sTmp.Substring(0,sTmp.Length));
    sMinute2=sMinute2/10000;
    sMinute=Convert.ToString(sMinute1+sMinute2);
    if(sMinute.Length>10)
     sMinute=sMinute.Substring(0,10);
    sReturn=sMinute;
   }
   return sReturn;
  }

  public bool ScanPort()
  {
   
   try
   {
    if (Opened)
    {
     Close();
     Open();
    }
    else
    {
     Open();//打开串口
     
    }
    byte[] bytRead=Read(512);
    Close();
    if(Encoding.ASCII.GetString(bytRead,0,bytRead.Length).IndexOf("$GP")>=0)
     return true;
    else
     return false;
   }
   catch
   {
    return false;
   }

  }
 }

 class HexCon
 {
  // 把十六进制字符串转换成字节型和把字节型转换成十六进制字符串 converter hex string to byte and byte to hex string
  public static string ByteToString(byte[] InBytes)
  {
   string StringOut="";
   foreach (byte InByte in InBytes)
   {
    StringOut=StringOut + String.Format("{0:X2} ",InByte);
   }
   return StringOut;
  }
  public static byte[] StringToByte(string InString)
  {
   string[] ByteStrings;
   ByteStrings = InString.Split(" ".ToCharArray());
   byte[] ByteOut;
   ByteOut = new byte[ByteStrings.Length-1];
   for (int i = 0;i==ByteStrings.Length-1;i++)
   {
    ByteOut[i] = Convert.ToByte(("0x" + ByteStrings[i]));
   }
   return ByteOut;
  }
 }
}

在别的class中调用时如Frmlogoin(是通过一个时间控件来循环的)

public class Frmlogin : System.Windows.Forms.Form
 {

private GPS ss_port=new GPS();

}

#region 读取GPS
  private void opengps(string ComPoint)
  {
   ss_port.PortNum = ComPoint;
   ss_port.BaudRate = 4800;
   ss_port.ByteSize = 8;
   ss_port.Parity = 0;
   ss_port.StopBits = 1;
   ss_port.ReadTimeout = 1000;

   try
   {
    if (ss_port.Opened)
    {
     ss_port.Close();
     ss_port.Open();
     timer1.Enabled=true;
    }
    else
    {
     ss_port.Open();//打开串口
     timer1.Enabled=true;
    }
    
   }
   catch
    
   {
//    MessageBox.Show("读取GPS错误!" ,"系统提示");
    
   }
  }
  private void timer1_Tick(object sender, System.EventArgs e)
  {
   
   if (ss_port.Opened)
    gpsread();
   else
    ss_port.Open();//打开串口
  }
  
  private void gpsread()
  {
   byte[] aa=ss_port.Read(512);
   string gpsinfo =System.Text.Encoding.ASCII.GetString(aa,0,aa.Length);
   GetParam.GpsLongitude=ss_port.GetGPS(gpsinfo,"X");
   GetParam.GpsLatitude=ss_port.GetGPS(gpsinfo,"Y");
   GetParam.GpsSpeed=ss_port.GetGPS(gpsinfo,"V");
   GetParam.GpsTime=ss_port.GetGPS(gpsinfo,"T");
   if(GetParam.GpsLongitude=="-1")
    GetParam.GpsState="0";
   if(GetParam.GpsLongitude=="V" && GetParam.GpsLatitude=="V")
    GetParam.GpsState="0";
   if(GetParam.GpsLongitude!="-1" && GetParam.GpsLongitude!="V")
    GetParam.GpsState="1";

    GetParam.GpsLongitude=(GetParam.GpsLongitude=="V") ? "0" : GetParam.GpsLongitude;
    GetParam.GpsLatitude=(GetParam.GpsLatitude=="V") ? "0" : GetParam.GpsLatitude;
    GetParam.GpsSpeed=(GetParam.GpsSpeed=="V") ? "0" : GetParam.GpsSpeed;
    GetParam.GpsTime=(GetParam.GpsTime=="V") ? "0" :GetParam.GpsTime;
   
  }
  private void GpsClose()
  {
   timer1.Enabled=false;
   if (ss_port.Opened)
    ss_port.Close();
  }
  #endregion

昆明的天气还真是奇怪,今天下班的时候看着还出着太阳,而且还是很刺眼的那种。结果才走了一段路就开始下雨了,还下得好大。

这个是不是就是传说中的秋天的天气了:又出太阳又下雨,栽黄秧,吃白米。呵呵

 

图片附件:
image_319.jpg
图片附件:
image_320.jpg