月度归档:2010年05月

正则表达式--递归匹配、非贪婪匹配与分组替换

1. 表达式的递归匹配

有时候,我们需要用正则表达式来分析一个计算式中的括号配对情况。比如, 使用表达式 "\( [^)]* \)" 或者 "\( .*? \)" 可以匹配一对小括号。但是如果括号 内还嵌有一层括号的话 ,如 "( ( ) )",则这种写法将不能够匹配正确,得到的结果是 "( ( )" 。类似情况的还有 HTML 中支持嵌套的标签如 "<font> </font>" 等。本节将要讨论的是,想办法把有嵌套的的成对括号或者成对标签匹配出来。
匹配未知层次的嵌套:
有的正则表达式引擎,专门针对这种嵌套提供了支持。并且在栈空间允许的情况下,能够支持任意未知层次的嵌套:比如 Perl,PHP,GRETA 等。在 PHP 和 GRETA 中,表达式中使用 "(?R)" 来表示嵌套部分。
匹配嵌套了未知层次的 "小括号对" 的表达式写法如下:"\( ([^()] | (?R))* \)"。
[Perl 和 PHP 的示例代码]
匹配有限层次的嵌套:
对于不支持嵌套的正则表达式引擎,只能通过一定的办法来匹配有限层次的嵌套。思路如下:
第一步,写一个不能支持嵌套的表达式:"\( [^()]* \)","<font>((?!</?font>).)*</font>"。 这两个表达式在匹配有嵌套的文本时,只匹配最内层。
第二步,写一个可匹配嵌套一层的表达式:"\( ([^()] | \( [^()]* \))* \)"。这个表达式在匹配嵌套层数大于一时,只能匹配最里面的两层,同时,这个表达式也能匹配没有嵌套的文本或者嵌套的最里层。
匹 配嵌套一层的 "<font>" 标签,表达式为:"<font>((?!</?font>).|(<font>((?!</? font>).)*</font>))*</font>"。这个表达式在匹配 "<font>" 嵌套层数大于一的文本时,只匹配最里面的两层。
第三步,找到匹配嵌套(n)层的表达式 与 嵌套(n-1)层的表达式之间的关系。比如,能够匹配嵌套(n)层的表达式为:
[标记头] ( [匹配 [标记头] 和 [标记尾] 之外的表达式] | [匹配 n-1 层的表达式] )* [标记尾]
回头来看前面编写的“可匹配嵌套一层”的表达式:
\( ( [^()] | \(([^()])*\) )* \)
<font> ( (?!</?font>). | (<font>((?!</?font>).)*</font>) )* </font>

PHP 和 GRETA 的简便之处在于,匹配嵌套(n-1)层的表达式用 (?R) 表示:
\( ( [^()] | (?R) )* \)
第四步,依此类推,可以编写出匹配有限(n)层的表达式。这种方式写出来的表达式,虽然看上去很长,但是这种表达式经过编译后,匹配效率仍然是很高的。

 
 
2. 非贪婪匹配的效率
可能有不少的人和我一样,有过这样的经历:当我们要匹配类似 "<td>内容</td>" 或者 "[b]加粗[/b]" 这样的文本时,我们根据正向预搜索功能写出这样的表达式:"<td>([^<]|<(?!/td>))*< /td>" 或者 "<td>((?!</td>).)*</td>"。
当发现非贪婪匹配之时,恍然 大悟,同样功能的表达式可以写得如此简单:"<td>.*?</td>"。 顿时间如获至宝,凡是按边界匹配的地方,尽量使用简捷的非贪婪匹配 ".*?"。特别是对于复杂的表达式来说,采用非贪婪匹配 ".*?" 写出来的表达式的确是简练了许多。
然而,当一个表达式中,有多个非贪婪匹配时,或者多个未知匹配次数的表达式时,这个表达式将可能存在效率上的陷阱。有时候,匹配速度慢得莫名奇妙,甚至开始怀疑正则表达式是否实用。
效率陷阱的产生:
在本站基础文章里,对非贪婪匹配的描述中说到:“如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。”
具体的匹配过程是这样的:
"非贪婪部分" 先匹配最少次数,然后尝试匹配 "右侧的表达式"。
如果右侧的表达式匹配成功,则整个表达式匹配结束。如果右侧表达式匹配失败,则 "非贪婪部分" 将增加匹配一次,然后再尝试匹配 "右侧的表达式"。
如果右侧的表达式又匹配失败,则 "非贪婪部分" 将再增加匹配一次。再尝试匹配 "右侧的表达式"。
依此类推,最后得到的结果是 "非贪婪部分" 以尽可能少的匹配次数,使整个表达式匹配成功。或者最终仍然匹配失败。
当 一个表达式中有多个非贪婪匹配,以表达式 "d(\w+?)d(\w+?)z" 为例,对于第一个括号中的 "\w+?" 来说,右边的 "d(\w+?)z" 属于它的 "右侧的表达式",对于第二个括号中的 "\w+?" 来说,右边的 "z" 属于它的 "右侧的表达式"。
当 "z" 匹配失败时,第二个 "\w+?" 会 "增加匹配一次",再尝试匹配 "z"。如果第二个 "\w+?" 无论怎样 "增加匹配次数",直至整篇文本结束,"z" 都不能匹配,那么表示 "d(\w+?)z" 匹配失败,也就是说第一个 "\w+?" 的 "右侧" 匹配失败。此时,第一个 "\w+?" 会增加匹配一次,然后再进行 "d(\w+?)z" 的匹配。循环前面所讲的过程,直至第一个 "\w+?" 无论怎么 "增加匹配次数",后边的 "d(\w+?)z" 都不能匹配时,整个表达式才宣告匹配失败。
其实,为了使整个表达式匹配成功,贪婪匹 配也会适当的“让出”已经匹配的字符。因此贪婪匹配也有类似的情况。当一个表达式中有较多的未知匹配次数的表达式时,为了让整个表达式匹配成功,各个贪婪 或非贪婪的表达式都要进行尝试减少或增加匹配次数,由此容易形成一个大循环的尝试,造成了很长的匹配时间。本文之所以称之为“陷阱”,因为这种效率问题往 往不易察觉。
举例:"d(\w+?)d(\w+?)d(\w+?)z" 匹配 "ddddddddddd..." 时,将花费较长一段时间才能判断出匹配失败 。
效率陷阱的避免:
避免效率陷阱的原则是:避免“多重循环”的“尝试匹配”。并不是说非贪婪匹配就是不好的,只是在运用非贪婪匹配的时候,需要注意避免过多“循环尝试”的问题。
情 况一:对于只有一个非贪婪或者贪婪匹配的表达式来说,不存在效率陷阱。也就是说,要匹配类似 "<td> 内容 </td>" 这样的文本,表达式 "<td>([^<]|<(?!/td>))*</td>" 和 "<td>((?!</td>).)*</td>" 和 "<td>.*?</td>" 的效率是完全相同的。
情况二:如果一个表达式中有多个未知匹配次数的表达式,应防止进行不必要的尝试匹配。
比如,对表达式 "<script language='(.*?)'>(.*?)</script>" 来说, 如果前面部分表达式在遇到 "<script language='vbscript'>" 时匹配成功后,而后边的 "(.*?)</script>" 却匹配失败,将导致第一个 ".*?" 增加匹配次数再尝试。而对于表达式真正目的,让第一个 ".*?" 增加匹配成“vbscript'>”是不对的,因此这种尝试是不必要的尝试。
因此,对依靠边界来识别的表达式,不要让未知匹配次数的部分跨 过它的边界。前面的表达式中,第一个 ".*?" 应该改写成 "[^']*"。后边那个 ".*?" 的右边再没有未知匹配次数的表达式,因此这个非贪婪匹配没有效率陷阱。于是,这个匹配脚本块的表达式,应该写成:"<script language='([^']*)'>(.*?)</script>" 更好。
 
3.正则表达式-分组构造

