2004-09-24
在黄色网站里迷失
时间: 2004-09-24 来源: 大学周刊 访问次数:20

    编者按:黄色网站的不断涌现,让我们不得不深思:这些浮华背后的隐藏者们到底都是些什么人?他们难道都是一群素质极其低下、没有受过什么文化教育的人吗?而随着公安机关的次次调查,慢慢浮出水面的竟然有很多是在校或者已经毕业的大学生……

事件回放

    1. 2004年8月,2名涉嫌制作黄色网站的犯罪嫌疑人、大学毕业生苏实和苏永被西城公安分局民警从厦门押送回京。这是北京开展打击黄色网站以来,破获的第一起服务器多层托管、网上传播淫秽物品案件。

    2. 毕业于沈阳某学院计算机专业的大学生刘某,发挥“专业特长”,在互联网上建立了一个淫秽网站——俏皮虎论坛网站。

    3. 2004年7月,江苏省扬州市两大色情淫秽网站,“情恋狼君娱乐天地专版”、 “棒棒糖工作室——免费激情电影资源”, 创办人分别为河北一家工程学院和山东某大学学生。

    4. 2004年8月,北京房山一个名为“山峰娱乐吧”的网站播放激情电影,涉及淫秽色情内容,创办人均毕业于某高校音乐系。

    5.  成都一个姓刘的大学生在国外建立了一名为“无尽诱惑”的黄色网站,被判处有期徒刑3年,缓刑4年,并处罚金2000元。

    恭小兵: 安徽黄山人。22岁出版单行本《我曾深深爱过谁》和《云端以上,水面以下》。中文界“80后”概念的提出者。

左手天理,右手人欲

    很多年前互联网还不普及的时候,在新华书店、“××书店”,常可以看到一些蔽衣遮体的民工在灰暗的“艺术专区”里徜徉。后来知道那是裸体艺术时,我又不禁有些可怜他们——为什么不像那些教授大师、西装革履的人物一样,把它们买回家去,细细品味呢?

    制黄贩黄者当然有罪,但也不可矫枉过正。最近成都两名学生浏览黄色网站被抓,引来一片哗然声。这一条新闻让那些看客们既吃惊又害怕:难道天生的爱色之心此时也变成了罪?于是互联网上的“淫民”们开始狡兔三窟。而众多饱学之士,也开始声讨起这种压抑人性的做法。

    有这么一个笑话,说警察把上色情网的男生全部抓去,那肯定会有人被冤枉;但要是隔一个抓一个的话,那肯定又有漏网的。这个笑话说明社会的需要是不可以否认的。如果说这种需要是罪恶的,那么只有没手淫过、做爱过的人才有权这样说。中国的封建由来已久,似乎今天犹有余毒,难不成只有“性冷感”才是高尚?鄙人只有一个祝福:愿中国的“性立法”也早日能像他们一样成熟,至少要像个正常人。

    胡坚:高中时代出版小说集《愤青时代》。2002年进入武汉大学中文系至今。兴趣广泛,爱好和平。在全国多家媒体发表各类文章若干,精通各类雕虫小技。

为有牺牲多壮志

    明末才子吴伟业有诗句:“错恣狂风扬落花,无边春色来天地”,十四个字无比精确地概括了正在我们面前徐徐展开的这幅互联网色情经济的宏大画卷。

    在当年那场启蒙的春风春雨中,国外网站当仁不让地承担起了启蒙的义务。我至今还牢牢记得我和众同学知道的第一个色情网站乃是whitehouse,和美国白宫网站所不同的仅仅在后缀,一个是“.com”,而另一个是“.org”。在那些青涩的岁月里,我的同学们没事就喜欢到处上网转转,看看美女图片。那会儿色情网站还都是国外的,每每碰到写着“$”符号的缴费提示,我们只有看着一串国外的账号一声叹息。

    后来我们这批同学上了大学,中文色情网站也就逐渐成长起来,一台服务器,几张光碟就可以在家里无本经营了。低起点,高收入的行业特点也吸引了大量学生朋友的加入。随着卖方市场的形成,买方也在享受着更多的免费服务,短短两三年间,业界便已传出“无网不黄,无黄不网”的说法了。

    在这样一种无奈的形式下,互联网扫黄呼之欲出。话说那天我在新浪首页看到永康大叔波澜壮阔的网络扫黄宣言后,第一个反应是又要“严打”啦!等到后来公布了举报电话,更是有同学借机公报私仇,把平日里因为要收费而没法看的色情网站义无反顾地举报了。

    当然,我们这些都还处在低级阶段。那些一台电脑一根线加上三五张碟坐在家里收钱的家伙开始大批落网。令公安机关始料未及的是这些家伙里不少是聪明伶俐的大学生——真是让人感慨他们具有生意头脑,只可惜没有用对地方,聪明反被聪明误。

    话说我有一个朋友是个小小公务员,平日里也喜欢追求些低级趣味。因为工作原因,常有机会接触到当地一些民事案件档案,他很聪明地将这些案件中火爆的情节改写成小稿子发在当地报纸上赚取三五稿费。不幸的是,后来他们领导发现报纸上类似七旬老翁调戏少女、昨夜江边发生强奸案之类稿件,有相当一部分出自自己手下同志之手后,大感羞愧,狠狠K了他一顿。

    这个事情给他的教训是,传统的道德标准和法律法规还是存在着一定的约束,任何时候任何情况都不可违犯,否则我们将付出更大的代价。我们的小邻居越南,暗地里流传这样一个说法:“牺牲一代少女发展经济”,期望通过色情业带动经济起飞,如此“唯经济发展论”搞了二十多年,少女牺牲了一代又一代,经济也还是那个样——目光短浅,终将自食其果。“全家白骨成灰土,一代红妆照汗青”,即使有朝一日经济真的发展起来了,又有谁能记得起少女们的哭声呢?

    类似的经济理论问题很容易造成我们集体的伤感,依靠人体作为增长点来发展经济,总会给当事人带来一种“和亲”的羞愧。“为有牺牲多壮志,敢教日月换新天”,聪明的脑瓜用在了邪路上,学问再多,做得再大,也只能是南辕北辙。就像当年讽刺IT业的名言说的:皮肉多了,骨头少了。无论对哪一个行业哪一个方面,这样的评价,都不大光彩。

    姜明亮:吉林人,汉语言文学专业大学本科学历,同时为多家媒体撰写评论。

厕所和殿堂

    据媒体报道,浙江省在一次打击淫秽色情网站专项行动中,共侦破和查处案件65起。其中98%的犯罪嫌疑人在35周岁以下,大专以上学历约占2/3,其中不少甚至是在校学生。而北京的状况也不太乐观,1个月就破获4起类似案件,被批准逮捕的黄网版主“居然”都有大学学历,有的甚至还是在校大学生……

    看到以上报纸上的两个消息,我并未感到吃惊。有数据显示,中国网民数量最庞大的群体就是学生,而作为网络色情业这一庞大的产业链,学生当然不可能成为其中缺席的人。我只是有点诧异,媒体在报道这样的新闻时,竟然如此关注大学生这一群体,而且想当然地在口气上硬梆梆地用上了“居然”的字眼。当然,我并不是教唆学生都到网络上从事色情活动,而是感觉我们的社会在为大学生下定义时,存在一种非常理想的,但却根深蒂固的偏见罢了。

    大学,并不能让每个人脱胎换骨,达到一种完美的境界;大学生,更不是什么完人,“天之娇子”也会犯下“人”犯下的错误。诚然,“达则兼济天下,穷则独善其身”这句话历来都是中国知识分子的行为模本,而以上事实只能说明,我们的法制教育,在传统道德日益匮乏的今天,在大学校园里也难觅一席之地了。

    互联网和任何一种科学技术一样,都是一把双刃剑,厕所和殿堂也仅仅隔了一层窗户纸而已,问题的关键并不在于相关部门对“厕所”的打击力度,而在于对学生的道德和法制教育本身,毕竟在市场化的今天,“有需求就有市场”是永远都不会变的道理。

 
2004-09-18
傻子苏更生
时间: 2004-09-10 来源: 大学周刊 黄小米 访问次数:42

    一出火车站,远远地我就看到B大建筑系的条幅醒目地写着:建筑系欢迎新同学。我拖着箱子往条幅面前走,一个男生拦住我嗡声嗡气地说“同学,你是B大的吗?我这里是新生接待处。”

    我抬头看说话人,皮肤很黑,五官虽然端正,却是一张木纳的脸。我刚想笑开的脸顿时没了生气,木木的说:“是。”男生二话不说,扛起我的箱子就往接送车前急匆匆地走。我顿时不好意思了,那箱子里除了新买的几件衣服,就是一堆高中时喜欢的书。那份量并不算轻啊。

    我追在木纳男生后头喊:“其实你可以滚了!”

    黑脸男生转过头来,很艰难地看着我,动了动嘴却说不出话来。

    我自知说错了话,低头红了脸,小声地说:“我的意思是箱子下有轮子,滚起来要省力很多。”

    我抬起头时,看到黑脸男生的眼睛闪了一下。

    对于这样的一闪我并不奇怪。我知道自己的优势在于漂亮的脸。这张脸虽然算不得十分精细,却是时下流行的大眼、小嘴、尖下巴。很多人都说过我的眼睛像秋天的湖水,深不见底。

    我四处打听,得知他叫苏更生,奇怪他这样一个木纳沉闷的人,怎会有这样灵动的名字,并暗自窃喜。我千方百计和他巧遇,并以他名字为对白开头,装作惊讶一般好奇地说:“原来你叫苏更生啊,好浪漫的名字!念起来像在读亦舒的书。”苏更生却看着我,瞪着眼睛结结巴巴地说:“我们老家没有钟,夜里还是人敲钟,我是三更时出生,所以叫苏更生。”

    我顿时气极,扭头就走。

    周围的同学都知道我和苏更生耗上了,个个惊讶,女生们阴阳怪气地叫着说:你怎么就看上苏更生那样的闷瓜呀!男生们则一句三叹气,直吼鲜花插在了牛粪上。

    我越发和自己较上了劲,步步为营,加紧攻势,硬是把苏更生这个硬比城墙的碉堡给拿下了。

    花前月下时,我学电视剧情节威逼苏更生,问他第一次见我时,他主动帮我拿行李是否动机不纯?苏更生的表情十分为难,嘴唇嚅动了半天才说:“是动机不纯。”我一阵得意,对他继续诱拐。好一阵苏更生才说:“开学时,校领导就承诺过了,接待好一个新生就可以领到十块钱。”

    我气得无语,站起身甩手就走,可不出两步又转了回来。哎,算了,就苏更生那老实的模样,还指望他能说出什么甜言蜜语好听的话呢!
其实我一直没告诉苏更生,我为什么喜欢他。

    第一次见他时,我的箱子就坏掉了,苏更生硬是把我那堆一百多斤重的书给扛回了宿舍。试问,现在的校园里还能看到这样的男生吗?而且做这些活时,他竟一句话都没说。

 
2004-09-13
菜鸟变黑客高手 整理版
文章作者:lamianbu

第一章——关于找软件
常用类软件:
黑白屋: http://www.play8.net/
华军软件 http://www.newhua.com/ (根据物理位置自行选择速度快的镜像)
中国下载 http://download.com.cn/ (使用查找功能可找到大部份软件)
东丽在线 http://www.tjdl.net/softdown/ (不错的软件下载站,类似华军)
世纪下载 http://www.21sx.com/ (也是一个不错的下载站)
安全类软件:
黑白屋:http://www.play8.net/index2.htm
安全焦点 http://www.xfocus.net/tool.php
安全资讯 http://www.aurorasafe.com/list.asp
天天安全 http://www.ttian.net/download/list.php
网嗅下载 http://netsill.com/download/default.asp
灰色轨迹 http://www.sandflee.net/down/list.asp
鹰派下载 http://211.155.27.112/~technic/down/
   (一些大型精典安全软件下载,不过有时候就上不去)