分组构造使您可以捕获子表达式组并提高具有非捕获预测先行和回顾后发修饰符的正则表达式的效率。下表描述了正则表达式分组构造。
分组构造 说明
( ) 捕获匹配的子字符串(或非捕获组;有关详细信息,请参见正则表达式选项中的 ExplicitCapture 选项)。使用 () 的捕获根据左括号的顺序从 1 开始自动编号。捕获元素编号为零的第一个捕获是由整个正则表达式模式匹配的文本。
(?<name> ) 将匹配的子字符串捕获到一个组名称或编号名称中。用于 name 的字符串不能包含任何标点符号,并且不能以数字开头。可以使用单引号替代尖括号,例如 (?'name')。
(?<name1-name2> ) 平衡组定义。删除先前定义的 name2 组的定义并在 name1 组中存储先前定义的 name2 组和当前组之间的间隔。如果未定义 name2 组,则匹配将回溯。由于删除 name2 的最后一个定义会显示 name2 的先前定义,因此该构造允许将 name2 组的捕获堆栈用作计数器以跟踪嵌套构造(如括号)。在此构造中,name1 是可选的。可以使用单引号替代尖括号,例如 (?'name1-name2')。
(?: ) 非捕获组。
(?imnsx-imnsx: ) 应用或禁用子表达式中指定的选项。例如,(?i-s: ) 将打开不区分大小写并禁用单行模式。有关详细信息,请参见正则表达式选项。
(?= ) 零宽度正预测先行断言。仅当子表达式在此位置的右侧匹配时才继续匹配。例如,\w+(?=\d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。
(?! ) 零宽度负预测先行断言。仅当子表达式不在此位置的右侧匹配时才继续匹配。例如,\b(?!un)\w+\b 与不以 un 开头的单词匹配。
(?<= ) 零宽度正回顾后发断言。仅当子表达式在此位置的左侧匹配时才继续匹配。例如,(?<=19)99 与跟在 19 后面的 99 的实例匹配。此构造不会回溯。
(?<! ) 零宽度负回顾后发断言。仅当子表达式不在此位置的左侧匹配时才继续匹配。
(?> ) 非回溯子表达式(也称为“贪婪”子表达式)。该子表达式仅完全匹配一次,然后就不会逐段参与回溯了。(也就是说,该子表达式仅与可由该子表达式单独匹配的字符串匹配。)
命 名捕获根据左括号的从左到右的顺序按顺序编号(与非命名捕获类似),但在对所有非命名捕获进行计数之后才开始对命名捕获进行编号。例如,模式 ((?<One>abc)/d+)?(?<Two>xyz)(.*) 按编号和名称产生下列捕获组。(编号为 0 的第一个捕获总是指整个模式)。
编号 名称 模式
0 0(默认名称) ((?<One>abc)/d+)?(?<Two>xyz)(.*)
1 1(默认名称) ((?<One>abc)/d+)
2 2(默认名称) (.*)
3 1 (?<One>abc)
4 2 (?<Two>xyz)

 
4.正则表达式-替换和分组
替换使用 | 字符来允许在两个或多个替换选项之间进行选择。例如,可以扩展章节标题正则表达式,以返回比章标题范围更广的匹配项。但是,这并不象您可能认为的那样简 单。替换匹配 | 字符两边的尽可能最大的表达式。您可能认为,下面的表达式匹配出现在行首和行尾、后面跟一个或两个数字的 Chapter 或 Section:
/^Chapter|Section [1-9][0-9]{0,1}$/
很遗憾,上面的正则表达式要么匹配行首的单词 Chapter,要么匹配行尾的单词 Section 及跟在其后的任何数字。如果输入字符串是 Chapter 22,那么上面的表达式只匹配单词 Chapter。如果输入字符串是 Section 22,那么该表达式匹配 Section 22。
若要使正则表达式更易于控制,可以使用括号 来限制替换的范围,即,确保它只应用于两个单词 Chapter 和 Section。但是,括号也用于创建子表达式,并可能捕获它们以供以后使用,这一点在有关反向引用的那一节讲述。通过在上面的正则表达式的适当位置添加 括号,就可以使该正则表达式匹配 Chapter 1 或 Section 3。
下面的正则表达式使用括号来组合 Chapter 和 Section,以便表达式正确地起作用:
/^(Chapter|Section) [1-9][0-9]{0,1}$/
虽 然这些表达式正确发挥作用,但 Chapter| Section 两边的括号还会使得两个匹配单词中的任何一个被捕获以供将来使用。由于在上面的表达式中只有一组括号,因此,只有一个被捕获的“子匹配项”。可以通过使用 RegExp 对象的 $1-$9 属性来引用此子匹配项。
在上面的示例中,您只需要使用括号来组合单词 Chapter 和 Section 之间的选择。若要防止匹配被保存以备将来使用,请在括号内正则表达式模式之前放置 ?:。下面的修改提供相同的能力而不保存子匹配项:
/^(?:Chapter|Section) [1-9][0-9]{0,1}$/
除 ?: 元字符外,两个其他非捕获元字符创建被称为“预测先行”匹配的某些内容。正向预测先行使用 ?= 指定,它匹配处于括号中匹配正则表达式模式的起始点的搜索字符串。反向预测先行使用 ?! 指定,它匹配处于与正则表达式模式不匹配的字符串的起始点的搜索字符串。
例 如,假设您有一个文档,该文档包含指向 Windows 3.1、Windows 95、Windows 98 和 Windows NT 的引用。再进一步假设,您需要更新该文档,将指向 Windows 95、Windows 98 和 Windows NT 的所有引用更改为 Windows 2000。下面的正则表达式(这是一个正向预测先行的示例)匹配 Windows 95、Windows 98 和 Windows NT:
/Windows(?=95 |98 |NT )/
找到一处匹配后,紧接着就在匹配的文本(不包括预测先行中的字符)之后搜索下一处匹配。例如,如果上面的表达式匹配 Windows 98,将在 Windows 之后而不是在 98 之后继续搜索。

SQL Server 2005 之 事物复制

SQL Server 2005相对于SQL Server 2000来说,无论是性能还是功能都有一个相当大的提高,甚至可以用“革命”来形容这一次升级。SQL Server 2005使 SQL Server 跻身于企业级数据库行列。在数据高可用性方面,SQL Server 2005为用户提供了数据镜像、复制、故障转移群集、日志传送功能。本文向读者简单介绍SQL Server 2005的复制功能。

    一、 “复制”简介

    复制是将数据或数据库对象从一个数据库复制和分发到另外一个数据库,并进行数据同步,从而使源数据库和目标数据库保持一致。使用复制,可以在局域网和广域网、拨号连接、无线连接和 Internet 上将数据分发到不同位置以及分发给远程或移动用户。

    一组SQL Server 2005复制有发布服务器、分发服务器、订阅服服务器(图1:复制服务器之间的关系图)组成,它们之间的关系类似于书报行业的报社或出版社、邮局或书店、读者之间的关系。

    以报纸发行为例说明,发布服务器类似于报社,报社提供报刊的内容并印刷,是数据源;分发服务器相当于邮局,它将各报社的报刊送(分发)到订户手中;订阅服 务器相当于订户,从邮局那里收到报刊。在实际的复制中,发布服务器是一种数据库实例,它通过复制向其他位置提供数据,分发服务器也是一种数据库实例,它起 着存储区的作用,用于复制与一个或多个发布服务器相关联的特定数据。每个发布服务器都与分发服务器上的单个数据库(称作“分发数据库”)相关联。分发数据 库存储复制状态数据和有关发布的元数据,并且在某些情况下为从发布服务器向订阅服务器移动的数据起着排队的作用。在很多情况下,一个数据库服务器实例充当 发布服务器和分发服务器两个角色,这称为“本地分发服务器”。订阅服务器是接收复制数据的数据库实例。一个订阅服务器可以从多个发布服务器和发布接收数 据。

点击查看原图

图1

    复制有三种类:事务复制、快照复制、合并复制。

  •  

    ? 事务复制:事务复制是将复制启用后的所有发布服务器上发布的内容在修改时传给订阅服务器,数据更改将按照其在发布服务器上发生的顺序和事务边界,应用于订阅服务器,在发布内部可以保证事务的一致性。

     

  •  

    ? 快照复制:快照复制将数据以特定时刻的瞬时状态分发,而不监视对数据的更新。发生同步时,将生成完整的快照并将其发送到订阅服务器。

     

  •  

    ? 合并复制:合并复制通常是从发布数据库对象和数据的快照开始,并且用触发器跟踪在发布服务器和订阅服务器上所做的后续数据更改和架构修改。订阅服务器在连接到网络时将与发布服务器进行同步,并交换自上次同步以来发布服务器和订阅服务器之间发生更改的所有行。

     

二、复制实例

 

    这里以配置一个事务复制来说明复制配置过程 。

    试验在同一台机器的二个实例间进行,实例名分别是SERVER01、SERVER02 。将SERVER01配置发布服务器和分发服务器(也就是前面提到的“本地分发服务器”),SERVER02配置为订阅服务器。在本例中将 SERVER01中一个DBCoper库中person表作为发布的数据,在发布前请确保person表有主键、SQL SERVER 代理自动启动、发布数据库是日志是完整模式。

    第一步:完全备份SERVER01 DBCopy数据库,在SERVER02上恢复DBCopy数据库(复制前的同步,使用发布的源和目标数据一致)。

       第二步: 在SERVER01上设置发布和分发。

    A、 在SERVER01的复制节点-->本地发布右键选择新建订阅(如图2)。

点击查看原图

图2

    B、 在新建发布向导中首先要求选择分发服务器,本例选择本机作为分发服务器,选择默认值(如图3)。

点击查看原图

图3

    C、 向导第三步要求选择快照的路径,一般情况下选择默认路径。

    D、 向导第四步选择发布的数据库(如图四),选择DBCopy。

点击查看原图

图4

    E、 接着选择发布的类型,这里选择事务复制(如图5)。

点击查看原图

图5

    F、 选择发布的内容(PERSON),这里不仅可以发表,还可以发布其他的数据库对象,比如函数。在选择某一个表之后还可以选择发布某一列或几列。在这个步骤下一个界面中可以选择要发布的行。

点击查看原图

图6

    G、 设置发布的内容之后设置 运行SQL代理的账号。设置如下:

点击查看原图

图7

    H、 设置上一步之后,给复制起个名字PersonCopy。到此为止,发布和分发已配置成功(如图8)。

点击查看原图

图8第三步:配置订阅

    订阅有两种方种,一种是由发布服务器向订阅服务器“推”数据,由订阅服务器去请求订阅数据。本例在SERVER02上设置请求订阅。

    A、 第一步在SERVER02复制节点右击订阅,新建订阅(图9)。

点击查看原图

图9

    B、 选择发布服务器,在下拉列表框中选择查找SQL SERVER 发布服务器,选择SERVER01,就可以看到刚才新建的发布PersonCopy(如图10)。

点击查看原图

图10

    C、 选择订阅方式(如图11), 这里选择请求订阅。

点击查看原图

图11

    D、 选择订阅的本地数据库(如图12)。

点击查看原图

图12

    E、 设置完本地数据库之后要求设置运行代理的安全性,设置成SQL 代理账号。完成以上设置后,订阅已设置完成。

    在SERVER01表中插入一条新记录后,在SERVER02中去检查是否同步过来。一般来说,几乎SERVER01执行完了,SERVER02就可以看到更新后的数据。

 

 

***************************

以上实在网上看到一个网友的文章的,图文并茂的 还不错

自己也在做数据库复制

不过是从sql server2000到 sql server2005

之前复制是成功了的,但是 不知干嘛现在又执行不了了

重做一下

实际验证一下这位仁兄的做法 再来评价一下

 

 

--------20090507

要把订阅服务器上那个新建的订阅的 快照文件夹地址 换成  “\\\\

发布服务器名称\\快找文件夹”

右键点击 订阅服务器的“本地订阅”下的订阅文件,进入“属性”

点击查看原图

属性界面如下,将“4.快照”下面的 “快照文件夹” 改成  “\\\\

发布服务器名称\\快找文件夹”

(我的,改成了\\\\mz02\\ReplData

,mz02是我的SQL Server 2000 发布服务器,ReplData是我在mz02的D盘上建立的快照文件夹,先前被我设置成共享文件夹了)

点击查看原图

编写简单的脚本解释器

首先声明一下以下文章是跟据我用C#写的脚本解释器的经验之谈,如不认可也请不要找本人。

一般写个脚本解释器需要以下的步骤:

源程序-词法分析-语法分析-生成中间代码-解释中间代码

一、我写的脚本解释器就是跟据上面的过程写的,下面说明一下本脚本解释器的语法。

1、语法规则:

(1)script_begin代表语句开始

(2)script_end代表语句结束

(3)条件语句:if 表达式 语句 endif

(4)循环语句:while 表达式 语句 endwhile

(5)赋值语句:变量=表达式

(6)表达式:

(为方便我们这里使用产生式来说明)

expr->expr+term|expr-term|term|term>=term|term<=term|term==term|term!=term|term>term|term<term|term

term->term*factor|term/factor|factor

factor->(expr)|数字|变量|字符串|!变量

(注意:产生式中的->代表前面的值可以是后面中的任何一个值,|代表着或的意思)

(7)变量:本脚本只有全局变量,我们使用一个结构符号表(另外这个表还保存着关键字等)来保存变量名、类型(说明是变量、关键字等)和值。以下是此符号表的定义:

public struct Symtable

{

public string value;

public string valuestr;

public int toketype;

}

Symtable[] m_table=new Symtable[max_size];

max_size的大小说明了本脚本可以定义的变量数有多少。

2、词法分析:

在这个阶段解释器把读取的字符分为以下类型:

(1)、变量

(2)、数字

(3)、字符串

(4)、+、-、*、/等符号

(5)、if、while等关键字

以下是此过程的代码:

       private int lexan(StreamReader sr)

        {

            m_tmpvalue = "";

            char t;

            while (true)

            {

                t = (char)sr.Read();

                if (sr.EndOfStream)

                {

                    return -1;

                }

                if (t == ' ')

                {

                }

                else if (t == '\r')

                {

                    t = (char)sr.Read();

                    if (t == '\n')

                    {

                        error_line_num++;

                    }

                }

                else if (Char.IsDigit(t))

                {

                    while (Char.IsDigit(t))

                    {

                        m_tmpvalue += t;

                        t = (char)sr.Peek();

                        if (Char.IsDigit(t))

                        {

                            sr.Read();

                        }

                    }

                    return m_numtype;

                }

                else if (isStrword(t))

                {

                    while (isStrword(t))

                    {

                        m_tmpvalue += t;

                        t = (char)sr.Peek();

                        if (isStrword(t))

                        {

                            sr.Read();

                        }

                    }

                    int p = LookUp(m_tmpvalue);

                    if (p == -1)

                    {

                        p = InertTable(m_tmpvalue, m_idtype);

                    }

                    return m_symtable[p].toketype;

                }

                else if (isSingleword(t))

                {

                    return (int)t;

                }

                else if (isDoubleword(t))

                {

                    char tmpc = (char)sr.Peek();

                    if (tmpc == '=')

                    {

                        sr.Read();

                        if (t == '>')

                        {

                            return m_largede;

                        }

                        else if (t == '<')

                        {

                            return m_smallde;

                        }

                        else if (t == '!')

                        {

                            return m_bude;

                        }

                        else if (t == '=')

                        {

                            return m_dede;

                        }

                        else

                        {

                            CException.ScriptError("格式错误!");

                        }

                    }

                    return (int)t;

                }

                else if (t == '\"')

                {

                    t=(char)sr.Read();

                    while (t != '\"')

                    {

                        m_tmpvalue += t;

                        t = (char)sr.Read();

                    }

                    return m_strtype;

                }

                else

                {

                    CException.ScriptError("错误格式");

                    return -1;

                }

            }

      }

2、语法分析:

在这个过程中对读取的字符按产生式的进行分阶段处理;表达式从中缀变成后缀,中缀就像3+4+5的后缀就是34+5+并面在后缀中是不需要括号的。这个阶段还要生成中间代码。

代码如下:

        private void match(int t, StreamReader sr)
        {
            if (t == m_headtype)
            {
                m_headtype = lexan(sr);
            }
            else
            {
                CException.ScriptError("错误格式");
            }
        }
        private void WriteToMemory(string s)
        {
            m_zhongJingdaima += s;
        }
        public int stmtExplain(StreamReader sr)
        {
            if (m_headtype == m_begintype)
            {
                match(m_headtype, sr);
                int ret = stmtExplain(sr);
                while (ret != 0)
                {
                    ret = stmtExplain(sr);
                }
            }
            else if (m_headtype == m_endtype)
            {
                match(m_headtype, sr);
                return 0;
            }
            else if (m_headtype == m_iftype)
            {
                WriteToMemory("label:" + label_line + "\n");
                label_line++;
                match(m_headtype, sr);
                expr(sr);
                WriteToMemory("gofalse label:" + label_line + " \n");

                stmtExplain(sr);
                match(m_endif, sr);
                WriteToMemory("label:" + label_line + "\n");
                label_line++;
            }
            else if (m_headtype == m_whiletype)
            {
                int tmplabel=label_line;
                WriteToMemory("label:" + label_line + "\n");
                label_line++;
                match(m_headtype, sr);
                expr(sr);
                WriteToMemory("gofalse label:" + label_line + " \n");

                stmtExplain(sr);
                match(m_endwhile, sr);
                WriteToMemory("goto label:" + tmplabel + " \n");
                WriteToMemory("label:" + label_line + "\n");
                label_line++;
            }
            else if (m_headtype == m_funtiontype)
            {
                WriteToMemory("function ");
                WriteToMemory(m_tmpvalue);

                WriteToMemory("\n");
                match(m_headtype, sr);
            }
            else if (m_headtype == m_idtype)
            {

                int index = LookUp(m_tmpvalue);
                WriteToMemory("lvalue " + m_tmpvalue + "\n");
                match(m_headtype, sr);
                match('=', sr);
                expr(sr);
                WriteToMemory(":=\n");
            }
            return 1;
        }
        private void expr(StreamReader sr)
        {
            term(sr);
            while (true)
            {
                switch (m_headtype)
                {
                    case '+':
                        {
                            match(m_headtype, sr);
                            term(sr);
                            WriteToMemory("+\n");
                            continue;
                        }
                    case '-':
                        {
                            match(m_headtype, sr);
                            term(sr);
                            WriteToMemory("-\n");
                            continue;
                        }
                    case m_largede:
                        {
                            match(m_headtype, sr);
                            term(sr);
                            WriteToMemory(">=\n");
                            continue;
                        }

                    case m_smallde:
                        {
                            match(m_headtype, sr);
                            term(sr);
                            WriteToMemory("<=\n");
                            continue;
                        }
                    case m_bude:
                        {
                            match(m_headtype, sr);
                            term(sr);
                            WriteToMemory("!=\n");
                            continue;
                        }
                    case m_dede:
                        {
                            match(m_headtype, sr);
                            term(sr);
                            WriteToMemory("==\n");
                            continue;
                        }
                    case '>':
                        {
                            match(m_headtype, sr);
                            term(sr);
                            WriteToMemory(">\n");
                            continue;
                        }
                    case '<':
                        {
                            match(m_headtype, sr);
                            term(sr);
                            WriteToMemory("<\n");
                            continue;
                        }
                    default:
                        return;
                }
            }
        }
        private void term(StreamReader sr)
        {
            factor(sr);
            while (true)
            {
                switch (m_headtype)
                {
                    case '*':
                        {
                            match(m_headtype, sr);
                            factor(sr);
                            WriteToMemory("*\n");
                            continue;
                        }
                    case '/':
                        {
                            match(m_headtype, sr);
                            factor(sr);
                            WriteToMemory("/\n");
                            continue;
                        }
                    default:
                        return;
                }
            }
        }
        private void factor(StreamReader sr)
        {
           
            switch (m_headtype)
            {
                case '(':
                    {
                        match('(', sr);
                        expr(sr);
                        match(')', sr);
                        break;
                    }
                case m_numtype:
                    {
                        WriteToMemory("push " + m_tmpvalue + "\n");
                        match(m_numtype, sr);
                        break;
                    }
                case m_idtype:
                    {
                        WriteToMemory("rvalue "+m_tmpvalue+"\n");
                        match(m_idtype, sr);
                        break;
                    }
                case m_strtype:
                    {
                        WriteToMemory("push " + m_tmpvalue + "\n");
                        match(m_headtype, sr);
                        break;
                    }
                case '!':
                    {   
                        match(m_headtype, sr);
                        match(m_headtype, sr);
                        WriteToMemory("oppvalue "+m_tmpvalue+"\n");
                        break;
                    }
                case m_funtiontype:
                    {
                        WriteToMemory("function ");
                        WriteToMemory(m_tmpvalue);

                        WriteToMemory("\n");
                        match(m_headtype, sr);
                        break;
                    }
                default:
                    CException.ScriptError("错误格式!");
                    break;
            }
        }
        private string ReadStrLine(string s)
        {
            int tmpindex = s.IndexOf("\n",m_excuteline_index);
            string tmpstr;
            if (tmpindex != -1)
            {
                int readlength=tmpindex-m_excuteline_index;
                tmpstr = s.Substring(m_excuteline_index,readlength);
                m_excuteline_index = tmpindex+1;
            }
            else
            {
                return null;
            }
            return tmpstr;
        }

 

二、现在我们的已把你的难以解释的脚本语言生成容易解释的中间代码,现在开始解释中间代码,为完成这个目标我们先看下中间语言的语法规则:

中间语法:

Push / 把/压栈

Lvalue /取值压栈

+ 弹出栈顶两个值相加后压栈

function 函数

等等

 

      private void ExectStr()
        {
            string retstr;
            retstr = ReadStrLine(m_zhongJingdaima);
            while (retstr != null)
            {
                if (retstr.StartsWith("lvalue"))
                {
                    string[] split = retstr.Split(new char[] { ' ' });
                    int index=LookUp(split[1]);
                    m_stack.push(Convert.ToString(index));
                }
                else if (retstr.StartsWith("function"))
                {
                    string tmpvalue = retstr.Substring(9);
                    string pushvalue = null;
                    int paramstart = tmpvalue.IndexOf('(') + 1;
                    int paramend = tmpvalue.LastIndexOf(')');
                    int paramlength = paramend - paramstart;
                    string subparam = tmpvalue.Substring(paramstart, paramlength);
                    ArrayList split=new ArrayList();

                    while (true)
                    {
                        string paramstr="";
                        int startindex=0;
                        if (subparam.StartsWith("\""))
                        {
                            startindex = subparam.IndexOf("\"", 1);
                            if (startindex == -1)
                            {
                                break;
                            }
                            paramstr = subparam.Substring(1, startindex - 1);
                            startindex = subparam.IndexOf(",", startindex);

                        }
                        else
                        {
                           
                            startindex = subparam.IndexOf(",", startindex);
                            if (startindex == -1)
                            {
                                paramstr = subparam;
                            }
                            else
                            {
                                paramstr = subparam.Substring(0, startindex);
                            }
                            int tmplookindex = LookUp(paramstr);
                            if (tmplookindex != -1)
                            {
                                paramstr = m_symtable[tmplookindex].value;
                            }
                        }
                        split.Add(paramstr);                     
                        if (startindex == -1)
                        {
                            break;
                        }
                        startindex++;
                        subparam = subparam.Substring(startindex);      
                    }

                   

                    if (tmpvalue.StartsWith("Strcat"))
                    {
                        pushvalue = m_globalFunction.Strcat(split[0].ToString(), split[1].ToString());
                    }
                    else if (tmpvalue.StartsWith("StartSplit"))
                    {
                        pushvalue = m_globalFunction.StartSplit(split[0].ToString(), split[1].ToString());
                    }
                    else if (tmpvalue.StartsWith("NextSplit"))
                    {
                        pushvalue = m_globalFunction.NextSplit(split[0].ToString(), split[1].ToString());
                    }
                    else if (tmpvalue.StartsWith("GetSplit"))
                    {
                        pushvalue = m_globalFunction.GetSplit(split[0].ToString(), split[1].ToString(), Convert.ToInt32(split[2]));
                    }
                    else
                    {
                        CException.ScriptError("错误格式!");
                    }
                    if (pushvalue != null)
                    {
                        m_stack.push(pushvalue);
                    }
                }
                else if (retstr.StartsWith("push"))
                {
                    //int index=retstr.IndexOf(' ', 0);
                    string tmpstr = retstr.Substring(5);
                    m_stack.push(tmpstr);
                }
                else if (retstr.StartsWith("oppvalue"))
                {
                    string[] split = retstr.Split(new char[] { ' ' });
                    int index = LookUp(split[1]);
                    bool tmpbool = !Convert.ToBoolean(m_symtable[index].value);
                    m_stack.push(Convert.ToString(tmpbool));
                }
                else if (retstr.StartsWith("rvalue"))
                {
                    string[] split = retstr.Split(new char[] { ' ' });
                    int index = LookUp(split[1]);
                    m_stack.push(m_symtable[index].value);
                }
                else if (retstr.StartsWith(":="))
                {
                    string rtmpvalue = m_stack.pop();
                    string ltmpvalue = m_stack.pop();
                    m_symtable[Convert.ToInt32(ltmpvalue)].value = rtmpvalue;
                }
                else if (retstr.StartsWith("+"))
                {
                    string ltmpvalue = m_stack.pop();
                    string rtmpvalue = m_stack.pop();
                    string totalvalue = Convert.ToString(Convert.ToInt32(ltmpvalue) + Convert.ToInt32(rtmpvalue));
                    m_stack.push(totalvalue);
                }
                else if (retstr.StartsWith("*"))
                {
                    string rtmpvalue = m_stack.pop();
                    string ltmpvalue = m_stack.pop();
                    string totalvalue = Convert.ToString(Convert.ToInt32(ltmpvalue) * Convert.ToInt32(rtmpvalue));
                    m_stack.push(totalvalue);
                }
                else if (retstr.StartsWith("/"))
                {
                    string rtmpvalue = m_stack.pop();
                    string ltmpvalue = m_stack.pop();
                    string totalvalue = Convert.ToString(Convert.ToInt32(ltmpvalue) / Convert.ToInt32(rtmpvalue));
                    m_stack.push(totalvalue);
                }
                else if (retstr.StartsWith("-"))
                {
                    string rtmpvalue = m_stack.pop();
                    string ltmpvalue = m_stack.pop();
                    string totalvalue = Convert.ToString(Convert.ToInt32(ltmpvalue) - Convert.ToInt32(rtmpvalue));
                    m_stack.push(totalvalue);
                }
                else if (retstr.StartsWith(">="))
                {
                    string rtmpvalue = m_stack.pop();
                    string ltmpvalue = m_stack.pop();
                    if (Convert.ToInt32(ltmpvalue) >= Convert.ToInt32(rtmpvalue))
                    {
                        m_stack.push("true");
                    }
                    else
                    {
                        m_stack.push("false");
                    }
                }
                else if (retstr.StartsWith("!="))
                {
                    string rtmpvalue = m_stack.pop();
                    string ltmpvalue = m_stack.pop();
                    if (Convert.ToInt32(ltmpvalue) != Convert.ToInt32(rtmpvalue))
                    {
                        m_stack.push("true");
                    }
                    else
                    {
                        m_stack.push("false");
                    }
                }
                else if (retstr.StartsWith("<="))
                {
                    string rtmpvalue = m_stack.pop();
                    string ltmpvalue = m_stack.pop();
                    if (Convert.ToInt32(ltmpvalue) <= Convert.ToInt32(rtmpvalue))
                    {
                        m_stack.push("true");
                    }
                    else
                    {
                        m_stack.push("false");
                    }
                }
                else if (retstr.StartsWith(">"))
                {
                    string rtmpvalue = m_stack.pop();
                    string ltmpvalue = m_stack.pop();
                    if (Convert.ToInt32(ltmpvalue) > Convert.ToInt32(rtmpvalue))
                    {
                        m_stack.push("true");
                    }
                    else
                    {
                        m_stack.push("false");
                    }
                }
                else if (retstr.StartsWith("<"))
                {
                    string rtmpvalue = m_stack.pop();
                    string ltmpvalue = m_stack.pop();
                    if (Convert.ToInt32(ltmpvalue) < Convert.ToInt32(rtmpvalue))
                    {
                        m_stack.push("true");
                    }
                    else
                    {
                        m_stack.push("false");
                    }
                }
                else if (retstr.StartsWith("=="))
                {
                    string rtmpvalue = m_stack.pop();
                    string ltmpvalue = m_stack.pop();
                    if (ltmpvalue == rtmpvalue)
                    {
                        m_stack.push("true");
                    }
                    else
                    {
                        m_stack.push("false");
                    }
                }
                else if (retstr.StartsWith("gofalse"))
                {
                    string rtmpvalue = m_stack.pop();
                    if (!Convert.ToBoolean(rtmpvalue))
                    {
                        string[] split = retstr.Split(new char[] { ' ' });
                        string strtofind = split[1] + "\n";
                        int tmppos = m_zhongJingdaima.IndexOf(strtofind);
                        m_excuteline_index = tmppos;
                    }
                }
                else if (retstr.StartsWith("gotrue"))
                {
                    string rtmpvalue = m_stack.pop();
                    if (Convert.ToBoolean(rtmpvalue))
                    {
                        string[] split = retstr.Split(new char[] { ' ' });
                        string strtofind = split[1] + "\n";
                        int tmppos = m_zhongJingdaima.IndexOf(strtofind);
                        m_excuteline_index = tmppos;
                    }
                }
                else if (retstr.StartsWith("goto"))
                {
                    string[] split = retstr.Split(new char[] { ' ' });
                    string strtofind = split[1] + "\n";
                    int tmppos = m_zhongJingdaima.IndexOf(strtofind);
                    m_excuteline_index = tmppos;
                }
                retstr = ReadStrLine(m_zhongJingdaima);
            }
        }

 

窥视生命的本质

美国科学家制造出完全由人造基因控制的单细胞细菌

20日,美国科学家宣布世界首例人造生命———完全由人造基因控制的单细胞细菌诞生,并将它命名为“人造儿”。这项具有里程碑意义的实验表明,新的生命体可以在实验室里“被创造”,而不是一定要通过“进化”来完成。

“一个新时代到来”

这项研究由美国基因遗传学顶尖科学家克莱格·凡特主持,历时10多年,耗资超过4000万美元。研究团队共有20多位科学家。

名为“人造儿”的人造细菌内核是移植于实验室、完全人工合成的基因组。凡特博士表示这意味着“一个新时代的到来”。

科学家们首先选取一种名为丝状支原体的细菌,对其基因组进行解码并复制,产生人造的合成基因组。然后,将人造基因组移植入另一种称为山羊支原体的细菌,通过分裂和增生,细菌内部的细胞逐渐为人造基因所控制,最终成为一种全新的生命。在培养皿中,合成细菌的分裂等行为就像天然细菌一样。

科学家们在“人造儿”DNA上写入4个“水印序列”,使其有别于同类的天然细菌,以及在这种生物的后代中识别它的“祖先”。

“当带着水印的细胞活了过来,我们欣喜若狂,它是一个活生生的生物了,成为了我们地球上各种生命的一部分。”凡特博士说。

应用前景广阔

尽管这种技术目前仍处于实验阶段,但研究人员相信其运用前景广阔。

研究小组计划,先合成出可供生命存在的最小数量的基因,然后通过向其中弥补其他基因,制造一系列新的微生物,比如可生产生物燃料的细菌、有用的药品、可以从空气中吸收二氧化碳和其他污染物的细菌或是制造合成疫苗所需的蛋白质。

人造生命原理

1. 科学家选取一种名为丝状支原体的细菌,将它的染色体解码。然后利用化学方法一点一点地重新排列DNA。

2. 将重组的DNA碎片放入酵母液中,令其慢慢地重新聚合。

3. 将人造DNA放入另外一个受体细菌中。通过生长和分离,受体细菌产生两个细胞,一个带有人造DNA,另外一个带有天然DNA。

4. 培养皿中的抗生素将带有天然DNA的细胞杀死,只留下人造细胞不断增生。

5. 几个小时之内,受体细菌内原有DNA的所有痕迹全部消失,人造细胞不断繁殖。新的生命诞生了。

■ 链接

反对者称“打开潘多拉魔盒”

“创造生命”再次激起了古老的争论:人类是否可以扮演上帝的角色?

英国牛津大学的伦理学教授朱利安·萨乌莱斯库认为:“凡特推开了人类历史上最重要、最基础的那扇大门———窥视生命的本质。他直接扮演了上帝的角色———创造出自然界原本不存在的新生命。”

一个名为“人类基因学警告”的团体负责人戴维·金说:“凡特的研究无异于打开了潘多拉的魔盒。”反对者认为,人造的有机体如果扩散到自然界,引发生物基因变化,有可能造成环境灾难,它们还有可能被用来制造生物武器。

用户体验设计

------------------------------------------------------------

UED = user experience design,用户体验设计

 

  UED的本意是用户体验设计,是英文User Experience Design的缩写。通常的理解,我们做的一切都是为了呈现在您眼前的页面。

全称是Customer Research & User Experience Design Center(即用户研究与体验设计中心)

-------------------------------------------------------------

观察各领导先驱者,他们走在你前面

是反省还是遥望,成功是必然还是偶然?

淘宝UED

蓝色理想

携程UED

网易UED

人人网FED

腾讯CDC

腾讯ISD

盛大UED

搜狐UED

口碑网UED

支付宝UED

HTTP(CODE)代码

Information Codes | Success Codes | Redirection Codes | Failure Codes | Server Error Codes | Internet API Error Codes | FTP API Error Codes | Gopher API Error Codes | HTTP API Error Codes | Additional Internet API Error Codes

Information Codes

100 - Continue
101 - Switching Protocols

Top

Success Codes

200 - OK
201 - Created
202 - Accepted
203 - Non-Authoritative Information (for DNS)
204 - No Content
205 - Reset Content
206 - Partial Content

Top

Redirection Codes

300 - Multiple Choices
301 - Moved Permanently
302 - Moved Temporarily
303 - See Other
304 - Not Modified
305 - Use Proxy
307 - Redirect Keep Verb

Top

Failure Codes

400 - Bad Request
401 - Unauthorized
402 - Payment Required
403 - Forbidden
404 - Not Found
405 - Bad Request
406 - Not Acceptable
407 - Proxy Authentication Required
408 - Request Timed-Out
409 - Conflict
410 - Gone
411 - Length Required
412 - Precondition Failed
413 - Request Entity Too Large
414 - Request, URI Too Large
415 - Unsupported Media Type

Top

Server Error Codes

500 - Internal Server Error
501 - Not Implemented
502 - Bad Gateway
503 - Server Unavailable
504 - Gateway Timed-Out
505 - HTTP Version not supported

Top

Internet API Error Codes

12001 - Out of Handles
12002 - Timeout
12003 - Extended Error
12004 - Internal Error
12005 - Invalid URL
12006 - Unrecognized Scheme
12007 - Name Not Resolved
12008 - Protocol Not Found
12009 - Invalid Option
12010 - Bad Option Length
12011 - Option not Settable
12012 - Shutdown
12013 - Incorrect User Name
12014 - Incorrect Password
12015 - Login Failure
12016 - Invalid Option
12017 - Operation Cancelled
12018 - Incorrect Handle Type
12019 - Inccorect Handle State
12020 - Not Proxy Request
12021 - Registry Value Not Found
12022 - Bad Registry Parameter
12023 - No Direct Access
12024 - No Content
12025 - No Callback
12026 - Request Pending
12027 - Incorrect Format
12028 - Item Not Found
12029 - Cannot Connect
12030 - Connection Aborted
12031 - Connection Reset
12032 - Force Retry
12033 - Invalid Proxy Request
12034 - Need UI
12035 - Not Defined in WinInet
12036 - Handle Exists
12037 - See Cert Date Invalid
12038 - See Cert CN Invalid
12039 - HTTP to HTTPS on Redir
12040 - HTTPs to HTTP on Redir
12041 - Mixed Security
12042 - Chg Post is Non Secure
12043 - Post is Non Secure
12044 - Client Auth Cert Needed
12045 - Invalid CA (Cert)
12046 - Client Auth Not Setup
12047 - Async Thread Failed
12048 - Redirect Scheme Changed
12049 - Dialog Pending
12050 - Retry Dialog
12052 - Https Http Submit Redir
12053 - Insert Cdrom
12171 - Failed DueToSecurityCheck

Top

FTP API Error Codes

12110 - Transfer in Progress
12111 - FTP Dropped

Top

Gopher API Error Codes

12130 - Protocol Error
12131 - Not File
12132 - Data Error
12133 - End of Data
12134 - Invalid Locator
12135 - Invalid Locator Type
12136 - Not Gopher Plus
12137 - Attribute Not Found
12138 - Unknown Locator

Top

HTTP API Error Codes

12150 - Header Not Found
12151 - Downlevel Server
12152 - Invalid Server Response
12153 - Invalid Header
12154 - Invalid Query Request
12155 - Header Already Exists
12156 - Redirect Failed
12157 - Security Channel Error
12158 - Unable to Cache File
12159 - TCP/IP not installed
12160 - Not Redirected
12161 - Cookie Needs Confirmation
12162 - Cookie Declined
12168 - Redirect Needs Confirmation

Top

Additional Internet API Error Codes

12157 - Security Channel Error
12158 - Unable To Cache File
12159 - Tcpip Not Installed
12163 - Disconnected
12164 - Server Unreachable
12165 - Proxy Server Unreachable
12166 - Bad Auto Proxy Script
12167 - Unable To Download Script
12169 - Sec Invalid Cert
12170 - Sec Cert Revoked

Win2003网站服务器的安全配置全攻略

======================= 第一类 ===============================

本配置仅适合Win2003,部分内容也适合于Win2000。很多人觉得3389不安全,其实只要设置好,密码够长,攻破3389也不是件容易的事情,我觉得别的远程软件都很慢,还是使用了3389连接。

经测试,本配置在Win2003 + IIS6.0 + Serv-U + SQL Server 的单服务器多网站中一切正常。以下配置中打勾的为推荐进行配置,打叉的为可选配置。

一、系统权限的设置

1、磁盘权限

系统盘只给 Administrators 组和 SYSTEM 的完全控制权限

其他磁盘只给 Administrators 组完全控制权限

系统盘\Documents and Settings 目录只给 Administrators 组和 SYSTEM 的完全控制权限

系统盘\Documents and Settings\All Users 目录只给 Administrators 组和 SYSTEM 的完全控制权限

系统盘\windows\system32\config\ 禁止guests组

系统盘\Documents and Settings\All Users\「开始」菜单\程序\ 禁止guests组

系统盘\windowns\system32\inetsrv\data\ 禁止guests组

系统盘\Windows\System32\ at.exe、attrib.exe、cacls.exe、net.exe、net1.exe、netstat.exe、regedit.exe 文件只给 Administrators 组和 SYSTEM 的完全控制权限

系统盘\Windows\System32\ cmd.exe、format.com 仅 Administrators 组完全控制权限

把所有(Windows\system32和Windows\ServicePackFiles\i386) format.com 更名为 format_nowayh.com

2、本地安全策略设置

开始菜单->管理工具->本地安全策略

A、本地策略-->审核策略

审核策略更改 成功 失败

审核登录事件 成功 失败

审核对象访问失败

审核过程跟踪 无审核

审核目录服务访问失败

审核特权使用失败

审核系统事件 成功 失败

审核账户登录事件 成功 失败

审核账户管理 成功 失败

B、本地策略-->用户权限分配

关闭系统:只有Administrators组、其它全部删除。

通过终端服务拒绝登陆:加入Guests组

通过终端服务允许登陆:加入Administrators、Remote Desktop Users组,其他全部删除

C、本地策略-->安全选项

交互式登陆:不显示上次的用户名 启用

网络访问:不允许SAM帐户和共享的匿名枚举 启用

网络访问:不允许为网络身份验证储存凭证 启用

网络访问:可匿名访问的共享 全部删除

网络访问:可匿名访问的命全部删除

网络访问:可远程访问的注册表路径全部删除

网络访问:可远程访问的注册表路径和子路径全部删除

帐户:重命名来宾帐户重命名一个帐户

帐户:重命名系统管理员帐户 重命名一个帐户

D、账户策略-->账户锁定策略

将账户设为“5次登陆无效”,“锁定时间为30分钟”,“复位锁定计数设为30分钟”

二、其他配置

√·把Administrator账户更改

管理工具→本地安全策略→本地策略→安全选项

√·新建一无任何权限的假Administrator账户

管理工具→计算机管理→系统工具→本地用户和组→用户

更改描述:管理计算机(域)的内置帐户

×·重命名IIS来宾账户

1、管理工具→计算机管理→系统工具→本地用户和组→用户→重命名IUSR_ComputerName

2、打开 IIS 管理器→本地计算机→属性→允许直接编辑配置数据库

3、进入Windows\system32\inetsrv文件夹→MetaBase.xml→右键编辑→找到"AnonymousUserName"→写入"IUSR_"新名称→保存

4、关闭"允许直接编辑配置数据库"

√·禁止文件共享

本地连接属性→去掉"Microsoft网络的文件和打印共享"和"Microsoft 网络客户端"前面的"√"

√·禁止NetBIOS(关闭139端口)

本地连接属性→TCP/IP属性→高级→WINS→禁用TCP/IP上的NetBIOS

管理工具→计算机管理→设备管理器→查看→显示隐藏的设备→非即插即用驱动程序→禁用 NetBios over tcpip→重启

√·防火墙的设置

本地连接属性→高级→Windows防火墙设置→高级→第一个"设置",勾选FTP、HTTP、远程桌面服务

√·禁止ADMIN$缺省共享、磁盘默认共享、限制IPC$缺省共享(匿名用户无法列举本机用户列表、禁止空连接)

新建REG文件,导入注册表

Windows Registry Editor Version 5.00
 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters]
 "AutoshareWks"=dword:00000000
 "AutoShareServer"=dword:00000000
 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
 "restrictanonymous"=dword:00000001
 