找代理在这里:
代理使用方法 http://extend.hk.hi.cn/~sunbird/freeproxy_why.html
     (各种代理使用方法介绍)
代理服务器地址 http://www.salala.com/proxy_index.htm
       (每日更新的,大部份是HTTP代理)
代理服务器地址 http://www.emaga.net/8341/myann
       (每日更新的,大部份是SOCKS代理,既QQ代理)

注册码在这里:
第六空间 http://www.sixthroom.com/down/qt/ser.rar (注册码大全下载)
注册码搜索 http://www.netpaste.com/code/
孤月注册码 http://www.guyue.com/key/

                 第二章——关于被入侵

简单说明:
经常有帖子说:“我中木马啦,怎么办?”、“我被攻击了”,“我的windows有问题,是不是被入侵啦?”等等。哪么如果你怀疑系统被入侵的话,请你首先看看日志的记录或是有什么变化,然后你应该查看可疑进程(win98需要用相关工具)、注册表启动项、服务、开放端口等,然后更新病毒库,杀毒。前提是你要有一定的电脑常识并对你的系统比较了解,才能分别正常与否。如果你自己对电脑一窍不通,那在论坛别人也很难帮助你。其实就像对付现实中的病毒一样,应该预防为主。杀毒软件和网络防火墙可以抵御绝大部分危险,自身安全知识的提高则是最根本的保障。最新的病毒相关知识可以到杀毒软件公司的主页上找。另外,系统不正常也可能是操作失误引起的。这里不是“电脑零起点”,所以关于系统修复的问题,请不要在论坛提了。

相关工具:

Active Ports 监视自己电脑的端口,并做出相应处理。http://www.sixthroom.com/down/aq/cn_aports.rar
windows优化大师5.1 它的进程管理功能不错。更是目前最好的系统优化软件。 http://www.sixthroom.com/down/aq/wom.rar
Windows 基准安全分析器 1.0 (特别推荐,详细资料看下载说明吧)
http://www.sixthroom.com/down/admin/aq/mbsasetup.msi
Fport-2.0 查看端口关联的进程 (应用于9x/me)http://www.sixthroom.com/down/admin/aq/fport.zip
mport 比fport更胜一筹的工具 http://www.sixthroom.com/down/admin/aq/mport.zip
KV3000江民杀毒王(正式版+钥匙盘)
http://www.kxweb.net/down/down.asp?downid=1&id=14
金山毒霸2003正式版
http://www.kxweb.net/down/down.asp?downid=1&id=11

相关资料:

黑白屋文档中心:http://www.play8.net/cgi-bin/news/article/list.cgi
104种木马的清除方法http://asp2.6to23.com/ebug88/net/article/net004.htm
清除恶意网页的破坏 http://assistant.3721.com/safe.htm
2000系统进程总列表 http://sinbad.zhoubin.com/read.html?board=Win&num=73
木马的检测、清除及其预防 天网安全检测 http://sky.net.cn/main/view.php?cid=170
蓝盾安全检测 http://www.bluedon.com/bluedonserver.asp

               第三章——基础知识和入侵步骤

简单说明:
电脑和网络知识可算是做黑客的基础的基础,至少你要先了解了它们再来看下面的文章。看完这部分的文章,你也只是算站到了门口,路还长着呢。这里我再多说几句关于入侵步骤的话,给新手做个引导。所谓入侵,可以理解为未授权的访问。既然是未授权的,就需要借助一些非常规的手段,即通常所说的利用漏洞。
基础知识网址:
http://tech.163.com/tm/010213/010213_14563.html
http://tech.163.com/tm/010213/010213_14564.html
http://tech.163.com/tm/010214/010214_14632.html
http://tech.163.com/tm/010214/010214_14634.html
http://tech.163.com/tm/010214/010214_14638.html

一、要利用漏洞首先要发现它。端口扫描和漏洞扫描就是“敲门砖”。可以对大量目标做一般扫描,也可以对单一目标做重点扫描。或者两者结合。当你对漏洞熟悉时,你可以只通过端口扫描就能了解目标的可能有的漏洞。这样既提高效率又不易被记录日志。
几种扫描器的简单使用教程:http://www.chinesehack.org/file/show.asp?id=5614
入侵技术介绍–目标探测:http://www.sixthroom.com/ailan/f … 2&RootID=279&ID=279

二、找到漏洞后的利用问题,是千差万别的。这正是新手学要学习的地方之一。很多要依靠自己的知识积累及对系统的掌握及熟悉程度,这里就不多说了。 下面提供几个提供漏洞资料的网站供大家参考。
天极网 http://www.myhard.com/76284138209935360/index.shtml
绿盟科技 http://www.nsfocus.net/index.php?act=sec_bug
五月安全网 http://bgbbs.www70.cn4e.com/article.asp?cat_id=2
中国信息安全 http://www.chinafirst.org.cn/ruodian/advisory.php

三、利用漏洞的目的是什么呢?是控制对方,即是获得远程shell。shell这个概念是从UNIX下继承过来的,是指与操作系统核心的一种交互方式和界面。典型的例子是telnet。得到shell的办法有很多种,比如通过系统自带的telnet,终端服务。或者用木马和工具提供的,如winshell,冰河等等。以下介绍两篇SHELL编程的文章给大家。
中国软件 http://www.csdn.net/develop/article/14/14219.shtm
程序春秋 http://www.cbinews.com/developer/showcontent.php?articleid=2193

四、shell是有权限差别的。最高权限–管理员权限才是我们的目标。所以有时会有提升权限的问题。当然,这也是利用了漏洞。以下介绍几篇文章。
Win2K 提升权限漏洞
http://www.yesky.com/20010530/182273.shtml
Microsoft SQL Server Webtasks权限提升漏洞
http://it.rising.com.cn/newSite/ … 10/31-153502052.htm
Linux kernel ptrace提升权限漏洞
http://levinstorm.myetang.com/main/holes/unix/005.html
NT/2000提升权限的方法小结
http://home.lufeng.net/wolf/Computer/luodong/2000tisheng.htm
IIS提升权限漏洞
http://www.ddhome.net/hole/14.htm

五、有了shell还要扩大它,就是进一步获得更好用的shell。命令行的到图形的、功能少的到多的。于是才有了“怎么开3389”,“怎么上传”之类问题。在这介绍给大家介绍一下现在最流行的3389吧。更多的文章请sixthroom.com。
远程开启3389终端服务
http://www.sandflee.net/wawa/3389-1.htm
建立你的3389肉鸡
http://www.sandflee.net/wawa/sz-3389.htm

六、为了下次还能控制目标,你需要保持shell。做一个好的后门又是一种“学问”。克隆帐号、埋木马、破administrator的密码,手段不一而足。各位慢慢学吧。
永远的后门 http://www.ttian.net/article/show.php?id=259
Win2000 下Ping 后门的简单实现
http://www.landun.org/wenzhang/images/xiaoran/article/154.html
帐号克隆
http://www.netXeyes.org/CA.exe
帐号检查
http://www.netXeyes.org/CCA.exe
暴力破解LC4
http://www.andyxu.net/banana/tools_2/lc4.rar

端口知识介绍:
相关工具:
扫描端口是扫描器的基本功能,工具太多了。提供两个给大家,更多的参看后面。
X-Port.zip下载 http://www.xfocus.net/download.php?id=327
PortReady下载 http://dotpot.533.net/dpsoft/PortReady1.6.zip
相关资料:
端口扫描简介 http://www.netscreen.com.cn/suml/zhishiyy/jingong/duankougj.htm0
系统服务及木马默认端口表
http://www.pttc.yn.cninfo.net/dtsy/nettech/netanquan/41250634.htm
端口大全 http://www.sixthroom.com/ailan/f … 2&RootID=268&ID=268
常用默认端口列表及功能中文注解 http://www.sixthroom.com/ailan/f … 2&RootID=267&ID=267
常见端口详解及部分攻击策略 http://www.sixthroom.com/ailan/f … 2&RootID=266&ID=266
相关资料:
如何成为一名黑客 http://263.aka.org.cn/Docs/hacker-howto_2001.html
提问的技巧 http://bbs.online.sh.cn/eliteart … 44fb3b6efa4377e48ae
TCP/IP基础 http://www.linkwan.com/gb/routertech/netbase/tcpip.htm  
网络攻防教程 http://www.netsill.com/wenzhang/list.asp?id=115
网络入侵步骤及思路 http://www.iamguo.com/bh3/hackguide2.htm
拒绝背后黑手的窥探 IPC$漏洞大揭秘
http://computer.szptt.net.cn/2002-04-27/nw2002042700109.shtml
全球ip分配表 http://519519.vicp.net/lb5000//usr/3/3_11.txt
黑客入门教程 http://www.pttc.yn.cninfo.net/dtsy/nettech/netanquan/43934529.htm
菜鸟XXX客快速入门
http://netsafe.ayinfo.ha.cn/sqxw/2002117172333.htm
几种流行的入侵工具与讲解
http://www.pttc.yn.cninfo.net/dtsy/nettech/netanquan/44188520.htm
常见端口详解及部分攻击策略
http://www.pttc.yn.cninfo.net/dtsy/nettech/netanquan/-90637.htm
攻击的各种级别
http://www.pttc.yn.cninfo.net/dtsy/nettech/netanquan/39825935.htm

                 第四章——关于命令的使用

简单说明:
windowsNT/2000下有丰富的cmd可供使用,其作用也是巨大的。完全值得去熟练掌握她它们。windows2000本身就提供了详细的命令帮助。在开始菜单–》帮助中可以搜索到“windows 2000 命令参考”。强烈建议各位新手花些时间仔细看一遍。装了比如IIS等软件,就会有新的命令(iisreset),在命令行方式下加/?或-h参数可以查看帮助,其他内置的命令当然也可以。还有就是掌握一些常用的DOS命令也是非常有必要的。因为WINSOWS不管发展到哪一天,它也都不可能取代DOS,至少现在还不行。NET命令更是最常用的网络命令,想做一个黑客,更是你所必需掌握的。掌握一些LINUX命令也是很有必要的。希望下面的资料对大家有所帮助。

相关帖子:
DOS下常用网络相关命令解释
http://www.jiejingwang.com/list.asp?id=521
入门网络命令
http://www.jiejingwang.com/list.asp?id=520
Win2000命令全集 http://www.sixthroom.com/ailan/f … 2&RootID=343&ID=343
Windows XP下cmd命令详解 http://www.sixthroom.com/ailan/f … 2&RootID=366&ID=366
ftp命令: http://www.hotcy.org/chem/campous/article/ftp.htm
telnet命令简介:http://www22.brinkster.com/lastknife/netbase/telnetorder.htm (以上地址简单介绍了TELNET命令,http://www.sixthroom.com/ailan/f … 2&RootID=277&ID=277
net命令基本用法:http://www.yy0730.com/1/1/1/wen/list.asp?id=12
tftp命令: 由于TFTP命令过于简单,请自行使用“TFTP /?”进行查询。下面在给出一个参照的
   实例:http://levinstorm.myetang.com/main/tutorials/hacking/006.html
一般入侵所需要的几个常用命令:
http://www.yixindz.com/badschool/hacker/hack_commands.htm
Linux 的常用网络命令
http://www.jiejingwang.com/list.asp?id=522

                     
                   第五章——关于windows98