√·删除以下注册表主键

WScript.Network
 WScript.Network.1
 {093FF999-1EA0-4079-9525-9614C3504B74}
 WScript.Shell
 WScript.Shell.1
 {72C24DD5-D70A-438B-8A42-98424B88AFB8}
 Shell.Application
 Shell.Application.1
 {13709620-C279-11CE-A49E-444553540000}
 

√·更改3389端口为12344

这里只介绍如何更改,既然本端口公布出来了,那大家就别用这个了,端口可用windows自带的计算器将10进制转为16进制,16进制数替换下面两个的dword:后面的值(7位数,不够的在前面补0),登陆的时候用10进制,端口更改在服务器重启后生效。新建REG文件,导入注册表

Windows Registry Editor Version 5.00
 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp]
 "PortNumber"=dword:0003038
 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp]
 "PortNumber"=dword:00003038
 

最后别忘了Windows防火墙允许12344端口,关闭3389端口

√·禁止非管理员使用at命令,新建REG文件,导入注册表

Windows Registry Editor Version 5.00
 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
 "SubmitControl"=dword:00000001
 

√·卸载最不安全的组件

运行"卸载最不安全的组件.bat",重启后更名或删掉Windows\System32\里的wshom.ocx和shell32.dll

----------------卸载最不安全的组件.bat-----------------
 regsvr32/u %SystemRoot%\System32\wshom.ocx
 regsvr32/u %SystemRoot%\System32\shell32.dll
 regsvr32/u %SystemRoot%\System32\wshext.dll
 -------------------------------------------------------
 

√·Windows日志的移动

打开"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\"
 

Application 子项:应用程序日志

Security 子项:安全日志

System 子项:系统日志

分别更改子项的File键值,再把System32\config目录下的AppEvent.Evt、SecEvent.Evt、SysEvent.Evt复制到目标文件夹,重启。
√·Windows日志的保护

1、移动日志后的文件夹→属性→安全→高级→去掉"允许父系的继承权限……"→复制→确定

2、保留System账户和User组,System账户保留除完全控制和修改之外的权限,User组仅保留只读权限

3、AppEvent.Evt、SysEvent.Evt保留Administrator、System账户和User组,Administrator、System账户保留除完全控制和修改之外的权 限,User组仅保留只读权限;

DnsEvent.Evt、SecEvent.Evt保留System账户和User组,System账户保留除完全控制和修改之外的权限,User组仅保留只读权限

√·要手动停止/禁用的服务:Computer Browser、Error reporting service、Microsoft Serch、Print Spooler、Remote Registry、Server 、TCP/IP NetBIOS Helper、Workstation

√·解决在 IIS 6.0 中,无法下载超过4M的附件(现改为10M)

停止IIS服务→打开WINDOWS\system32\inetsrv\→记事本打开MetaBase.xml→找到 AspBufferingLimit 项→值改为 10485760