简单说明:
这类问题有两种:一是怎样入侵win98系统,二是在win98怎样入侵。
由于98的网络功能并不完善,使得问题的解决远没有像对2000那样“丰富多采”。98默认没有什么网络服务启动,众所周知漏洞是由于各种服务的功能设计并不完美,所以才产生的,也就是说没有漏洞也就很难入侵,找不到什么可利用的漏洞。这给入侵带来的困难是难以想像的.共享入侵,算是最常见的攻击方式了。

相关资料:
共享入侵 http://www.sixthroom.com/ailan/f … 2&RootID=269&ID=269
入侵windows98系统 http://www.sixthroom.com/ailan/f … 2&RootID=270&ID=270
win98入侵网吧详解 http://www.sixthroom.com/ailan/f … 2&RootID=271&ID=271

其实还有些方法,比如嗅探密码、发病毒和木马到信箱、甚至用QQ“联络感情”再传个绑木马的Flash等,没什么意思,就此打住(这是前辈说的,他老人家都说打住了,哪我也打住,其实是我也不知道说什么,呵呵)。
基于同样的理由,98不是一个好的攻击平台。如果只是端口扫描,那么superscan可以胜任。web类的漏洞扫描x-scan也可以。但涉及ipc$的弱口令、漏洞、远程控制工具以及连接一些服务(如sql)就要“基于NT技术构建”的os了。好在3389终端服务的客户端可以是98,所以先搞一台开3389的肉鸡就算是回避了问题。如果你还在用98,诚恳的建议你:请用2000。如果你在网吧,先试试入侵网吧服务器。(在这里我也要加一句就是如果你是用98系统的话,哪么选择榕哥的流光98版也是不错的。不过有很多功能也还是无法使用)。
鉴于98的问题技术含量不高、没有深入探讨价值,所以就谈到这里吧。(个人观点)

相关工具:
NetPass 1.0 破解98共享密码 http://lovezxd.myetang.com/indexpage/indextool/NetPass.zip
cain v2.5 综合破解工具 http://www.qq888.com/down/download.asp?Did=968
exeBinderZ 1.3 EXE捆绑机 http://www.heibai.net/download/show.php?id=3028&down=3
SUPERSCAN3.0中文版下载 http://download.pchome.net/php/d … erscanv30.exe&svr=3
X-SCAN2.3下载 http://www.xfocus.net/download.php?id=366
流光98下载 http://www.netxeyes.com/cfluxay2k1for98setup.exe(因榕哥不愿意看到加了补丁的作品,为了尊重他老人家,所以这里不提供补丁下载,需要的就自己去找吧)。
终端服务客户端 http://arm.533.net/hack/winterminal.zip (既3389连接器)

               第6章——关于ipc$、空连接和默认共享
简单说明:
******首先需要指出的是空连接和ipc$是不同的概念。空连接是在没有信任的情况下与服务器建立的会话,换句话说,它是一个到服务器的匿名访问。ipc$是为了让进程间通信而开放的命名管道,可以通过验证用户名和密码获得相应的权限。有许多的工具必须用到ipc$。默认共享是为了方便远程管理而开放的共享,包含了所有的逻辑盘(c$,d$,e$……)和系统目录winnt或windows(admin$)。******个人认为这段很重要,因为很多人根本就不知道什么是空连接什么是IPC$.建议不知道的朋友仔细看一下吧.这种问题,不应该不知道的.

相关帖子:
拒绝背后黑手的窥探 IPC$漏洞大揭秘
http://www.sixthroom.com/ailan/f … 2&RootID=281&ID=281
IPC入侵全攻略 http://www.sixthroom.com/ailan/f … 2&RootID=278&ID=278
win2k中C驱等的默认共享是怎么回事
http://www.sixthroom.com/ailan/f … 2&RootID=282&ID=282
取消默认共享≠安全 http://js00.51.net/23/wudi/show.cgi?type=2000&id=20021017212524

常见问题和回答:
一、怎样建立空连接,它有什么用?
答:使用命令 net use \IPipc$ “” /user:”" 就可以简单地和目标建立一个空连接(需要目标开放ipc$)。
对于NT,在默认安全设置下,借助空连接可以列举目标用户、共享,访问everyone权限的共享,访问小部分注册表等,没有什么利用价值。对2000作用就更小了。而且实现也不方便,需借助工具。如果你不理解“没用”的东西为什么还会存在,就看看“专业”的解释吧:
在NT/2000下的空连接 http://www.sixthroom.com/ailan/f … 2&RootID=280&ID=280
解剖WIN2K下的空会话 http://www.sixthroom.com/ailan/f … 2&RootID=283&ID=283
二、为什么我连不上IPC$?
答:1,只有nt/2000/xp及以上系统才可以建立ipc$。如果你用的是98/me是没有该功能的。
2、确认你的命令没有打错。正确的命令是: net use \目标IPipc$ “密码” /user:”用户名”
注意别多了或少了空格。当用户名和密码中不包含空格时两边的双引号可以省略。空密码用”"表示。
3,根据返回的错误号分析原因:
错误号5,拒绝访问 : 很可能你使用的用户不是管理员权限的,先提升权限;
错误号51,Windows 无法找到网络路径 : 网络有问题;
错误号53,找不到网络路径 : ip地址错误;目标未开机;目标lanmanserver服务未启动;目标有防火墙(端口过滤);
错误号67,找不到网络名 : 你的lanmanworkstation服务未启动;目标删除了ipc$;
错误号1219,提供的凭据与已存在的凭据集冲突 : 你已经和对方建立了一个ipc$,请删除再连。
错误号1326,未知的用户名或错误密码 : 原因很明显了;
错误号1792,试图登录,但是网络登录服务没有启动:目标NetLogon服务未启动。(连接域控会出现此情况)
错误号2242,此用户的密码已经过期 : 目标有帐号策略,强制定期要求更改密码。
4,关于ipc$连不上的问题比较复杂,本论坛没有总结出一个统一的认识,我在肉鸡上实验有时会得出矛盾的结论,十分棘手。而且知道了问题所在,如果没有用其他办法获得shell,很多问题依然不能解决。问题过于细致后就不适合在本文章里探讨了。各位看着办吧,呵呵。
三、怎样打开目标的IPC$?
答:首先你需要获得一个不依赖于ipc$的shell,比如sql的cmd扩展、telnet、木马。当然,这shell必须是admin权限的。然后你可以使用shell执行命令 net share ipc$ 来开放目标的ipc$。从上一问题可以知道,ipc$能否使用还有很多条件。请确认相关服务都已运行,没有就启动它(不知道怎么做的请看net命令的用法)。还是不行的话(比如有防火墙,杀不了)建议放弃。
四、怎样映射和访问默认共享?
答:使用命令net use z: \目标IPc$ 密码” /user:”用户名” 将对方的c盘映射为自己的z盘,其他盘类推。
如果已经和目标建立了ipc$,则可以直接用IP加盘符加$访问。比如 copy muma.exe \IPd$pathmuma.exe 。或者再映射也可以,只是不用用户名和密码了:net use y: \IPd$ 。然后 copy muma.exe y:pathmuma.exe 。当路径中包含空格时,须用”"将路径全引住。
五、如何删除映射和ipc$连接?
答:用命令 net use \IPipc$ /del 删除和一个目标的ipc$连接。
用命令 net use z: /del 删除映射的z盘,其他盘类推。
用命令 net use * /del 删除全部。会有提示要求按y确认。
六、连上ipc$然后我能做什么?
答:能使用管理员权限的帐号成功和目标连接ipc$,表示你可以和对方系统做深入“交流”了。你可以使用各种命令行方式的工具(比如pstools系列、Win2000SrvReskit、telnethack等)获得目标信息、管理目标的进程和服务等。如果目标开放了默认共享(没开你就帮他开),你就可以上传木马并运行。也可以用tftp、ftp的办法上传。像dwrcc、VNC、RemoteAdmin等工具(木马)还具有直接控屏的功能。如果是2000server,还可以考虑开启终端服务方便控制。这里提到的工具的使用,请看自带的说明或相关教程。
七、怎样防止别人用ips$和默认共享入侵我?
答:A、一种办法是把ipc$和默认共享都删除了。但重起后还会有。这就需要改注册表。
1,先把已有的删除
net share ipc$ /del
net share admin$ /del
net share c$ /del
…………(有几个删几个)
2,禁止建立空连接
  首先运行regedit,找到如下主键[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlLSA]把RestrictAnonymous(DWORD)的键值改为:00000001。
  3,禁止自动打开默认共享
  对于server版,找到如下主键[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesLanmanServerParameters]把AutoShareServer(DWORD)的键值改为:00000000。
对于pro版,则是[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesLanmanServerParameters]把AutoShareWks(DWORD)的键值改为:00000000。
B、另一种是关闭ipc$和默认共享依赖的服务(不推荐)
net stop lanmanserver
可能会有提示说,XXX服务也会关闭是否继续。因为还有些次要的服务依赖于lanmanserver。一般情况按y继续就可以了。
C、最简单的办法是设置复杂密码,防止通过ipc$穷举密码。但如果你有其他漏洞,ipc$将为进一步入侵提供方便。
D、还有一个办法就是装防火墙,或者端口过滤。防火墙的方法就不说了,端口过滤看这里:
过配置本地策略来禁止139/445端口的连接:
http://www.sixthroom.com/ailan/f … 2&RootID=284&ID=284

第7章——关于扫描出的漏洞

简单说明:
很多扫描器都有漏洞扫描功能。当你获得了一些主机的漏洞列表时,不要急着把它们帖在论坛上,期望别人来为你分析和告诉你利用的方法。你应该首先尝试自己完成这些。扫描出的漏洞并不是都有用的,一部分漏洞过时了,一部分是误报。如果你希望了解的多一些,最好经常到发布漏洞比较快的网站走一走,漏洞的利用是一个不段积累的过程。时间长了相信你就体会到了。

漏洞搜索:

绿盟的引擎 http://www.nsfocus.net/index.php?act=sec_bug
蓝盾的引擎 http://www.landun.org/zhongyao/sousuo.htm
补天网的引擎 http://www.patching.net/otherweb/leak/leakindex.asp
安全焦点的引擎 http://www.xfocus.net/vuln/index.php
小凤居的引擎 http://lilitou1.myetang.com/

相关帖子:
一个CGI漏洞的发现和利用
http://www.sixthroom.com/ailan/f … 2&RootID=285&ID=285
cgi漏洞大全 http://www.sixthroom.com/ailan/f … 2&RootID=293&ID=293
常见CGI漏洞及应对二 http://www.sixthroom.com/ailan/f … 2&RootID=286&ID=286
常见CGI漏洞及应对一 http://www.sixthroom.com/ailan/f … 2&RootID=287&ID=287
Windows 2000漏洞集锦1 http://www.sixthroom.com/ailan/f … 2&RootID=288&ID=288
Windows 2000漏洞集锦2 http://www.sixthroom.com/ailan/f … 2&RootID=289&ID=289
Windows 2000漏洞集锦3
http://www.sixthroom.com/ailan/f … 2&RootID=290&ID=290
Windows 2000漏洞集锦4
http://www.sixthroom.com/ailan/f … 2&RootID=291&ID=291
Windows 2000漏洞集锦5
http://www.sixthroom.com/ailan/f … 2&RootID=292&ID=292
ASP漏洞大全 http://www.sixthroom.com/ailan/f … 2&RootID=294&ID=294
IIS漏洞整理一 http://www.sixthroom.com/ailan/f … 2&RootID=295&ID=295
IIS漏洞整理二 http://www.sixthroom.com/ailan/f … 2&RootID=296&ID=296
中国网络安全响应中心各种漏洞大全 http://www.cns911.com/holes/linux/list.php

                 第8章——关于提升权限