√·设置Web上传单个文件最大值为10 MB

停止IIS服务→打开WINDOWS\system32\inetsrv\→记事本打开MetaBase.xml→找到 AspMaxRequestEntityAllowed 项→值改为 10485760

×·重新定位和设置 IIS 日志文件的权限

1、将 IIS 日志文件的位置移动到非系统分区:在非系统的NTFS分区新建一文件夹→打开 IIS 管理器→右键网站→属性→单击"启用日志 记录"框架中的"属性"→更改到刚才创建的文件夹

2、设置 IIS 日志文件的权限:浏览至日志文件所在的文件夹→属性→安全→确保Administrators和System的权限设置为"完全控制"

×·配置 IIS 元数据库权限

打开 Windows\System32\Inetsrv\MetaBase.xml 文件→属性→安全→确认只有 Administrators 组的成员和 LocalSystem 帐户拥有对元 数据库的完全控制访问权,删除所有其他文件权限→确定

解释 Web 内容的权限

打开IIS管理器→右键想要配置的网站的文件夹、网站、目录、虚拟目录或文件

脚本源文件访问,用户可以访问源文件。如果选择"读",则可以读源文件;如果选择"写",则可以写源文件。脚本源访问包括脚本的源代码 。如果"读"或"写"均未选择,则此选项不可用。

读(默认情况下选择):用户可以查看目录或文件的内容和属性。

写:用户可以更改目录或文件的内容和属性。

目录浏览:用户可以查看文件列表和集合。

日志访问:对网站的每次访问创建日志项。

检索资源:允许检索服务检索此资源。这允许用户搜索资源。

√·关闭自动播放

运行组策略编辑器(gpedit.msc)→计算机配置→管理模板→系统→关闭自动播放→属性→已启用→所有驱动器

√·禁用DCOM

运行Dcomcnfg.exe。控制台根节点→组件服务→计算机→右键单击“我的电脑”→属性”→默认属性”选项卡→清除“在这台计算机上启用分布式 COM”复选框。

√·启用父路径

IIS管理器→右键网站→属性→主目录→配置→选项→启用父路径

√·IIS 6.0 系统无任何动作超时时间和脚本超时时间

IIS管理器→右键网站→属性→主目录→配置→选项→分别改为40分钟和180秒

√·删除不必要的IIS扩展名映射

IIS管理器→右击Web站点→属性→主目录→配置→映射,去掉不必要的应用程序映射,主要为.shtml, .shtm, .stm

√·增加IIS对MIME文件类型的支持

IIS管理器→选择服务器→右键→属性→MIME类型(或者右键web站点→属性→HTTP头→MIME类型→新建)添加如下表内容,然后重启IIS,扩展名MIME类型

.iso application/octet-stream
 .rmvb application/vnd.rn-realmedia
 

√·禁止dump file的产生

我的电脑→右键→属性→高级→启动和故障恢复→写入调试信息→无。

dump文件在系统崩溃和蓝屏的时候是一份很有用的查找问题的资料(不然我就照字面意思翻译成垃圾文件了)。然而,它也能够给黑客提供 一些敏感信息比如一些应用程序的密码等。

三、Serv-U FTP服务的设置

√·本地服务器→设置→拦截"FTP_bounce"攻击和FXP

对于60秒内连接超过10次的用户拦截5分钟

√·本地服务器→域→用户→选中需要设置的账号→右边的"同一IP只允许2个登录"

√·本地服务器→域→设置→高级→取消"允许MDTM命令来更改文件的日期/时间"

设置Serv-U程序所在的文件夹的权限,Administrator组完全控制,禁止Guests组和IIS匿名用户有读取权限

服务器消息,自上而下分别改为:

服务器工作正常,现已准备就绪...
 错误!请与管理员联系!
 FTP服务器正在离线维护中,请稍后再试!
 FTP服务器故障,请稍后再试!
 当前账户达到最大用户访问数,请稍后再试!
 很抱歉,服务器不允许匿名访问!
 您上传的东西太少,请上传更多东西后再尝试下载!
 

四、SQL安全设置

审核指向SQL Server的连接

企业管理器→展开服务器组→右键→属性→安全性→失败

修改sa账户密码

企业管理器→展开服务器组→安全性→登录→双击sa账户

SQL查询分析器

use master
 exec sp_dropextendedproc xp_cmdshell
 exec sp_dropextendedproc xp_dirtree
 exec sp_dropextendedproc xp_enumgroups
 exec sp_dropextendedproc xp_fixeddrives
 exec sp_dropextendedproc xp_loginconfig
 exec sp_dropextendedproc xp_enumerrorlogs
 exec sp_dropextendedproc xp_getfiledetails
 exec sp_dropextendedproc Sp_OACreate
 exec sp_dropextendedproc Sp_OADestroy
 exec sp_dropextendedproc Sp_OAGetErrorInfo
 exec sp_dropextendedproc Sp_OAGetProperty
 exec sp_dropextendedproc Sp_OAMethod
 exec sp_dropextendedproc Sp_OASetProperty
 exec sp_dropextendedproc Sp_OAStop
 exec sp_dropextendedproc Xp_regaddmultistring
 exec sp_dropextendedproc Xp_regdeletekey
 exec sp_dropextendedproc Xp_regdeletevalue
 exec sp_dropextendedproc Xp_regenumvalues
 exec sp_dropextendedproc Xp_regread
 exec sp_dropextendedproc Xp_regremovemultistring
 exec sp_dropextendedproc Xp_regwrite
 drop procedure sp_makewebtask
 

(完)

*****************************第二************************************