简单说明:
黑客的最终目标就是得到root(即win中的admin)权限。一个真正的黑客会把一次入侵当做是自己的一件作品,不会轻易放弃,但是有些漏洞(典型的如Unicode漏洞、ASP木马)不能直接获得管理员权限,所以必然需要提升权限。一些新手可能会犯这类错误,以为中了木马、获得了shell就能控制一切。结果就出现“为何不能加用户”、“为何不能开3389”等问题。2000及更高版本os承袭了NT的安全结构,多重机制环环相扣来保障安全,特别是帐户安全。无奈安全系统过于庞大,多少会出现漏洞,于是我们就有机会了。 还要补充一点,就是在拿到一个现成的后门软件,或是一个木马的时候,一定要先看看说明。至少你应该知道这个后门运行后的效果吧?更有些人上传了某个后门软件或是木马到目标后就认为完事了,你不执行它就是传个地雷上去又有什么用呢?

相关工具:
erunasx 利用Debug Registers漏洞提升权限 http://www.qq888.com/down/download.asp?Did=796
Windows NT/2000权限提升工具,可以将任意用户提升到SYSTEM级别的权限。漏洞出在smss.exe中的DEBUG子系统,所有普通用户都可以通过该漏洞获得对系统中任意进程或线程句柄的控制,从而可以以SYSTEM或管理员权限执行任意命令。2、使用方法:假设我们已经获得一台机器上的一个GUEST用户(或其他普通用户),现在我们要这个工具来获得系统最高权限。进行如下步骤:把ERunAsX.exe和ERunAsX.dll这两个文件复制到目标主机上可访问的目录下,例如C:下。以GUEST身份运行”ERunAsX 要执行命令”,例如”ERunAsX cmd.exe”,这时执行的命令是以SYSTEM 权限运行的…(请注意:具体使用以软件内英文说明为准,内附该BUG解决办法)

PipeUpAdmin 对sp1及更低有效 http://maopao.com/down/download.asp?Did=69
ISPC 利用IIS的漏洞,详见自带说明 http://www.cnsq.net/sq88/down/show.asp?id=572&down=1
PHPBB论坛权限提升 http://www.newyouth.org/softdown … .0.exploit_code.zip
WIN帮助文件溢出(可用于XP) http://www.newyouth.org/softdown … ack/chmoverflow.zip
NT/2K权限提升工具GetAdmin下载 http://www.csdn.net/cnshare/soft/openfile.asp?kind=1&id=9807

相关帖子:
NT/2000提升权限的方法小结 http://www.sixthroom.com/ailan/f … 2&RootID=297&ID=297
关于WIN2000的入侵,以及安全防御等问题(文章包含一次利用U漏洞提高权限的过程)
http://www.sixthroom.com/ailan/f … 2&RootID=298&ID=298
UNICODE漏洞介绍及入侵
http://www.sixthroom.com/ailan/f … 2&RootID=299&ID=299
怎样提升权限,做后门
http://www.sixthroom.com/ailan/f … 2&RootID=300&ID=300
一般用户获取NT服务器Admin权限的方法
http://www.sixthroom.com/ailan/f … 2&RootID=302&ID=302
Windows NT4的安全结构(对新手有些难,了解一下吧) http://www.sixthroom.com/ailan/f … 3&RootID=303&ID=303

                       
               第9章——关于做代理和跳板

简单介绍:
代理服务器英文全称是Proxy Cerver,其功能就是代理网络用户去取得网络信息。形象的说:它是网络信息的中转站。在一般情况下,我们使用网络浏览器直接去连接其他Internet站点取得网络信息时,须送出Request信号来得到回答,然后对方再把信息以bit方式传送回来。代理服务器是介于浏览器和Web服务器之间的一台服务器,有了它之后,浏览器不是直接到Web服务器去取回网页而是向代理服务器发出请求,Request信号会先送到代理服务器,由代理服务器来取回浏览器所需要的信息并传送给你的浏览器。而且,大部分代理服务器都具有缓冲的功能,就好象一个大的Cache,它有很大的存储空间,它不断将新取得数据储存到它本机的存储器上,如果浏览器所请求的数据在它本机的存储器上已经存在而且是最新的,那么它就不重新从Web服务器取数据,而直接将存储器上的数据传送给用户的浏览器,这样就能显著提高浏览速度和效率。更重要的是:Proxy Server (代理服务器)是 Internet链路级网关所提供的一种重要的安全功能,它的工作主要在开放系统互联 (OSI) 模型的对话层,有了对代理的了解,相信你也认识到了什么是跳板。

相关工具:
SocksCap 2.2 SOCKS调度工具 http://www.123gz.com/dzc/download/sc32r231.exe
SkSockServer1.04 代理跳板 http://www.123gz.com/dzc/download/sksockserver.zip
Snake跳板傻瓜版 http://www.123gz.com/dzc/download/sgtb.zip
代理猎手V3.1Beta1简装版 http://www.123gz.com/dzc/download/proxyhunter.zip
FTP Serv-U 4.0 正式汉化版,最常用的ftp服务程序 http://61.159.224.188/makesoftur … 627E207574756375737
slimftp 隐蔽的ftp服务器 http://www.whitsoftdev.com/files/slimftpd.zip
天雁WEB服务器 不用安装的小型web服务程序 http://www.cnzzz.com/download/do … 33352254709&Url=100
多种服务程序下载
http://www.zdnet.com.cn/download/windows/business/swlist/0,2008004954,39000268r,00.htm?sort=5

相关帖子:
代理、肉鸡、跳板的概念 http://www.sixthroom.com/ailan/f … 2&RootID=305&ID=305
代理服务器(Proxy)完全解析 http://www.sixthroom.com/ailan/f … 2&RootID=307&ID=307
如何使用代理服务器 http://www.sixthroom.com/ailan/f … 2&RootID=309&ID=309
简单制作跳板 http://www.123gz.com/dzc/sksockserver-cusky.htm
Serv-U设置教程 http://www.enanshan.com/ftp/
SocksCap32 使用详解 http://www.123gz.com/dzc/sockscap32.htm
在肉鸡上安装FTP服务器 http://www.sixthroom.com/ailan/f … 2&RootID=306&ID=306
利用 unicode 漏洞,轻松建立自己的代理服务器
http://www.123gz.com/dzc/sksockserver-nicky-1.htm#top1
特别推荐猎手与蚂蚁收藏馆 http://www.123gz.com/ (绝对值得一看)

           第10章——关于终端服务(3389)
简单说明:
windows终端服务提供了通过作为终端仿真器工作的“瘦客户机”软件远程访问服务器桌面的能力。图形界面和不影响当前本地用户的特性是它的最大优点。由于它是2000server及以上版本自带的功能,因此成为一个绝好的“后门”而倍受青睐。而且win98也可以成为客户端,这使得在网吧“工作”成为可能。有一点需要强调一下使用客户端登陆远程主机对当前工作的用户没有影响,而且一切动作本地用户都是看不到的。也就是说远程登陆和本地用户是在不相同的空间,两者互不干扰。

相关工具:
WIN2000客户端
http://zudu2000.myetang.com/soft/win2k.rar
winxp下的客户端 功能比2000下的更强大
http://zudu2000.myetang.com/soft/windowsXP.zip
终端服务程序的一个补丁 使本地和远程间能复制文本 http://www.sandflee.net/wawa/tools/rdpclip_hotfix.exe
web版终端客户端 使用浏览器调用ActiveX控件访问终端服务
http://www.enanshan.com/down/tswebsetup.exe
C3389.EXE 修改终端服务端口号的工具
http://www.sandflee.net/down/show.asp?id=228&down=1
Win2k终端服务器端所需文件包
http://www.netsill.com/download/download.asp?Did=1965
3389自动安装程序-djshao正式版5.0
http://netsill.com/download/download.asp?Did=2019
开启3389工具(如果要想让远程主机开启WIN2000的终端服务,请把3389.exe也传到远程主机上并运行。然后等待一个漫长的时间(由于是无人执守安装)。就可以看到远程主机的3389端口会被打开。)
http://netsill.com/download/download.asp?Did=1991
W2K终端服务客户端安装版
http://www.sandflee.net/down/show.asp?id=39&down=1

相关帖子:
关于远程启动终端服务的帖子 http://www.sixthroom.com/ailan/f … 2&RootID=385&ID=385
终端服务问题常见问答
http://www.sixthroom.com/ailan/f … 2&RootID=386&ID=386
图文讲解输入法漏洞入侵
http://www.sandflee.net/txt/list.asp?id=22
3389自动安装工具教程
http://netsill.com/download/download.asp?Did=2068
3389动画教程(密码china)
http://netsill.com/download/download.asp?Did=1990
修改终端客户端端口动画教程
http://netsill.com/download/download.asp?Did=2009
3389资料 http://www21.brinkster.com/srob/wawa/wawa/3389txt.htm

                   第11章——关于克隆帐号

简单说明:
克隆帐号的原理简单的说是这样:在注册表中有两处保存了帐号的SID相对标志符,一处是SAMDomainsAccountUsers下的子键名,另一处是该子键的子项F的值中。这里微软犯了个不同步它们的错误,登陆时用的是后者,查询时用前者。当用admin的F项覆盖其他帐号的F项后,就造成了帐号是管理员权限但查询还是原来状态的情况。即所谓的克隆帐号。(前辈就是前辈把大家想到的都写出来了,我实在不知道这里在加些什么了。看来也只有这样了。大家如果还有什么不明白的就到论坛里发贴子吧。
具体的看这里:
解剖安全帐号管理器(SAM)结构 http://www.sixthroom.com/ailan/f … 3&RootID=387&ID=387
明白原理后就可以手动或者用现成的工具克隆帐号了。

相关工具:
克隆ca.exe http://www.netxeyes.org/CA.exe
检查克隆cca.exe http://www.netxeyes.org/CCA.exe
手动克隆需要SYSTEM权限,用它 psu.exe
http://www.sandflee.net/down/show.asp?id=176&down=1

相关帖子:
工具克隆:ca和cca 请访问作者主页 http://www.netxeyes.org/main.html
psu用法:psu.exe提升为system权限 http://www.sixthroom.com/ailan/f … 2&RootID=390&ID=390
手动克隆:如何克隆管理员帐号 http://www.sixthroom.com/ailan/f … 3&RootID=388&ID=388
如何克隆管理员帐号的补充 http://www.sixthroom.com/ailan/f … 3&RootID=389&ID=389

常见问题和回答:
1,使用ca时,出现connect **.**.**.** …Error是怎么会事?
答:ca和cca需要目标开放ipc$,请确认可以与目标建立ipc$。参见“关于ipc$和空连接”
2,使用ca时,出现“Processing….ERROR”是怎么会事?
答:这说明对方主机缺少文件msvcp60.dll,想办法传个过去放在系统目录下就可以了。
3,克隆过程没有错误,但cca没有显示该帐号克隆成功,无法使用被克隆的帐号。
答:这一般是因为对方主机是域控制器,注册表中sam结构不同,工具失效。暂时无法解决。
4,手动克隆无法访问注册表SAM键怎么办?
答:在命令行方式,可以使用psu工具获得SYSTEM权限,从而访问SAM键。详见上面说明。
在图形界面,运行regedt32.exe,找到SAM键并选中。“安全”子菜单栏里有一项“权限”,打开它。在里面设置administrator和SYSTEM一样有完全控制权限。关闭regedt32再打开,就可以访问SAM键

2004-09-08
c语言的编程风格

第一章:缩进格式

  Tab是8个字符,于是缩进也是8个字符.有很多怪异的风格,他们将缩进格式定义为4个字符(设置为2个字符!)的深度,这就象试图将PI定义为3一样让人难以接受.

  理由是:缩进的大小是为了清楚的定义一个块的开始和结束.特别是当你已经在计算机前面呆了20多个小时了以后,你会发现一个大的缩进格式使得你对程序的理解更容易.

  现在,有一些人说,使用8个字符的缩进使得代码离右边很近,在80个字符宽度的终端屏幕上看程序很难受.回答是,但你的程序有3个以上的缩进的时候,你就应该修改你的程序.
  
总之,8个字符的缩进使得程序易读,还有一个附加的好处,就是它能在你将程序变得嵌套层数太多的时候给你警告.这个时候,你应该修改你的程序.

第二章:大符号的位置

  另外一个C程序编程风格的问题是对大括号的处理.同缩进大小不同,几乎没有什么理由去选择一种而不选择另外一种风格,但有一种推荐的风格,它是Kernighan和Ritchie的经典的那本书带来的,它将开始
的大括号放在一行的最后,而将结束大括号放在一行的第一位,如下所示:

  if (x is true) { we do y }
  
  然而,还有一种特殊的情况:命名函数:开始的括号是放在下一行的第一位,如下:
int function(int x) { body of function }
  
  所有非正统的人会非难这种不一致性,但是,所有思维正常的人明白: (第一) K&R是___对___的,(第二)如果K&R不对,请参见第一条. (:-))……另外,函数也是特殊的,不一定非得一致.

  需要注意的是结束的括号在它所占的那一行是空的,__除了__它跟随着同一条语句的继续符号.如”while”在do-while循环中,或者”else”在if语句中.如下:

  do { body of do-loop } while (condition);
  以及
  if (x == y) { .. } else if (x > y) { … } else { …. }

  理由: K&R.
  
  另外,注意到这种大括号的放置方法减小了空行的数量,但却没有减少可读性.于是,在屏幕大小受到限制的时候,你就可以有更多的空行来写些注释了.