引用
补充
1终端服务默认端口号:3389。
更改原因:不想让非法用户连接到服务器进行登录实验。当这台服务器托管在外时更不希望发生这种情况,呵呵,还没忘记2000的输入法漏洞吧?
更改方法:
  (1)、第一处[HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Terminal Server \ Wds \ rdpwd \ Tds \ tcp],看到右边的PortNumber了吗?在十进制状态下改成你想要的端口号吧,比如7126之类的,只要不与其它冲突即可。
  (2)、第二处[HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Terminal Server \ WinStations \ RDP-Tcp,方法同上,记得改的端口号和上面改的一样就行了。

2系统盘\Windows\System32\cacls.exe、cmd.exe、net.exe、net1.exe、telnet.exe、ftp.exe 文件只给 Administrators 组和 SYSTEM 的完全控制权限

注册表删除 WScript.Shell、WScript.Shell.1、Wscript.Network、Wscript.Network.1、Shell.application
注册表改名 adodb.stream、Scripting.Dictionary、Scripting.FileSystemObject

3启用防火墙和tcp/ip过滤,再serv-u开启一组端口映射
  80 \ 20 \ 21 \ 2121 \ * 以及serv-u端口组
  

4关闭默认共享
  
  在Windows 2000中,有一个“默认共享”,这是在安装服务器的时候,把系统安装分区自动进行共享,虽然对其访问还需要超级用户的密码,但这是潜在的安全隐患,从服务器的安全考虑,最好关闭这个“默认共享”,以保证系统安全。方法是:单击“开始/运行”,在运行窗口中输入“Regedit”,打开注册表编辑器,展开“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters”项,添加键值AutoShareServer,类型为REG_DWORD,值为0。 这样就可以彻底关闭“默认共享”。

[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run]
"deletenetshare"="c:\\\\deletenetshare.bat"

5防范拒绝服务攻击
禁止响应ICMP重定向报文。此类报文有可能用以攻击,所以系统应该拒绝接受ICMP重定向报文。
"EnableICMPRedirects"=dword:00000000

6 iis部分的配置,mdb防止下载,添加数据库名的如MDB的扩展映射 iislog.dll

7 如何解除FSO上传程序小于200k限制?
 先在服务里关闭IIS admin service服务,找到Windows\System32\Inesrv目录下的Metabase.xml并打开,找到ASPMaxRequestEntityAllowed,将其修改为需要的值。默认为204800,即200K,把它修改为51200000(50M),然后重启IIS admin service服务。

Windows2003下的IIS权限设置
前提:仅针对windows 2003 server SP1 Internet(IIS) 服务器

系统安装在C:\盘

系统用户情况为:
administrators 超级管理员(组)
system 系统用户(内置安全主体)
guests 来宾帐号(组)
iusr_服务器名 匿名访问web用户
iwam_服务器名 启动iis进程用户
www_cnnsc_org 自己添加的用户、添加后删除Users(组)、删除后添加到guests来宾帐号(组)
为加强系统安全、(guest)用户及(iusr_服务器名)用户均被禁用
将访问web目录的全部账户设为guests组、去除其他的组

■盘符 安全访问权限
△C:\盘 administrators(组) 完全控制权限、system(内置安全主体) 完全控制权限
△D:\盘 (如果用户网站内容放置在这个分区中)、administrators(组) 完全控制权限
△E:\盘 administrators(组) 完全控制权限、system(内置安全主体) 完全控制权限
△f:\盘 administrators(组) 完全控制权限、system(内置安全主体) 完全控制权限
△如有其他盘符类推下去.

■禁止系统盘下的EXE文件:
net.exe、cmd.exe、tftp.exe、netstat.exe、regedit.exe、regedt32.exe、at.exe、attrib.exe、cacls.exe
△些文件都设置成 administrators 完全控制权限

■禁止下载Access数据库
△Internet 信息服务(IIS)管理器→网站→属性→主目录→配置→添加
△可执行文件:C:\WINDOWS\twain_32.dll
△扩展名:.mdb
▲如果你还想禁止下载其它的东东
△Internet 信息服务(IIS)管理器→网站→属性→主目录→配置→添加
△可执行文件:C:\WINDOWS\twain_32.dll
△扩展名:.(改成你要禁止的文件名)
▲然后删除扩展名:shtml stm shtm cdx idc cer

■防止列出用户组和系统进程:
△开始→程序→管理工具→服务
△找到 Workstation 停止它、禁用它

■卸载最不安全的组件:
△开始→运行→cmd→回车键
▲cmd里输入:
△regsvr32/u C:\WINDOWS\system32\wshom.ocx
△del C:\WINDOWS\system32\wshom.ocx
△regsvr32/u C:\WINDOWS\system32\shell32.dll
△del C:\WINDOWS\system32\shell32.dll
△也可以设置为禁止guests用户组访问

■解除FSO上传程序小于200k限制:
△在服务里关闭IIS admin service服务
△打开 C:\WINDOWS\system32\inetsrv\MetaBase.xml
△找到ASPMaxRequestEntityAllowed
△将其修改为需要的值、默认为204800、即200K、把它修改为51200000(50M)、然后重启
IIS admin service服务

■禁用IPC连接
△开始→运行→regedit
△找到如下组建(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa)中的
(restrictanonymous)子键
△将其值改为1即

■清空远程可访问的注册表路径:
△开始→运行→gpedit.msc
△依次展开“计算机配置→Windows 设置→安全设置→本地策略→安全选项”
△在右侧窗口中找到“网络访问:可远程访问的注册表路径”
△然后在打开的窗口中、将可远程访问的注册表路径和子路径内容全部设置为空即

■关闭不必要的服务
△开始→程序→管理工具→服务
△Telnet、TCP\IP NetBIOS Helper

■解决终端服务许可证过期的办法
△如果你服务器上已经开着终端服务、那就在添加删除程序里删除终端服务和终端授权
服务
△我的电脑--右键属性--远程---远程桌面、打勾、应用
△重启服务器、OK了、再也不会提示过期了

■取消关机原因提示
△开始→运行→gpedit.msc
△打开组策略编辑器、依次展开
△计算机配置→管理模板→系统
△双击右侧窗口出现的(显示“关闭事件跟踪程序”)
△将(未配置)改为(已禁用)即可

***************************第三******************************
1、按照Windows2003安装光盘的提示安装,默认情况下2003没有把IIS6.0安装在系统里面。
2、IIS6.0的安装
  开始菜单—>控制面板—>添加或删除程序—>添加/删除Windows组件
  应用程序 ———ASP.NET(可选)
  |——启用网络 COM+ 访问(必选)
  |——Internet 信息服务(IIS)———Internet 信息服务管理器(必选) 
    |——公用文件(必选)
    |——万维网服务———Active Server pages(必选)
    |——Internet 数据连接器(可选)
          |——WebDAV 发布(可选)
         |——万维网服务(必选)
         |——在服务器端的包含文件(可选)
  然后点击确定—>下一步安装。(具体见本文附件1)

3、系统补丁的更新
  点击开始菜单—>所有程序—>Windows Update
  按照提示进行补丁的安装。

4、备份系统
  用GHOST备份系统。

5、安装常用的软件
  例如:杀毒软件、解压缩软件等;安装完毕后,配置杀毒软件,扫描系统漏洞,安装之后用GHOST再次备份系统。

6、先关闭不需荊4a4 ??的端口 开启防火墙 导入IPSEC策略
在”网络连接”里,把不需要的协议和服务都删掉,这里只安装了基本的Internet协议(TCP/IP),由于要控制带宽流量服务,额外安装了Qos数据包计划程序。在高级tcp/ip设置里–”NetBIOS”设置”禁用tcp/IP上的NetBIOS(S)”。在高级选项里,使用”Internet连接防火墙”,这是windows 2003 自带的防火墙,在2000系统里没有的功能,虽然没什么功能,但可以屏蔽端口,这样已经基本达到了一个IPSec的功能。

修改3389远程连接端口
修改注册表.
开始–运行–regedit
依次展开 HKEY_LOCAL_MACHINE/SYSTEM

/CURRENTCONTROLSET/CONTROL/
TERMINAL SERVER/WDS/RDPWD/TDS/TCP
右边键值中 PortNumber 改为你想用的端口号.注意使用十进制(例 10000 )

HKEY_LOCAL_MACHINE/SYSTEM/CURRENTCONTROLSET

/CONTROL/TERMINAL SERVER/
WINSTATIONS/RDP-TCP/
右边键值中 PortNumber 改为你想用的端口号.注意使用十进制(例 10000 )
注意:别忘了在WINDOWS2 45d 003自带的防火墙给+上10000端口
修改完毕.重新启动服务器.设置生效.

二、用户安全设置
1、禁用Guest账号
在计算机管理的用户里面把Guest账号禁用。为了保险起见,最好给Guest加一个复杂的密码。你可以打开记事本,在里面输入一串包含特殊字符、数字、字母的长字符串,然后把它作为Guest用户的密码拷进去。
2、限制不必要的用户
去掉所有的Duplicate User用户、测试用户、共享用户等等。用户组策略设置相应权限,并且经常检查系统的用户,删除已经不再使用的用户。这些用户很多时候都是黑客们入侵系统的突破口。
3、把系统Administrator账号改名
大家都知道,Windows 2003 的Administrator用户是不能被停用的,这意味着别人可以一遍又一遍地尝试这个用户的密码。尽量把它伪装成普通用户,比如改成Guesycludx。
4、创建一个陷阱用户
什么是陷阱用戍 487 ??即创建一个名为“Administrator”的本地用户,把它的权限设置成最低,什么事也干不了的那种,并且加上一个超过10位的超级复杂密码。这样可以让那些 Hacker们忙上一段时间,借此发现它们的入侵企图。
5、把共享文件的权限从Everyone组改成授权用户
任何时候都不要把共享文件的用户设置成“Everyone”组,包括打印共享,默认的属性就是“Everyone”组的,一定不要忘了改。
6、开启用户策略
使用用户策略,分别设置复位用户锁定计数器时间为20分钟,用户锁定时间为20分钟,用户锁定阈值为3次。 (该项为可选)
7、不让系统显示上次登录的用户名
默认情况下,登录对话框中会显示上次登录的用户名。这使得别人可以很容易地得到系统的一些用户名,进而做密码猜测。修改注册表可以不让对话框里显示上次登录的用户名。方法为:打开注册表编辑器并找到注册表“HKLM\Software\Microsoft\Windows T

\CurrentVersion\Winlogon\Dont-DisplayLastUserName” 4ad ,把REG_SZ的键值改成1。
密码安全设置
1、使用安全密码
一些公司的管理员创建账号的时候往往用公司名、计算机名做用户名,然后又把这些用户的密码设置得太简单,比如“welcome”等等。因此,要注意密码的复杂性,还要记住经常改密码。
2、设置屏幕保护密码
这是一个很简单也很有必要的操作。设置屏幕保护密码也是防止内部人员破坏服务器的一个屏障。
3、开启密码策略
注意应用密码策略,如启用密码复杂性要求,设置密码长度最小值为6位 ,设置强制密码历史为5次,时间为42天。
4、考虑使用智能卡来代替密码
对于密码,总是使安全管理员进退两难,密码设置简单容易受到黑客的攻击,密码设置复杂又容易忘记。如果条件允许,用智能卡来代替复杂的密码是一个很好的解决方法。
三、系统权限的设置
1、磁盘权限
  系统盘及所有磁盘只给 Administrators 组和 SYSTEM 的完全控制 4ce 权限
  系统盘\Documents and Settings 目录只给 Administrators 组和 SYSTEM 的完全控制权限
  系统盘\Documents and Settings\All Users 目录只给 Administrators 组和 SYSTEM 的完全控制权限
  系统盘\Windows\System32\cacls.exe、cmd.exe、net.exe、

net1.exe、ftp.exe、tftp.exe、telnet.exe 、

netstat.exe、regedit.exe、at.exe、

attrib.exe、format.com、del文件只给 Administrators 组和SYSTEM 的完全 控制权限
另将\System32\cmd.exe、format.com、ftp.exe转移到其他目录或更名
  Documents and Settings下所有些目录都设置只给adinistrators权限。并且要一个一个目录查看,包括下面的所有子目录。
删除c:\inetpub目录

2、本地安全策略设置
  开始菜单—>管理工具—>本地安全策略
  A、本地策略——>审核策略
  审核策略更改   成功 失败  
  审核登录事件   成功 失败
  审核对象访问      失败
  审核过程跟踪  4ed   无审核
  审核目录服务访问    失败
  审核特权使用      失败
  审核系统事件   成功 失败
  审核账户登录事件 成功 失败
  审核账户管理   成功 失败

  B、本地策略——>用户权限分配
  关闭系统:只有Administrators组、其它全部删除。
  通过终端服务允许登陆:只加入Administrators,

Remote Desktop Users组,其他全部删除

  C、本地策略——>安全选项
  交互式登陆:不显示上次的用户名       启用
  网络访问:不允许SAM帐户和共享的匿名枚举  启用
  网络访问:不允许为网络身份验证储存凭证   启用
  网络访问:可匿名访问的共享         全部删除
  网络访问:可匿名访问的命          全部删除
  网络访问:可远程访问的注册表路径      全部删除
  网络访问:可远程访问的注册表路径和子路径  全部删除
  帐户:重命名来宾帐捊509 ??            重命名一个帐户
  帐户:重命名系统管理员帐户         重命名一个帐户

3、禁用不必要的服务 开始-运行-services.msc
TCP/IPNetBIOS Helper提供 TCP/IP 服务上的 NetBIOS 和网络上客户端的 NetBIOS 名称解析的支持而使用户能够共享
文件、打印和登录到网络
Server支持此计算机通过网络的文件、打印、和命名管道共享
  Computer Browser 维护网络上计算机的最新列表以及提供这个列表
Task scheduler 允许程序在指定时间运行
Messenger 传输客户端和服务器之间的 NET SEND 和 警报器服务消息
  Distributed File System: 局域网管理共享文件,不需要可禁用
  Distributed linktracking client:用于局域网更新连接信息,不需要可禁用
  Error reporting service:禁止发送错误报告
  Microsoft Serch:提供快速的单词搜索,不需要可禁用
  NTLMSecuritysupportprovide:telnet服务和Microsoft Serch用的,不需要可禁用
  PrintSpooler:如果没有打印机可 521 禁用
  Remote Registry:禁止远程修改注册表
  Remote Desktop Help Session Manager:禁止远程协助
Workstation 关闭的话远程NET命令列不出用户组
  以上是在Windows Server 2003 系统上面默认启动的服务中禁用的,默认禁用的服务如没特别需要的话不要启动。

4、修改注册表
修改注册表,让系统更强壮
1、隐藏重要文件/目录可以修改注册表实现完全隐藏
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\ Current-Version\Explorer\Advanced\Folder\Hi-dden\SHOWALL”,鼠标右击 “CheckedValue”,选择修改,把数值由1改为0

2、防止SYN洪水攻击
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet

\Services\Tcpip\Parameters
新建DWORD值,名为SynAttackProtect,值为2
新建EnablePMTUDiscovery REG_DWORD 0
新建NoNameReleaseOnDemand REG_DWORD 1
新建EnableDeadGWDetect REG_DWORD 0
新建KeepAliveTime REG_DWORD 300,000
新建PerformRouterDiscovery REG_DWORD 0
新建EnableICMPRedirects REG_DWORD 0

3. 禁止响应ICMP路由通告报文
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

\Tcpip\Parameter 538 s\Interfaces\interface
新建DWORD值,名为PerformRouterDiscovery 值为0

4. 防止ICMP重定向报文的攻击
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\

Services\Tcpip\Parameters
将EnableICMPRedirects 值设为0

5. 不支持IGMP协议
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

\Tcpip\Parameters
新建DWORD值,名为IGMPLevel 值为0
6、禁止IPC空连接:
cracker可以利用net use命令建立空连接,进而入侵,还有net view,

nbtstat这些都是基于空连接的,禁止空连接就好了。
Local_Machine\System\CurrentControlSet\Control\

LSA-RestrictAnonymous 把这个值改成”1”即可。

7、更改TTL值
cracker可以根据ping回的TTL值来大致判断你的操作系统,如:
TTL=107(WINNT);
TTL=108(win2000);
TTL=127或128(win9x);
TTL=240或241(linux);
TTL=252(solaris);
TTL=240(Irix);
实际上你可以自己改的:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet

\Services\Tcpip\Parameters:DefaultTTL REG_DWORD 0-0xff(0-255 十进制,默认值128)改成一个莫名其妙的数字如258,起码让那些小菜鸟晕上半天,就此放弃入侵你也不一定哦

8. 删除默荊54c ??共享
有人问过我一开机就共享所有盘,改回来以后,重启又变成了共享是怎么回事,这是2K为管理而设置的默认共享,HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

\LanmanServer\Parameters:AutoShareServer类型是REG_DWORD把值改为0即可

9. 禁止建立空连接
默认情况下,任何用户通过通过空连接连上服务器,进而枚举出帐号,猜测密码。我们可以通过修改注册表来禁止建立空连接:
Local_Machine\System\CurrentControlSet\Control\

LSA-RestrictAnonymous 的值改成”1”即可。

10、建立一个记事本,填上以下代码。保存为*.bat并加到启动项目中
net share c$ /del
net share d$ /del
net share e$ /del
net share f$ /del
net share ipc$ /del
net share admin$ /del

5、IIS站点设置:
1、将IIS目录&数据与系统磁盘分开,保存在专用磁盘空间内。
2、启用父级路径
3、在IIS管理器中删除必须之外的任何没有用到的映射(保留asp等必要映射即可)
4、在IIS中将HTTP404 Object Not Found出错页面通过URL重定向到一个定制HTM文件
5、Web站点权限设定(建议)
读 允许
写 55e ? 不允许
脚本源访问 不允许
目录浏览 建议关闭
日志访问 建议关闭
索引资源 建议关闭
执行 推荐选择 “仅限于脚本”
6、建议使用W3C扩充日志文件格式,每天记录客户IP地址,用户名,服务器端口,方法,URI字根,HTTP状态,用户代理,而且每天均要审查日志。(最好不要使用缺省的目录,建议更换一个记日志的路径,同时设置日志的访问权限,只允许管理员和system为Full Control)。
7、程序安全:
1) 涉及用户名与口令的程序最好封装在服务器端,尽量少的在ASP文件里出现,涉及到与数据库连接地用户名与口令应给予最小的权限;
2) 需要经过验证的ASP页面,可跟踪上一个页面的文件名,只有从上一页面转进来的会话才能读取这个页面。
3) 防止ASP主页.inc文件泄露问题;
4) 防止UE等编辑器生成some.asp.bak文件泄露问题。