第三章:命名系统

  C是一种简洁的语言,那么,命名也应该是简洁的.同MODULE-2以及ASCAL语言不同的是,C程序员不使用诸如ThisVariableIsATemporaryCounter之类的命名方式.一个C语言的程序员会将之命名为”tmp”,这很容易书写,且并不是那么难以去理解.

  然而,当混合类型的名字不得不出现的时候,描述性名字对全局变量来说是必要的了.调用一个名为”foo”全局的函数是很让人恼火的.全局变量(只有你必须使用的时候才使用它) ,就象全局函数一样,需要描述性的命名方式.假如你有一个函数用来计算活动用户的数量,你应该这样命名–”count_active_users()”–或另外的相近的形式,你不应命名为”cntusr()”.

  有一种称为Hungarian命名方式,它将函数的类型编码写入变量名中,这种方式是脑子有毛病的一种表现—编译器知道这个类型而且会去检查它,而这样只会迷惑程序员. –知道为什么Micro$oft为什么会生产这么多”臭虫”程序了把!!.

  局部变量的命名应该短小精悍.假如你有一个随机的整数循环计数器,它有可能有”i”,如果没有任何可能使得它能被误解的话,将其写作”loop_counter”是效率低下的.同样的,”"tmp”可以是任何临时数值的函数变量.

  如果你害怕混淆你的局部变量的名字,还有另外一个问题,就是称
function-growth-hormone-imbalancesyndrome.

第四章:函数

  函数应该短小而迷人,而且它只作一件事情.它应只覆盖一到两个屏幕(80*24一屏),并且只作一件事情,而且将它做好.(这不就是UNIX的风格吗,译者注).

  一个函数的最大长度和函数的复杂程度以及缩进大小成反比.于是,如果你已经写了简单但长度较长的的函数,而且你已经对不同的情况做了很多很小的事情,写一个更长一点的函数也是无所谓的.

  然而,假如你要写一个很复杂的函数,而且你已经估计到假如一般人读这个函数,他可能都不知道这个函数在说些什么,这个时候,使用具有描述性名字的有帮助的函数.

  另外一个需要考虑的是局部变量的数量.他们不应该超过5-10个,否则你有可能会出错.重新考虑这个函数,将他们分割成更小的函数.人的大脑通常可以很容易的记住7件不同的事情,超过这个数量会引起混乱.你知道你很聪明,但是你可能仍想去明白2周以前的做的事情.

第5章:注释

  注释是一件很好的事情,但是过多的注释也是危险的,不要试图区解释你的代码是注释如何如何的好:你应该将代码写得更好,而不是花费大量的时间去解释那些糟糕的代码.

  通常情况下,你的注释是说明你的代码做些什么,而不是怎么做的.而且,要试图避免将注释插在一个函数体里:假如这个函数确实很复杂,你需要在其中有部分的注释,你应该回到第四章看看.你可以写些简短的注释来注明或警告那些你认为特别聪明(或极其丑陋)的部分,但是你必须要避免过多.取而代之的是,将注释写在函数前,告诉别人它做些什么事情,和可能为什么要这样做.

第六章:你已经深陷其中了.

  不要着急.你有可能已经被告之”GUN emacs”会自动的帮你处理C的源代码格式,而且你已经看到它确实如此,但是,缺省的情况下,它的作用还是不尽如人意(实际上,他们比随便敲出来的东西还要难看- ainfinite number of monkeys typing into GNU emacs would never make a good program)

  于是,你可以要么不要使用GUN emacs,要么让它使用sanervalules.使用后者,你需要将如下的语句输入到你的.emacs文件中.(defun linux-c-mode() “C mode with adjusted defaults for use with the Linux kernel.”(interactive) (c-mode) (c-set-style”K&R”) (setq c-basic-offset8))
  
  这会定义一个M-x Linux-c-mode的命令.当你hacking一个模块的时候,如何你将-*- linux-c -*-输入在最开始的两行,这个模式会自动起作用.而且,你也许想加入如下

  (setq auto-mode-alist (cons ‘(“/usr/src/linux.*/.*\\.〖ch〗$” . linux-c-mode) auto-mode-alist))
  
  到你的.emacs文件中,这样的话,当你在/usr/src/linux下编辑文件的时候,它会自动切换到linux-c-mode .

  但是,假如你还不能让emaces去自动处理文件的格式,不要紧张,你还有一样东西: “缩进” .

  GNU的缩进格式也很死板,这就是你为什么需要加上几行命令选项.然而,这还不算太坏,因为GNU缩进格式的创造者也记得K&R的权威, (GNU没有罪,他们仅仅是在这件事情上错误的引导了人们) ,你要做的就只有输入选项”-kr -i8″(表示”K&R,缩进8个字符).

  ”缩进”有很多功能,特别是当它建议你重新格式你的代码的时候,你应该看看帮助.但要记住: “缩进”不是风格很差的程序的万灵丹.

资料收集:beck Copyright 2002 www.vcok.com, All Rights Reserved

Tc2.0编写俄罗斯方块游戏

  很多编程爱好者都编写过俄罗斯方块的游戏程序。很久以前,我用Tc2.0也做过一个;最近有好些朋友看见我以前的俄罗斯方块的程序后,
问我是怎么做的。我一直想把这个程序的整个过程写一份详细的东西,与各位编程爱好者分享,一直没空。正好现在放假了,而且离回家还有几天。于是我就把这个程序重新写了一遍,尽量使程序的结构比较清晰好懂一些。同时写了下面的这份东西。

  俄罗斯方块游戏的程序中用到了一些方法。为了比较容易理解这些方法,我在讲述的同时写了些专门针对这些方法的示例程序。这些示例程序力求短小,目的是用最小的代码能够清楚的示例所用的方法。这些示例程序都经过tc2.0测试。最后还附了完整的俄罗斯方块游戏的源代码,和最终的可执行程序。如果你看了这份东东,有什么意见和想法,请发电子邮件告诉我。我将会继续更新这分东东,最新的版本可以在我的个人主页上下载。

  下面的问题是有关俄罗斯方块程序的,其中有些是朋友问我的,有些是我认为可能会被问到的。我尽量按问题从易到难排列这些问题。 关于俄罗斯方块程序的一些问题:
******************************************************
Tc2.0中怎么样设置图形显示?
Tc2.0中常用图形函数的用法?
怎样获取鍵盘输入?
怎样控制方块的移动?
怎样控制时间间隔(用于游戏中控制形状的下落)?
游戏中的各种形状及整个游戏空间怎么用数据表示?
游戏中怎么判断左右及向下移动的可能性?
游戏中怎么判断某一形状旋转的可能性?
按向下方向键时加速某一形状下落速度的处理?
怎么判断某一形状已经到底?
怎么判断某一已经被填满?
怎么消去已经被填满的一行?
怎么消去某一形状落到底后能够消去的所有的行?(如长条最多可以消去四行)
怎样修改游戏板的状态?
怎样统计分数?
怎样处理升级后的加速问题?
怎样判断游戏结束?
关于计分板设计的问题。
关于“下一个”形状取法的问题。
剩下的问题。

******************************************************
新的问题:
 我想有一个最高记录的显示,应该怎么做呀?
 我想实现一个进度存储功能,应该怎么做呀?


Tc2.0中怎么样设置图形显示?

  Tc2.0中有两种显示模式,一种是我们所熟知的字符模式,另一种是图形模式。在字符模式下只能显式字符,如ASCII字符。一般是显示25
行,每行80个字符。程序缺省的是字符模式。在字符模式下不能显式图形和进行绘图操作。要想进行图形显示和绘图操作,必须切换到图形模
式下。

  Tc2.0中用initgraph()函数可以切换到图形模式,用closegraph()可以从图形模式切换回字符模式。initgraph()和closegraph()都是图形
函数,使用图形函数必须包括头文件”graphics.h”。

  void far initgraph(int far *graphdriver,int far *graphmode,char far *pathtodriver);graphdriver是上涨指向图形驱动序号变量的指针;graphmode是在graphdriver选定后,指向图形显示模式序号变量的指针。pathtodriver表示存放图形驱动文件的路径。

  Tc2.0中有多种图形驱动,每种图形驱动下又有几种图形显示模式。在我的程序中图形驱动序号为VGA,图形显示模式序号为VGAHI。这是一种分辨率为640*480(从左到右坐标依次为0-639,从上到下坐标依次为0-479),能够显示16种颜色的图形模式。别的图形驱动序号和图形显示模式序号,可以从手册或联机帮助中找到。

  pathtodriver指示存放图形驱动文件的路径。图形驱动序号不同,图形驱动文件也不同。序号为VGA图形驱动对应”egavga.bgi”这个图形驱动文件。”egavga.bgi”一般在Tc目录下。

void far closegraph(void);
  没有参数,从图形模式直接返回字符模式。

initgraph()和closegraph()的常用用法如下:
int gdriver = VGA, gmode=VGAHI, errorcode;

/* initialize graphics mode */
initgraph(&gdriver, &gmode, “e:\\tc2″);

/* read result of initialization */
errorcode = graphresult();

if (errorcode != grOk) /* an error occurred */
{
printf(“Graphics error: %s\n”, grapherrormsg(errorcode));
printf(“Press any key to halt:”);
getch();
exit(1); /* return with error code */
}

/* return to text mode */
closegraph();


Tc2.0中常用图形函数的用法?

在这里讲几个游戏中用到的绘图用的图形函数:
setcolor();
line();
rectangle();
settextjustify();
outtextxy();
setfillstyle();
bar();

void far setcolor(int color);
  设置画线、画框和在图形模式下显示文字的当前颜色。这个函数将影响line()、rectangle()和outtextxy()函数绘图的颜色。
color可以取常的颜色常量:
BLACK ? 0
BLUE ? 1
GREEN ? 2
CYAN ? 3
RED ? 4
MAGENTA ? 5
BROWN ? 6
LIGHTGRAY ? 7
DARKGRAY ? 8
LIGHTBLUE ? 9
LIGHTGREEN ?10
LIGHTCYAN ?11
LIGHTRED ?12
LIGHTMAGENTA ?13
YELLOW ?14
WHITE ?15

void far line(int x1,int y1,int x2,int y2);
用当前颜色从(x1,y1)画一条到(x2,y2)的线段。

void far rectangle(int left,int top,int right,int bottom);
用当前颜色画一个左上角为(left,top)、右下角为(right,bottom)的矩形框。

void far settextjustify(int horz,int vert);
设置图形模式下文字输出的对齐方式。主要影响outtextxy()函数。
horiz和vert可取如下枚举常量:
horiz ?LEFT_TEXT ? 0 ?Left-justify text
?CENTER_TEXT ? 1 ?Center text
?RIGHT_TEXT ? 2 ?Right-justify text
vert ?BOTTOM_TEXT ? 0 ?Justify from bottom
?CENTER_TEXT ? 1 ?Center text
?TOP_TEXT ? 2 ?Justify from top

void far outtextxy(int x,int y,char * textstring);
在(x,y)处用当前字体(缺省的字体是DEFAULT_FONT)显示字符串textstring,字符串的对齐方式由settextjustify()指定。

void far setfillstyle(int pattern,int color);
设置图形的填充模式和填充颜色,主要影响bar()等函数。
pattern一般取枚举常量值SOLID_FILL,color的取值与setcolor(int color)中color的取值范围相同。

  介绍完了前面两个问题,现在来写一个程序。这个程序演示前了面所介绍的几个图形函数。
程序prog1.c


怎样获取鍵盘输入?

  在Tc2.0中有一个处理键盘输入的函数bioskey();
int bioskey(int cmd);
  当cmd为1时,bioskey()检测是否有键按下。没有键按下时返回0;有键按下时返回按键码(任何按键码都不为0),但此时并不将检测到的按
键码从键盘缓冲队列中清除。
  当cmd为0时,bioskey()返回键盘缓冲队列中的按键码,并将此按键码从键盘缓冲队列中清除。如果键盘缓冲队列为空,则一直等到有键按
下,才将得到的按键码返回。

  Escape键的按键码为0×11b,下面的小程序可以获取按键的按键码。

for (;;)
{
key=bioskey(0); /* wait for a keystroke */
printf(“0x%x\n”,key);
if (key==0×11b) break; /* Escape */
}

常用按键的按键码如下:

#define VK_LEFT 0×4b00
#define VK_RIGHT 0×4d00
#define VK_DOWN 0×5000
#define VK_UP 0×4800
#define VK_HOME 0×4700
#define VK_END 0×4f00
#define VK_SPACE 0×3920
#define VK_ESC 0×011b
#define VK_ENTER 0×1c0d


  完整的程序请参见prog2.c、prog3.c。
prog2.c获取按键的按键码,按Escape键退出程序。
prog3.c根据不同的按键进行不同的操作,按Escape键退出程序。


怎样控制方块的移动?
  方块移动的实现很简单,将方块原来的位置用背景色画一个同样大小的方块,将原来的方块涂去。然后在新的位置上重新绘制方块就可以
了。这样就实现了方块的移动。完整的程序请参见prog4.c。这个用方向键控制一个黄色的小方块在屏幕上上、下、左、右移动。这个程序用到了前面几个问题讲的内容,如果你有点忘了,还要回头看看哦。:)


怎样控制时间间隔(用于游戏中控制形状的下落)?
  解决这个问题要用到时钟中断。时钟中断大约每秒钟发生18.2次。截获正常的时钟中断后,在处理完正常的时钟中断后,将一个计时变量
加1。这样,每秒钟计时变量约增加18。需要控控制时间的时候,只需要看这个计时变量就行了。


  截获时钟中断要用到函数getvect()和setvect()。
两个函数的声明如下:
?void interrupt (*getvect(int interruptno))();
?void setvect(int interruptno, void interrupt (*isr) ( ));

  保留字interrupt指示函数是一个中断处理函数。在调用中断处理函数的时候,所有的寄存器将会被保存。中断处理函数的返回时的指令是iret,而不是一般函数用到的ret指令。

getvect()根据中断号interruptno获取中断号为interruptno的中断处理函数的入口地址。
setvect()将中断号为interruptno的中断处理函数的入口地址改为isr()函数的入口地址。即中断发生时,将调用isr()函数。


  在程序开始的时候截获时钟中断,并设置新的中断处理。在程序结束的时候,一定要记着恢复时钟中断哦,不然系统的计时功能会出问题
的。
具体演示程序请参见prog5.c。由于中断处理大家可能用的不多,所以我把prog5.c这个程序完整地贴在下面,并加上详细的解释。

/* prog5.c */
This is an interrupt service routine. You can NOT compile this
program with Test Stack Overflow turned on and get an executable
file which will operate correctly. */

/* 这个程序每隔1秒钟输出一个整数,10秒钟后结束程序。
按escape键提前退出程序 。*/

#include <stdio.h>
#include <dos.h>
#include <conio.h>

/* Escape key */
#define VK_ESC 0×11b

#define TIMER 0×1c /* 时钟中断的中断号 */

/* 中断处理函数在C和C++中的表示略有不同。
如果定义了_cplusplus则表示在C++环境下,否则是在C环境下。 */

#ifdef __cplusplus
#define __CPPARGS …
#else
#define __CPPARGS
#endif

int TimerCounter=0; /* 计时变量,每秒钟增加18。 */

/* 指向原来时钟中断处理过程入口的中断处理函数指针(句柄) */
void interrupt ( *oldhandler)(__CPPARGS);

/* 新的时钟中断处理函数 */
void interrupt newhandler(__CPPARGS)
{
/* increase the global counter */
TimerCounter++;

/* call the old routine */
oldhandler();
}

/* 设置新的时钟中断处理过程 */
void SetTimer(void interrupt (*IntProc)(__CPPARGS))
{
oldhandler=getvect(TIMER);
disable(); /* 设置新的时钟中断处理过程时,禁止所有中断 */
setvect(TIMER,IntProc);
enable(); /* 开启中断 */
}

/* 恢复原有的时钟中断处理过程 */
void KillTimer()
{
disable();
setvect(TIMER,oldhandler);
enable();
}


void main(void)
{
int key,time=0;

SetTimer(newhandler); /* 修改时钟中断 */

for (;;)
{
if (bioskey(1))
{
key=bioskey(0);
if (key==VK_ESC) /* 按escape键提前退出程序 */
{
printf(“User cancel!\n”);
break;
}
}
if (TimerCounter>18) /* 1秒钟处理一次 */
{
/* 恢复计时变量 */
TimerCounter=0;
time++;
printf(“%d\n”,time);
if (time==10) /* 10秒钟后结束程序 */
{
printf(“Program terminated normally!\n”);
break;
}
}
}
KillTimer(); /* 恢复时钟中断 */

}


游戏中的各种形状及整个游戏空间怎么用数据表示?

以后我提到的形状都是指下面七种形之一及它们旋转后的变形体。

□□□□ □□□□ □□□□ □□□□
□■□□ □■■□ □□□□ □□□□
□■□□ □■□□ □■□□ □■■□
□■■□ □■□□ ■■■□ ■■□□

□□□□ □■□□ □□□□
□□□□ □■□□ □□□□
■■□□ □■□□ □■■□
□■■□ □■□□ □■■□

我定义了一个结构来表示形状。
struct shape
{
int xy[8];
int color;
int next;
}
-1 0 1 2
-3□□□□
-2□□□□
-1□□□□
0□■□□

  所有的各种形状都可以放在4×4的格子里。假定第二列,第四行的格子坐标为(0,0)(如上图中黑块所示),则每个形状的四个方块都可以用4
个数对来表示。坐标x从左向右依次增加,y从上到下依次增加。表示的时候,组成该形状的四个方块从左到右,从上到下(不一定非要按这个顺
序)。如上面七种形状的第一个用数对来表示就是(-2,0)、(-1,0)、(0,0)、(1,0)。结构shape中的xy就是用来表示这4个数对的。为了简化程序,用一维数组xy[8]来表示。xy[0]、xy[1]表示第一个数对,xy[2]、xy[3]表示第二个数对,依次类推。
  shape中的color表示形状的颜色,不同的形状有不同的颜色。七种形状及它们旋转后的变形体一共有19种形状,用一个全局数组表示。假定旋转的方向是逆时针方向(顺时针方向道理一样)。shape中的next就表示当前形状逆时针旋转后的下一个形状的序号。例如:第一种形状及其旋
转变形的形状用结构表示如下。

□□□□ □□□□ □□□□ □□□□
□■□□ □□□□ □■■□ □□□□
□■□□ □□■□ □□■□ ■■■□
□■■□ ■■■□ □□■□ ■□□□

struct shape shapes[19]=
{
/*{x1,y1,x2,y2,x3,y3,x4,y4, color, next}*/
{ 0,-2, 0,-1, 0, 0, 1, 0, CYAN, 1}, /* */
{-1, 0, 0, 0, 1,-1, 1, 0, CYAN, 2}, /* # */
{ 0,-2, 1,-2, 1,-1, 1, 0, CYAN, 3}, /* # */
{-1,-1,-1, 0, 0,-1, 1,-1, CYAN, 0}, /* ## */

……

}

  游戏空间指的是整个游戏主要的界面(呵呵,这个定义我实在想不出更准确的,还请哪位大虾指点)。实际上是一个宽10格子、高20格子的
游戏板。用一个全局数组board[12][22]表示。表示的时候:board[x][y]为1时表示游戏板上(x,y)这个位置上已经有方块占着了,board[x][y]
为0表示游戏板上这位置还空着。为了便于判断形状的移动是否到边、到底,初始的时候在游戏板的两边各加一列,在游戏板的下面加一行,全
部填上1,表示不能移出界。即board[0][y],board[11][y](其中y从0到21)初始都为1,board[x][21](其中x从1到10)初始都为1。
1 2 3 4 5 6 7 8 910
1□□□□□□□□□□
2□□□□□□□□□□
3□□□□□□□□□□
4□□□□□□□□□□
5□□□□□□□□□□
6□□□□□□□□□□
7□□□□□□□□□□
8□□□□□□□□□□
9□□□□□□□□□□
10□□□□□□□□□□
11□□□□□□□□□□
12□□□□□□□□□□
13□□□□□□□□□□
14□□□□□□□□□□
15□□□□□□□□□□
16□□□□□□□□□□
17□□□□□□□□□□
18□□□□□□□□□□
19□□□□□□□□□□
20□□□□□□□□□□

  prog6.c演示了用结构表示各种形状的方法。虽然程序稍长一些,但并不是特别复杂。其中游戏板初始化部分并没有真正用到,但是后面的程
序会用到的。
其中SIZE定义为16,这样将整个屏幕的坐标系由原来的640×480转换成40×30(640/16=40,480/16=30)。游戏中所有的坐标都是基于40×30的坐标系的,这样有助于简化程序。坐标的转换在程序中由DrawBlock(int x,int y)来体现。

  新的坐标系如下图所示:
-8-7-6-5-4-3-2-1 0 1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031
-4□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
-3□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
-2□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
-1□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
1□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
2□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
3□□□□□□□□□■■■■■■■■■■□□□■■■■□□□□□□□□□□□□□□
4□□□□□□□□□■■■■■■■■■■□□□■■■■□□□□□□□□□□□□□□
5□□□□□□□□□■■■■■■■■■■□□□■■■■□□□□□□□□□□□□□□
6□□□□□□□□□■■■■■■■■■■□□□■■■■□□□□□□□□□□□□□□
7□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
8□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
9□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
10□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
11□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
12□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
13□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
14□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
15□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
16□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
17□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
18□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
19□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
20□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□□□□□□
21□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
22□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
23□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
24□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
25□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
26□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□

  新坐标中最主要的是就是上面两块黑色的部分。左边那块大的就是游戏板(横坐标从1到10,纵坐标从1到20),右边那块小的就是显示“下一个”形状的部分(横坐标从14到17,纵坐标从3到6)。这个新的坐标系是整个游戏的基础,后面所有的移动、变形等的计算都是基于这个坐标系的。


游戏中怎么判断左右及向下移动的可能性?

  看懂了前面的各种形状和游戏板等的表示,接下来的东西就都好办多了。先来看一下某个形状如何显示在游戏板当中。假设要在游戏板中
显示第一个形状。第一个形状在结构中的表示如下:

struct shape shapes[19]=
{
/*{x1,y1,x2,y2,x3,y3,x4,y4, color, next}*/
{ 0,-2, 0,-1, 0, 0, 1, 0, CYAN, 1},

……

}

  那么这个组成形状四个方块的坐标表示为(0,-2)、(0,-1)、(0,0)和(1,0)。这实际上是相对坐标。假形状的实际坐标指的是4×4方块中的第
二列、第三行的方块的位置,设这个位置为(x,y)。那么组成这个形状的四个小方块的实际坐标(以第一个形状为例)就是(x+0,y-2)、(x+0,y-1)、(x+0,y+0)和(x+1,y+0)。由于所有的形状都可以在4×4的方块阵列中表示,这样就找到了一种统一的方法来表示所有的形状了。

-1 0 1 2
-3□□□□ 相对坐标
-2□■□□
-1□■□□ 组成第一种形状的四个方块的相对坐标为(0,-2)、(0,-1)、(0,0)和(1,0)。
0□■■□

让我们看看形状是如何显示在游戏板中的(以第一个形状为例)。

1 2 3 4 5 6 7 8 910
1□■□□□□□□□□ 形状的坐标为(2,3)。组成形状的四个方块的坐标由形状的
2□■□□□□□□□□ 坐标加上这四个小方块各自的相对坐标得出。它们分别是:
3□■■□□□□□□□ (2+0,3-2)、(2+0,3-1)、(2+0,3-0)和(2+1,3-0)。即:
4□□□□□□□□□□ (2,1)、(2,2)、(2,3)和(3,3)。如左图所示。
5□□□□□□□□□□
6□□□□□□□□□□
7■□□□□□□□□□ 形状的坐标为(1,9)。组成形状的四个方块的坐标分别是:
8■□□□□□□□□□ (1+0,9-2)、(1+0,9-1)、(1+0,9-0)和(1+1,9-0)。即:
9■■□□□□□□□□ (1,7)、(1,8)、(1,9)和(2,9)。如左图所示。
10□□□□□□□□□□
11□□□□□□□□□□
12□□□□□□□□□□
13□□□□□□□□□□
14□□□□□□□□□□
15□□□□□□□□□□
16□□□□□□□□□□
17□□□□□□□□□□
18□□□□□□□□■□ 形状的坐标为(9,20)。组成形状的四个方块的坐标分别是:
19□□□□□□□□■□ (9+0,20-2)、(9+0,20-1)、(9+0,20-0)和(9+1,20-0)。即:
20□□□□□□□□■■ (9,18)、(9,19)、(9,20)和(10,20)。如左图所示。

  从现在起,我不再举别的示例程序了。从现在开始所有的示例代码均来自于我写的”Russia.c”。为了记录游戏板的状态,用了一个全局数组board[12][22]。board[x][y](其中x从0到11,y从1到21)等于1表示(x,y)这个位置已经被填充了,组成形状的四个方块的坐标都不能为(x,y),否则将发生冲突。board[x][y](其中x从1到10,y从1到20)等于表示(x,y)这个位置还没有被填充。

  游戏板初始化时,给board[0][y],board[11][y](其中y从1到21)都赋为1,给board[x][21](其中x从1到10)都赋为1。这相当于一开始就给游戏板左右和下方加了个“边”。所有的形状都不能够移入这个“边”,否则将发生冲突。

  现在我们可以开始讨论如何判断一个形状向左、向右和向下移动的可能性了。先说个概念,“当前形状”是指那个正在下落还没有落到底的那个形状。如果当前形状向左移动,不与游戏板现有状态发生冲突,则可以向左移动。具体做法是:先假设当前形状已经向左移动了,判断此时是否与游戏板现有状态发生冲突。如果不发生冲突,则可以向左移动。否则,不可以向左移动。

  判断索引号为ShapeIndex的形状在坐标(x,y)是否与游戏板当前状态发生冲突的代码如下。我把详细的说明加在这段代码中。

enum bool Confilict(int ShapeIndex,int x,int y)
{
int i;

/* 对组成索引号为ShapeIndex的形状的四个方块依次判断 */
for (i=0;i<=7;i++,i++) /* i分别取0,2,4,6 */
{
/* 如果四个方块中有任何一个方块的x坐标小于1或大于10,表示超出左边界或右边界。
此时,发生冲突。 */
if (shapes[ShapeIndex].xy[i]+x<1 ||
shapes[ShapeIndex].xy[i]+x>10) return True;

/* 如果四个方块中某个方块的y坐标小于1,表示整个形状还没有完全落入游戏板中。
此时,没有必要对这个方块进行判断。*/
if (shapes[ShapeIndex].xy[i+1]+y<1) continue;

/* 如果四个方块中有任何一个方块与游戏板当前状态发生冲突,则整个形状在(x,y)处
与游戏板当前状态冲突 */
if (board[shapes[ShapeIndex].xy[i]+x][shapes[ShapeIndex].xy[i+1]+y])
return True;
}

/* 四个方块中没有任何一个方块与游戏板当前状态发生冲突,则整个形状在(x,y)处
没有与游戏板当前状态冲突 */
return False;
}

对以上代码附加说明如下:
  shapes[ShapeIndex].xy[i](其中i等于0,2,4,6)表示组成索引号为ShapeIndex的形状的某个方块的x相对坐标。(i等于0时,表示第1个方块的x相对坐标;i等于2时,表示第2个方块的x相对坐标;i等于4时,表示第3个方块的x相对坐标;i等于6时,表示第4个方块的x相对坐标。)

  shapes[ShapeIndex].xy[i](其中i等于1,3,5,7)表示组成索引号为ShapeIndex的形状的某个方块的y相对坐标。(i等于1时,表示第1个方块的y相对坐标;i等于3时,表示第2个方块的y相对坐标;i等于5时,表示第3个方块的y相对坐标;i等于7时,表示第4个方块的y相对坐标。)

  shapes[ShapeIndex].xy[i]+x(其中i等于0,2,4,6)表示索引号为ShapeIndex的形状的坐标为(x,y)时,组成该形状的某个方块的x实际坐标。(i等于0时,表示第1个方块的x实际坐标;i等于2时,表示第2个方块的x实际坐标;i等于4时,表示第3个方块的x实际坐标;i等于6时,表示第4个方块的x实际坐标。)

  shapes[ShapeIndex].xy[i]+y(其中i等于1,3,5,7)表示索引号为ShapeIndex的形状的坐标为(x,y)时,组成该形状的某个方块的y实际坐
标。(i等于1时,表示第1个方块的y实际坐标;i等于3时,表示第2个方块的y实际坐标;i等于5时,表示第3个方块的y实际坐标;i等于7时,表示第4个方块的y实际坐标。)

现在来看看这句是什么意思吧。
board[shapes[ShapeIndex].xy[i]+x][shapes[ShapeIndex].xy[i+1]+y]

可以这样理解,把上面一句分开来看::

ActualX=shapes[ShapeIndex].xy[i]+x;/* 其中x为0,2,4,6 */
表示某个方块实际的x坐标。