6、IIS权限设置的思路
?要为每个独立的要保护的个体(比如一个网站或者一个虚拟目录)创建一个系统用户,让这个站点在系统中具有惟一的可以设置权限的身份。
?在IIS的【站点属性或者虚拟盍 4e1 ?录属性→目录安全性→匿名访问和验证控制→编辑→匿名访问→编辑】填写刚刚创建的那个用户名。
?设置所有的分区禁止这个用户访问,而刚才这个站点的主目录对应的那个文件夹设置允许这个用户访问(要去掉继承父权限,并且要加上超管组和SYSTEM组)。

7、卸载最不安全的组件
最简单的办法是直接卸载后删除相应的程序文件。将下面的代码保存为一个.BAT文件,( 以下均以 WIN2000 为例,如果使用2003,则系统文件夹应该是 C:\WINDOWS\ )
regsvr32/u C:\WINDOWS\System32\wshom.ocx
del C:\WINDOWS\System32\wshom.ocx
regsvr32/u C:\WINDOWS\system32\shell32.dll
del C:\WINNT\WINDOWS\shell32.dll

然后运行一下,WScript.Shell, Shell.application, WScript.Network就会被卸载了。可能会提示无法删除文件,不用管它,重启一下服务器,你会发现这三个都提示“×安全”了。
 

ASP.NET视图状态验证MAC失败 解决办法

验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.Web.HttpException: 验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。
分析:

分 析后找到了问题的根源。首先,文章中提到,如果用GridView,并且指定了DataKeyNames属性,则出于安全的理由(因为 DataKeyNames指定的字段代表数据的主键,且该主键值需要保存在视图状态中发送到客户端,用户如果篡改主键值,会导致安全问题), GridView会要求加密视图状态。为此会自动在页面表单</forms>之前添加一个<input type="hidden" name="__VIEWSTATEENCRYPTED" id="__VIEWSTATEENCRYPTED" value="" /> 。

然 而,Atlas的UpdatePanel要求放置在<form></form>内部,也就是</form>之前。这 就意味着添加的隐藏input控件没有被放置在UpdatePanel内,而是放置在UpdatePanel和</form>之间。

当UpdatePanel 更新时,UpdatePanel内部的控件被提交到服务器进行处理(Patrial Rendering),而整个页面并没有被提交。也就是说隐藏的input控件没有随着一起提交。因此服务器并不知道提交的ViewState被加密了, 从而导致MAC验证错误。

解决方法有二,仅供参考:

1.可以在当前页面的<page ...>里加两个属性:
enableEventValidation="false" viewStateEncryptionMode ="Never"

2.当然还可以在web.config里加入:(<system.web>之间)
<pages enableEventValidation="false" viewStateEncryptionMode ="Never" />

flash与后台数据交换方法整理

1.LoadVars(XML)
2.Flash Remoting
3.Webservice
4.XMLSocket

一.LoadVars篇
我之所以把XML也放在这里说,是因为XML和LoadVars数据交互的方式大体相同,就是传递时的数据内容有点不一样而已!
我现在列出在开发过程最常用的"用户密码验证"实例,加以说明!

引用
// Flash代码;
//=======================================================;
//定义LoadVars对象;
var data_lv = new LoadVars();
//提交的用户名变量和参数值;
data_lv.username = "kinglong";
//提交的密码变量和参数值;
data_lv.password = "king";
//提交后返回结果;
data_lv.onLoad = function(success){
//success,数据提交是否成功;
//这个只是表示数据传输是否成功,并不是用户验证的结果;
if(success){
trace("数据提交成功!");
//result也是用户验证返回的实际结果!
if(this.result=="true"){
trace("yes");
}else{
trace("no");
}
}else{
trace("数据提交失败!");
}
}
//数据提交方法调用;
//第一参数就是提交的页面地址;
//第二参数就是返回结果对象(只要是LoadVars对象就可以了);
//第三参数就是提交方式(这个和html中form表单类似,分为"post"和"get"两种方式)
data_lv.sendAndLoad("http://www.klstudio.com/save.asp
",data_lv,"post");
//=======================================================;
//后台服务端页面处理及返回内容;
//=======================================================;
//接收flash提交过来的变量和接收一个页面提交过来的变量一致的;
Request("username") 就是flash端username变量传过来的值"kinglong";
Request("password") 就是flash端password变量传过来的值"kinglong";
....数据库验证.....
//如果用户验证通过
&result=true
//如果用户验证失败
&result=false
//整个页面返回内容就是上面那一行内容,&result对应用着flash端的result变量;
//如果是多个返回值的话,就是&result=xxx&result1=xxx这种形式就可以了;
如有不清楚的地方,你可查看flash帮助文档!
至于XML的方式,请对应地查看flash帮助文档就可以了!
LoadVars方式的优点:
1.flash代码实现起来简单,方便.
2.服务端接收页面和接收一个表单过来的数据一样处理,不需要专门的技术,所有服务端程序都可以实现!

LoadVars方式的缺点:
1.传递的变量不宜过多.
2.变量传递的值不能过长.
3.变量传递值只能使用"字符串"这一种数据类型,数据类型单一.
4.数据返回值当中不能有"&"字符,因此比较复杂的返回值都需进行URL编码处理.

  Flash Remoting这种数据接口是四个之中效率最高的!
其优点:
1.支持数据类型比较多(Converting from application server data types to ActionScript);
2.传递数据量比较大;
3.运行效率是现有几个当中最高的;
4.对各种后台的支持也比较好;
5.其还有调试模块(NetConnection Debugger)

其缺点:
1.需要flash端装Flash Remoting MX Components(这个是免费提供的);
2.需要后台服务端装相应版本的Flash Remoting模块才可以使用,MM提供的模块有j2ee和.net两个版本是要收费的,好在网上还有两个开源的(OpenAMF,AMFPHP);
3.好像Remoting对虚拟主机的支持不太好(可以去google搜索一下,有没有解决方法).
Flash端代码说明:(我这里用as1.0版本为例,其他版本到MM站查找)
//加载Remoting Component代码,这个是必须的;
#include "NetServices.as"
//加载Remoting 调试模块代码,这个是可选择的,用NetConnection Debugger查看调试信息;
#include "NetDebug.as"
if (inited == null){
inited = true;
//设置默认网关;
NetServices.setDefaultGatewayUrl("http://localhost:8500/flashservices/gateway
");
//建立网关连接;
gateway_conn = NetServices.createGatewayConnection();
//获取一个服务;
myService = gateway_conn.getService("myservice", this);
}

//定义调用方法的函数;
function getString(name){
//调用Remoting的getString方法;
myService.getString(name);
}
//定义返回结果的函数;
function getString_Result(result){
//result就为返回的结果;
trace(result);
}
//定义返回状态的函数,此为可选的;
function getString_Status(error){
trace("getString_Status");
trace(error.code);
trace(error.description);
trace(error.details);
}

//调用函数;
getString("kinglong"); 服务端方法定义(我这里以Coldfusion Component为例,其他版本请参考相应的资料)

<!---文件名为myservice.cfc--->
<cfcomponent displayname="我的服务">
<!---定义了getString方法,需将access设为remote,否则Flash remoting无法调用此方法--->
<cffunction name="getString" access="remote" returntype="string">
<cfargument name="name" type="string" required="true">
<cfset myResult = arguments.name & ",欢迎你!">
<cfreturn myResult>
</cffunction>
</cfcomponent>
另附上Flash Remoting的在线帮助文件(Flash Remoting LiveDocs),MM网站上的Remoting相关的资料

演练如何缓存依赖于 SQL Server 数据库中数据的 ASP.NET 页

此演练演示如何缓存依赖于 SQL Server 数据库中数据的 ASP.NET 页。

ASP.NET 输出缓存的一项高级功能是 SQL 缓存依赖项。SQL 缓存依赖项使您可以缓存依赖于 SQL Server 表中数据的页。您可以配置 SQL Server 和 ASP.NET 以缓存页请求,降低服务器工作负荷,直到页所依赖的数据已在 SQL Server 中更新为止。对于相对保持静态的产品目录或客户注册信息等数据而言,SQL 缓存依赖项很有用。

本演练中阐释的任务包括:

创建并配置页,以显示 Northwind 数据库中的数据。

为 SQL 缓存通知启用数据库。

在页以及 Web.config 文件中指定 SQL 缓存依赖项。

对 Northwind 数据库进行更改并查看缓存行为。

先决条件
若要完成本演练,您需要:

对具有 Northwind 数据库的 SQL Server 2000 或 SQL Server 2005 的访问。

SQL Server Northwind 数据库的访问权限。有关下载和安装 SQL Server 示例数据库 Northwind 的信息,请参见位于 Microsoft SQL Server 网站上的“Installing Sample Databases”(安装示例数据库)。

注意
如果需要有关如何登录到运行 SQL Server 的计算机的信息,请与服务器管理员联系。

Microsoft 数据访问组件 (MDAC) 2.7 版或更高版本。

如果您使用的是 Windows XP 或 Windows Server 2003,那么您已经有了 MDAC 2.7。但是,如果使用 Windows 2000,您可能需要升级您计算机上已经安装的 MDAC。有关更多信息,请参见 MSDN 文章“MDAC Installation”(MDAC 安装)。

.NET Framework 2.0 版。

创建网站
如果您已在 Visual Web Developer 中创建了网站(请参见 演练:在 Visual Web Developer 中创建基本网页),则可以使用该网站并转至本演练的后面部分“为 SQL Server 启用缓存通知”。否则,按照下面的步骤创建一个新的网站和网页。

创建文件系统网站
打开 Visual Web Developer。

在“文件”菜单上单击“新建网站”。(在 Visual Web Developer 速成版中,在“文件”菜单上单击“新建”,然后单击“网站”。)

出现“新建网站”对话框。

在“Visual Studio 已安装的模板”之下单击“ASP.NET 网站”。

在“位置”框中输入要保存网站页面的文件夹的名称。

例如,键入文件夹名 C:\WebSites。

在“语言”列表中,单击您想使用的编程语言。

单击“确定”。

Visual Web Developer 创建该文件夹和一个名为 Default.aspx 的新页。

为 SQL Server 启用缓存通知
必须配置 SQL Server 以就依赖数据中的更改向 ASP.NET 提供合适的通知。您需要具有管理特权才能配置服务器。

为 SQL Server 启用缓存通知
在 Windows“启动”菜单中,指向“所有程序”,指向“附件”,然后单击“命令提示符”以打开命令提示窗口。

在磁盘驱动器中找到 Aspnet_regsql.exe 可执行文件。此文件随 .NET Framework 2.0 版安装在下面的位置:

复制代码
%windir%\Microsoft.NET\Framework\FrameworkVersion

确保 %windir% 表示 Windows 目录并且 .NET Framework 版本为 2.0 或更高版本。该路径可能看起来类似于下面这样:

复制代码
C:\WINDOWS\Microsoft.NET\Framework\v2.0.40217

使用下面的命令为 Northwind 数据库中的 Employees 表启用缓存通知:

复制代码
aspnet_regsql.exe -S <Server> -U <Username> -P <Password> -ed -d Northwind -et -t Employees
注意
您需要具有管理特权,或管理帐户和密码。如果没有此信息,请与数据库管理员联系。

将出现一条消息,指示启用数据库的成功与失败。下面的消息指示成功:

复制代码
Enabling the table for SQL cache dependency.
..
Finished.

向项目中添加数据连接
要在 Visual Web Developer 中使用 SQL Server 数据库,您需要向 Northwind 数据库添加连接。

向项目添加数据源
在“服务器资源管理器”(Visual Web Developer 速成版中为“数据库资源管理器”)中,右击“数据连接”,然后单击“添加连接”。

注意
“服务器资源管理器”(Visual Web Developer 速成版中为“数据库资源管理器”)通常停靠在解决方案资源管理器后面。

如果“服务器资源管理器”(Visual Web Developer 速成版中为“数据库资源管理器”)不可见,则在“视图”菜单中单击“服务器资源管理器”(Visual Web Developer 速成版中为“数据库资源管理器”)。

如果显示“选择数据源”对话框,则执行以下操作:

在“数据源”列表中,单击“Microsoft SQL Server”。

在“数据提供程序”列表中,单击“用于 SQL Server 的 .NET Framework 数据提供程序”。

单击“继续”。

在“添加连接”对话框中,为数据库提供详细信息(服务器名称、登录凭据等),然后选择 Northwind 数据库。

单击“确定”。

向网页添加时间戳和数据
现在可以创建网页来演示缓存处理。在本节中,您将添加一个时间戳来跟踪页创建时间,并添加一个 GridView 控件来查看 Northwind 数据库的 Employees 表。

向网页添加时间戳和数据
切换到或打开 Default.aspx 页。

切换到“设计”视图。

从工具箱的“标准”组中,将一个 Label 控件拖到页上,保留默认名称 Label1。

在“服务器资源管理器”(Visual Web Developer 速成版中为“数据库资源管理器”)中,展开“数据连接”。

为以前创建的数据连接展开节点。

展开“表”节点。

将 Employees 表拖到页上。

Visual Web Designer 创建一个 GridView 控件,它配置为使用您所选择的连接和表。

在“GridView 任务”菜单上,单击“配置数据源。

默认数据连接字符串名称 NorthwindConnectionString1 出现在“配置数据源”向导的第一个步骤中。

单击“下一步”。

在“配置 Select 语句”窗格中,选择“指定来自表或视图的列”。

在“名称”列表中,单击 Employees。

在“列”列表中,选择 EmployeeID、LastName 和 FirstName 列。

单击“下一步”。

单击“完成”。

Visual Web Designer 配置 GridView 控件以显示您所选择的数据。

注意
如果看到一条消息询问您是否要刷新 GridView 控件的字段和键,单击“是”。

双击页的空白部分。

设计器生成 Page_Load 方法并切换视图。

添加以下突出显示的代码,以显示指示页创建的时间戳:

Visual Basic 复制代码
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles Me.Load
Label1.Text = System.DateTime.Now
End Sub

C# 复制代码
protected void Page_Load(Object sender, System.EventArgs e)
{
Label1.Text = System.DateTime.Now.ToString();
}

保存该文件。

测试不使用缓存功能的页
现在可以运行页,并观察不使用缓存功能的行为。此时将加载页并显示当前服务器时间,然后将检索数据并将其放置在页中。

测试不使用缓存功能的页
按 Ctrl+F5 运行该页。

在浏览器中刷新页

注意,时间戳随着每次页刷新而更改。数据将保持相同。

为缓存功能配置网页
在本部分演练中,您将基于 Northwind 数据库的 Employees 表为 SQL 缓存依赖项配置页。

为缓存功能配置网页
切换到“源”视图。

在页顶部,添加下面的指令以指示依赖项:

复制代码
<%@ OutputCache Duration="3600" SqlDependency="Northwind:Employees" VaryByParam="none" %>

VaryByParam 属性指示缓存时 ASP.NET 是否应考虑页参数(如查询字符串或发布值)。当 VaryByParam 设置为 none 时,将不考虑任何参数;无论提供什么附加参数,都将向所有用户发送相同的页。将 VaryByParam 设置为 *(星号)表明,对于每个唯一的请求参数组合,将缓存一个唯一页。但是,将 VaryByParam 设置为 * 会缓存页的许多不同版本,所以如果您知道缓存变化所依据的参数,建议您在 VaryByParam 属性中显式指定这些参数。有关详细信息,请参见 缓存页的多个版本。

在 Web.config 文件中设置缓存配置
除了前面部分中网页的 OutputCache 声明外,您需要在 Web.config 文件中指定缓存详细信息。

创建和更新 Web.config 文件
如果您的网站已具有 Web.config 文件,请转至步骤 4。

在解决方案资源管理器中,右击网站的名称,然后单击“添加新项”。

在“添加项”对话框中,单击“Web 配置文件”,然后单击“添加”。

请确保使用名称 Web.config。

将下面的 XML 作为 system.web 元素的子级添加到 Web.config 文件中:

复制代码
<!-- caching section group -->
<caching>
<sqlCacheDependency enabled = "true" pollTime = "1000" >
<databases>
<add name="Northwind"
connectionStringName="NorthwindConnectionString1"
pollTime = "1000"
/>
</databases>
</sqlCacheDependency>
</caching>
注意
前面您在创建数据连接时,已建立了连接字符串名称 NorthwindConnectionString1。如果您的连接字符串具有不同的名称,请替换为该名称。

注意
在连接字符串中指定的帐户凭据必须具有足够的特权来轮询数据库。

保存文件,然后将其关闭。

测试使用缓存功能的页
启用缓存后,刷新页时将不再导致时间戳或数据库查询更新,因为 ASP.NET 将从缓存中满足页请求。

测试使用缓存功能的页
按 Ctrl+F5 运行该页。

注意,时间戳在每次页刷新时保持不变。将从缓存中检索页。

更改数据
现在可以更改数据库中的数据,并可看到缓存被验证,并创建了一个新页。

更改数据
在“服务器资源管理器”(Visual Web Developer 速成版中为“数据库资源管理器”中),展开“数据连接”节点。

展开您先前创建的连接。

展开“表”节点。

右击“Employees”,然后单击“显示表数据”。

通过编辑数据表中的任何字段并确保它是网页所显示的字段来更新数据库。

或者也可以使用 SQL 窗格(如果 SQL 窗格不可见,则在“查询设计器”菜单中单击“窗格”,然后单击“SQL”)。直接输入 SQL 命令,然后单击“查询设计器”工具栏中的“执行 SQL”按钮。例如,运行下面的命令:

复制代码
UPDATE dbo.Employees SET LastName = 'Doe' WHERE (EmployeeID = 5)

这将把雇员 5 的名称更改为 Doe。

关闭数据的视图。

测试 SQL 缓存依赖项
现在可以测试页,以查看数据和时间戳是否已更改。

测试 SQL 缓存依赖项
按 Ctrl+F5 运行该页。

注意,时间戳已更改,并显示新数据。

按 Ctrl+F5 再次运行该页。

这次时间戳保持不变,因为数据未更改,并且现在正从缓存中再次检索该页