ActualY=[shapes[ShapeIndex].xy[i+1]+y;
表示某个方块实际的y坐标。

board[ActualX][ActualY]就是与某个方块坐标相同处的游戏板的标志。如果此标志不为0(为1),表示这个方块与游戏板发生冲突。如果此标志为0,表示这个方块没有与游戏板发生冲突。

这段写的比较长,但是不是特别难理解。游戏中很多地方都用到了这种相对坐标向实际坐标的转换方式,看懂了这一段对理解其他部分的代码很有帮助。


仔细看过这段代码后,你可能会提一个问题:不是已经在游戏板的左右两边都加了“边”了吗,为什么还要加下面这个对x坐标的判断呢?

/* 如果四个方块中有任何一个方块的x坐标小于1或大于10,表示超出左边界或右边界。
此时,发生冲突。 */
if (shapes[ShapeIndex].xy[i]+x<1 ||
shapes[ShapeIndex].xy[i]+x>10) return True;

这是因为有一种特殊情况,如下图所示:

■■
■ 2 3 4 5 6 7 8 910
1■□□□□□□□□□ 这在当前形状刚出来的时候,是可能发生的。但是我们只给游戏板
2□□□□□□□□□□ 加了一层“边”。对于这个形状的最左边的那个方块将失去判断,
3□□□□□□□□□□ 如果不予理会,这个形状将会“挂”在游戏板的左上角!当初我也
4□□□□□□□□□□ 没有想到这一点,后来发现会有形状“挂”在最顶层,而导致游戏
5□□□□□□□□□□ 提前退出。发现了这个问题。
6□□□□□□□□□□
7□□□□□□□□□□
8□□□□□□□□□□ 加了这个判断后,游戏板的左右两个“边”对冲突的判断就是去意
9□□□□□□□□□□ 义了。因为没有这两个“边”,对于冲突的判断也不会出错。不过
10□□□□□□□□□□ 为了程序易于理解,还是保留了游戏板的左右两个“边”。
11□□□□□□□□□□
12□□□□□□□□□□
13□□□□□□□□□□
14□□□□□□□□□□
15□□□□□□□□□□
16□□□□□□□□□□
17□□□□□□□□□□
18□□□□□□□□□□
19□□□□□□□□□□
20□□□□□□□□□□

  如果你对我上面提出的新问题及对于这个问题的解释不太明白,没关系,这并不重要。因为现在才刚刚开始,而且刚才所说的这个问题只
有在特殊情况下才出现(当然,一旦发生上面说的问题,游戏就出错啦!^_^ ),对于理解整个程序的思路影响不大。看多了就会明白了(你
会说:原来就这么简单!)。

2004-09-03

黑客态度是重要的,但技术更加重要。态度无法替代技术,在你被别的黑客称为黑客之前,有一套基本的技术你必须掌握。 这套基本技术随着新技术的出现和老技术的过时也随时间在缓慢改变。例如,过去包括使用机器码编程,而知道最近才包括了HTML语言。但现在明显包括以下技术:

1 学习如何编程这当然是最基本的黑客技术。如果你还不会任何计算机语言,我建议你从Python开始。它设计清晰,文档齐全,对初学者很合适。尽管是一门很好的初级语言,它不仅仅只是个玩具。它非常强大,灵活,也适合做大型项目。 但是记住,如果你只会一门语言,你将不会达到黑客所要求的技术水平,甚至也不能达到一个普通程序员的水平—你需要学会如何以一个通用的方法思考编程问题,独立于任何语言。要做一名真正的黑客,你需要学会如何在几天内通过一些手册,结合你现在所知,迅速掌握一门新语言。这意味着你应该学会几种不同的语言。 如果要做一些重要的编程,你将不得不学习C语言,Unix的核心语言。其他对黑客而言比较重要的语言包括Perl和LISP。 Perl很实用,值得一学;它被广泛用于活动网页和系统管理,因此即便你从不用Perl写程序,至少也应该能读懂它。 LISP 值得学习是因为当你最终掌握了它你会得到丰富的经验;这些经验使你在以后的日子里成为一个更好的程序员,即使你实际上可能很少使用LISP本身。 当然,实际上你最好四种都会。 (Python, C, Perl, and LISP). 除了是最重要的四种基本语言,它们还代表了四种非常不同的编程方法,每种都会让你受益非浅。 这里我无法完整地教会你如何编程—这是个复杂的活儿。但我可以告诉你,书本和课程也不能作到。几乎所有最好的黑客都是自学成材的。真正能起作用的就是去亲自读代码和写代码。 学习如何编程就象学习用自然语言写作一样。最好的做法是读一些大师的名著,试着自己写点东西,再读些,再写点,又读些,又写点….如此往复,直到你达到自己在范文中看到的简洁和力量。 过去找到好的代码去读是困难的,因为很少有大型程序的可用源代码能让新手练手。这种状况已经得到了很大的改善;现在有很多可用的开放源码软件,编程工具和操作系统(全都有黑客写成)。这使我们自然地来到第二个话题…

2 得到一个开放源码的Unix并学会使用、运行它 我假设你已经拥有了一台个人计算机或者有一个可用的( 今天的孩子们真幸福  )。新手们最基本的一步就是得到一份Linux或BSD-Unix,安装在个人计算机上,并运行它。当然,这世界上除了Unix还有其他操作系统。但它们都是以二进制形式发送的—你无法读到它的源码,更不可能修改它。尝试在DOS或Windows的机器上学习黑客技术,就象是在腿上绑了铁块去学跳舞。 除此之外,Unix还是Internet的操作系统。你可以不知道Unix而学会用Internet,但不懂它你就无法成为一名Internet黑客。因为这个原因,今天的黑客文化在很大程度上是以Unix为中心的。(这点并不总是真的,一些很早的黑客对此很不高兴,但Unix和Internet之间的共生关系已是如此之强,甚至连微软也无可奈何) So,装一个Unix—我个人喜欢Linux,不过也有其他选择。(你也可以在同一台机器上同时运行DOS,Windows和Linux)学会它。运行它。用它跟Internet对话。读它的代码。试着去修改他。你会得到比微软操作系统上好的多的编程工具(包括C,Lisp, Python, and Perl),你会得到乐趣,并将学到比你想象的更多知识。 关于学习Unix的更多信息,请看 The Loginataka. 要得到Linux,请看: 哪里能得到 Linux.

3 学会如何使用WWW和写HTML 大多黑客文化建造的东西都在你看不见的地方发挥着作用,帮助工厂、办公室和大学正常运转,表面上很难看到它对他人的生活的影响。Web是一个大大的例外。即便政客也同意,这个巨大而耀眼的黑客玩具正在改变整个世界。单是这个原因(还有许多其它的), 你就需要学习如何掌握Web。 这并不是仅仅意味着如何使用浏览器(谁都会),而是要学会如何写HTML,Web的标记语言。如果你不会编程,写HTML会教你一些有助于学习的思考习惯。因此,先建起自己的主页。 但仅仅建一个主页也不能使你成为一名黑客。 Web里充满了各种网页。多数是无意义的,零信息量垃圾。 要想有价值,你的网页必须有内容—必须有趣或对其它黑客有用。这样,我们来到下一个话题…. —黑客文化中的地位 象大部分不涉及金钱的文化一样,黑客王国的运转靠声誉维护。你设法解决有趣的问题,但它们到底多有趣,你的解法有多好,是要有那些和你具有同样技术水平的人或比你更牛的人去评判的。 相应地,当你在玩黑客游戏时,你知道,你的分数要靠其他黑客对你的技术的评估给出。(这就是为什么只有在其它黑客称你为黑客是,你才算得上是一名黑客)这个事实常会被黑客是一项孤独的工作这一印象所减弱;它也会被另一个黑客文化的禁忌所减弱(此禁忌的效力正在减弱但仍很强大):拒绝承认自我或外部评估是一个人的动力。 特别地,黑客王国被人类学家们称为一种精英文化。在这里你不是凭借你对别人的统治来建立地位和名望,也不是靠美貌,或拥有其他人想要的东西,而是靠你的奉献。尤其是奉献你的时间,你的才智和你的技术成果。 要获得其他黑客的尊敬,你可以做以下五种事情:

1. 写开放源码的软件 第一个(也是最基本和传统的)是写些被其他黑客认为有趣或有用的程序,并把程序的原代码公布给大家共享。(过去我们称之为“自由软件-free software”,但这却使很多不知free的精确含义的人感到不解。现在我们很多人使用“开放源码-open source”这个词) 黑客王国里最受尊敬的大牛们是那些写了大型的、具有广泛用途的软件,并把它们公布出去,使每人都在使用他的软件的人。

2. 帮助测试并修改开放源码的软件 黑客们也尊敬也那些使用、测试开放源码软件的人。在这个并非完美的世界上,我们不可避免地要花大量软件开发的时间在测试和抓臭虫阶段。 这就是为什么任何开放源码的作者稍加思考后都会告诉你好的beta测试员象红宝石一样珍贵。 (他知道如何清楚描述出错症状,很好地定位错误,能忍受快速发布的软件中的bug,愿意使用一些简单的诊断工具) 甚至他们中的一个能判断出哪个测试阶段是延长的、令人精疲力尽的噩梦,哪个只是一个有益健康的玩意儿。 如果你是个新手,试着找一个赶兴趣的正在开发的程序,作一个好的beta测试员。从帮着测试,到帮着抓臭虫,到最后帮着改程序,你会不断进步。以后你写程序时,会有别人来帮你,你就得到了你当初善举的回报。

 3. 公布有用的信息 另一个好事是收集整理网页上有用有趣的信息或文档如FAQ。许多主要FAQ的维护者和其他开放源码的作者一样受到大家的尊敬。

4. 帮助维护基础设施的运转 黑客文化是靠自愿者运转的。要使Internet能正常工作,就要有大量枯燥的工作不得不去完成—-管理mail list,newsgroup,维护大量文档,开发RFC和其它技术标准等等。做这类事情的人会得到很多人的尊敬,因为每人都知道这些事情是耗时耗力的苦役,不象编码那样好玩。做这些事情需要毅力。

5. 为黑客文化本身服务 最后,你可以为这个文化本身服务(例如象我这样,写一个“如何成为黑客”的初级教程  )(hehe,象我这样把它翻成中文  ) 这并非一定要在你已经在这里呆了很久,精通所有以上4点,获得一定声誉后后才能去做。 黑客文化没有领袖。精确地说,它确实有些文化英雄和部落长者和历史学家和发言人。若你在这圈内呆的够长,你或许成为其中之一。记住:黑客们不相信他们的部落长者的自夸的炫耀,因此很明显地去追求这种名誉是危险的。你必须具备基本的谦虚和优雅。 —黑客和怪人(Nerd)的联系 同流行的传说相反,做一名黑客并不一定要你是个怪人。然而,很多黑客都是怪人。做一个出世者有助于你集中精力进行更重要的事情,如思考和编程。因此,很多黑客都愿意接受“怪人”这个标签,更有甚者愿意使用“傻子(geek)”一词并自以为豪—这是宣布他们与主流社会不合作的声明。 如果你能集中足够的精力来做好黑客同时还能有正常的生活,这很好。今天作到这一点比我在1970年代是个新手是要容易的多。今天主流文化对技术怪人要友善的多。甚至有更多的人意识到黑客通常更富爱心,是块很好的做恋人和配偶的材料。 更多信息见 Girl’s Guide to Geek Guys. 如果你因为生活上不如意而为做黑客而吸引,那也没什么—至少你不会分神了。或许以后你会找到自己的另一半。 —风格的意义 重申一下,做一名黑客,你必须进入黑客精神之中。当你不在计算机边上时,你仍然有很多事情可做。它们并不能替代真正的编程(没有什么能替代编程),但很多黑客都那么做,并感到它们与黑客精神存在一种本质的关联。 阅读科幻小说。参加科幻小说讨论会。(一个很好的寻找黑客的场合)研究禅宗,或练功习武。练就一双精确的耳朵,学会鉴赏特别的音乐。学会玩某种乐器,或唱歌。提高对双关语的鉴赏。学会流畅地用母语写作。(令人惊讶的时,我所知道的所有最棒的黑客,都是很不错的作家) 这些事情,你做的越多,你就越适合做黑客。至于为什么偏偏是这些事情,原因并不很清楚,但它们都涉及到了左-右脑的综合技巧,这似乎是关键所在。(黑客们既需要清晰的逻辑思维,有时也需要强烈的跳出逻辑之外的直觉) 最后,还有一些不要去做的事情。 不要使用愚蠢的,过于哗众取宠的ID 不要自称为网络崩客(punk) ,也不要对那些人浪费时间不要寄出充满拼写和语法错误的email,或张贴错误百出的文章 做以上的事情,会使大大损害你的声誉。黑客们个个记忆超群—你将需要数年的时间让他们忘记你的愚蠢。 —其它资源 Peter Seebach为那些不知如何同黑客打交道的经理们维护了一个非常精彩的黑客FAQ。 The Loginataka 有许多关于如何正确培养一个Unix黑客的态度的材料。 我也曾写过一篇“黑客文化简史”。 我还写过另一篇文章,“大教堂与集市”,解释了许多Linux和开放源码文化的运做原理。我还在它的续集“开拓智域”一文中有更直接的论述。 —FAQ(常问问题解答) 问:你会教我如何做黑客吗? 自从第一次发布此页,我每周都会得到一些请求,要我“教会他如何做黑客”;遗憾的是,我没有足够的时间和精力来做这个;我自己的编程项目已经占用了我110%的时间。甚至即便我想教你也不可能,黑客基本上是一项需要你自行修炼的的态度和技术。你会发现即使真正的黑客想帮助你,如果你乞求他们填鸭一样教你的话,你不会赢得他们的尊敬。首先去学习。显示你在尝试,你能靠自己去学习。然后再去向黑客们请教问题。 问:你会帮我“黑”掉一个站点吗?或者教我怎么黑它? No. 任何在读完FAQ后还问此问题人,都是愚不可及的家伙,即使有时间我也不会理睬。 任何发给我的此类mail都会被忽略或被痛斥。 问:哪里能找到真正的可以与之交流的黑客? 最佳办法是就近参加一个Unix或Linux的用户组,参加他们的会议。 问:我该先学哪种语言? HTML, 如果你还不会的话. 但它不是一个真正的编程语言。当你准备编程时,我建议你从 Python开始. 会有很多人向你推荐Perl,它比Python还受欢迎,但却难学一些。 C 是非常重要的,但它却是最难学的。不要一开始就尝试学C。 问:开放源码的自由软件不会使程序员饿肚子吗? 这似乎不大可能—到目前,开放源码软件产业创造了而不是消灭了大量工作机会。如果写一个程序比不写一个程序只是个纯粹经济上的收益的话,无论它是否免费,只要它被完成,程序员都会从中得到回报。而且,无论软件是由多么的free的方法开发的,对更新的软件应用的需求总是会有的。 问:我从何学起?哪里有免费的Unix? 本页的其他地方指向最常用的免费Unix。要做一名黑客,你需要自立自强,以及自我教育的能力。现在开始吧……

发表于 @ 2004年05月29日 3:16 PM | 评论 (0)