在域名越来越Hot的情况下,忍不住想知道域名的动态。虽然昨天的花生壳已经有了这样的功能
,但我还是写了个程序来实现简单的域名批量检测功能。
要实现域名检测,首先要有一个查询平台。我选择的是花生壳。原因是花生壳的Web实现是通过
XML的。通过WinSockExpert截包分析数据交换相当简单,并且域名都是分开查询的。这样就有了一个先天
比较好的平台。
分析发现,提交的数据只要在POST的内容里把域名进行相关的替换,然后把Content-Length的值
进行修改就完成了提交数据的构造。
接下来就是收到的数据。这里要分两种情况(目前我的分析是这样的)。
1、cn域名:返回数据的主体只有一条
可以通过后面的数字判断域名状态。数字的含义是(目前只收集到这么多,可能不全):
2、非cn域名:在cn域名的后面还附加了Whois信息。这个里面包含了域名的注册和过期信息。
这正是我想要的数据。
知道了数据的获取,就是程序的具体实现部分了。
程序主要用到了Socket,Access,Threads。
首先是建立数据库。
这里建立一个空数据库的方式是通过FileStream直接写一个文件。这样就是简单快捷。
然后是生成待检测列表的代码了。这里面自定义了一种描述语言:[(c1)(c2)(c3)|(c4){*}]。含
义是这样的:在一个字符位上可以出现字符c1,c2,c3~c4。“*”代表这一位可以是域名的结束位。对于输
入信息的检测是通过正则表达式加上简单的字符串操作共同实现的。这里就不分析了。在生成待测列表时
,先要把描述语言里的跨字符给扩充起来。就是把c3~c4这样的元素变成c3,ci,cj....cm,c4。生成是用的
递归。
这样就完成了待测列表的建立。
下面是单个获取域名信息的代码。太简单,不需要分析了。
现在就只要多线程的控制了。这里用的是生产与消费的方式。生成与消费的控制代码
好了,基本的内容都出来了。然后就是整合代码。点击 这里下载完整的程序。
,但我还是写了个程序来实现简单的域名批量检测功能。
要实现域名检测,首先要有一个查询平台。我选择的是花生壳。原因是花生壳的Web实现是通过
XML的。通过WinSockExpert截包分析数据交换相当简单,并且域名都是分开查询的。这样就有了一个先天
比较好的平台。
POST /ASP_PAGES/Domain/Domain_Check.asp HTTP/1.1
Accept: */*
Accept-Language: zh-cn
x-prototype-version: 1.4.1
Referer: http://www.oray.cn/Domain/
x-requested-with: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded
UA-CPU: x86
Accept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NETCLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Host: www.oray.cn
Content-Length: 50
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: ASPSESSIONIDSCQRBBAQ=MCJLLHJDCBDMLMIBIDGGELPO;
__utma=153953382.112318203.1207907509.1207907509.1207907509.1; __utmb=153953382;
__utmc=153953382; __utmz=153953382.1207907509.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=
(none)
s=0.016809734685802102 &act =check &root =ccvvcc.cn &_ =
Accept: */*
Accept-Language: zh-cn
x-prototype-version: 1.4.1
Referer: http://www.oray.cn/Domain/
x-requested-with: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded
UA-CPU: x86
Accept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NETCLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Host: www.oray.cn
Content-Length: 50
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: ASPSESSIONIDSCQRBBAQ=MCJLLHJDCBDMLMIBIDGGELPO;
__utma=153953382.112318203.1207907509.1207907509.1207907509.1; __utmb=153953382;
__utmc=153953382; __utmz=153953382.1207907509.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=
(none)
s=0.016809734685802102 &act =check &root =ccvvcc.cn &_ =
分析发现,提交的数据只要在POST的内容里把域名进行相关的替换,然后把Content-Length的值
进行修改就完成了提交数据的构造。
接下来就是收到的数据。这里要分两种情况(目前我的分析是这样的)。
1、cn域名:返回数据的主体只有一条
可以通过后面的数字判断域名状态。数字的含义是(目前只收集到这么多,可能不全):
|-
1
|
'
超时
| 0 | ' 已被注册
| 0 | 3 ' 已被注册
| 100 | ' 未注册
| 0 | ' 已被注册
| 0 | 3 ' 已被注册
| 100 | ' 未注册
2、非cn域名:在cn域名的后面还附加了Whois信息。这个里面包含了域名的注册和过期信息。
Domain Name: CC.COM
Registrar: MARKMONITOR INC.
Whois Server: whois.markmonitor.com
Referral URL: http: // www.markmonitor.com
Name Server: DNS1.CLEARCHANNEL.COM
Name Server: DNS2.CLEARCHANNEL.COM
Name Server: NS1.CLEARCHANNEL.COM
Name Server: NS2.CLEARCHANNEL.COM
Status: clientDeleteProhibited
Status: clientTransferProhibited
Status: clientUpdateProhibited
Updated Date: 24 - may - 2007
Creation Date: 27 - jun - 1997
Expiration Date: 26 - jun - 2008
Registrar: MARKMONITOR INC.
Whois Server: whois.markmonitor.com
Referral URL: http: // www.markmonitor.com
Name Server: DNS1.CLEARCHANNEL.COM
Name Server: DNS2.CLEARCHANNEL.COM
Name Server: NS1.CLEARCHANNEL.COM
Name Server: NS2.CLEARCHANNEL.COM
Status: clientDeleteProhibited
Status: clientTransferProhibited
Status: clientUpdateProhibited
Updated Date: 24 - may - 2007
Creation Date: 27 - jun - 1997
Expiration Date: 26 - jun - 2008
这正是我想要的数据。
知道了数据的获取,就是程序的具体实现部分了。
程序主要用到了Socket,Access,Threads。
首先是建立数据库。
这里建立一个空数据库的方式是通过FileStream直接写一个文件。这样就是简单快捷。
然后是生成待检测列表的代码了。这里面自定义了一种描述语言:[(c1)(c2)(c3)|(c4){*}]。含
义是这样的:在一个字符位上可以出现字符c1,c2,c3~c4。“*”代表这一位可以是域名的结束位。对于输
入信息的检测是通过正则表达式加上简单的字符串操作共同实现的。这里就不分析了。在生成待测列表时
,先要把描述语言里的跨字符给扩充起来。就是把c3~c4这样的元素变成c3,ci,cj....cm,c4。生成是用的
递归。
private
void
Mk(
string
Pre,
int
n)
{
string q = QsFull[n];
if (q[q.Length - 1] == '*')
{
q = q.Remove(q.Length - 1);
foreach (char i in q)
foreach (string s in Suxs)
{
sql = "insert into ym (name,sux,sta) values('" + Pre + i + "','" + s +
"',0)";
Cmd = new OleDbCommand(sql, Conn);
Cmd.ExecuteNonQuery();
Application.DoEvents();
}
}
if (n < QsFull.Length - 1)
foreach (char i in QsFull[n])
Mk(Pre + i, n + 1);
}
{
string q = QsFull[n];
if (q[q.Length - 1] == '*')
{
q = q.Remove(q.Length - 1);
foreach (char i in q)
foreach (string s in Suxs)
{
sql = "insert into ym (name,sux,sta) values('" + Pre + i + "','" + s +
"',0)";
Cmd = new OleDbCommand(sql, Conn);
Cmd.ExecuteNonQuery();
Application.DoEvents();
}
}
if (n < QsFull.Length - 1)
foreach (char i in QsFull[n])
Mk(Pre + i, n + 1);
}
这样就完成了待测列表的建立。
下面是单个获取域名信息的代码。太简单,不需要分析了。
string
domain
=
"
cc.com
"
;
Socket Soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
byte [] buf = new byte [ 4096 ];
Soc.Connect( " www.oray.cn " , 80 );
Soc.Send(Encoding.UTF8.GetBytes(Properties.Resources.Post.Replace( " {0} " , ( 41 +
domain.Length).ToString()).Replace( " {1} " , domain)));
Soc.Receive(buf);
string s;
int sta = - 2 ;
string crt = string .Empty, exp = string .Empty;
StreamReader sr = new StreamReader( new MemoryStream(buf));
while (sr.ReadLine() != string .Empty) ;
s = sr.ReadLine();
if (sr.ReadLine() == " HTTP/1.1 200 OK " )
{
while (sr.ReadLine() != string.Empty) ;
s = sr.ReadLine();
if (s.IndexOf('') != -1) s = s.Substring(0, s.IndexOf(''));
switch (s.Split('|')[1])
{
case "0": sta = 10; break;
case "100": sta = 100; break;
default: sta = 0; break;
};
}
else sta = 0 ;
if (sta == 10 )
while ( ! sr.EndOfStream)
{
s = sr.ReadLine();
string[] sp;
if (s.IndexOf(':') != -1)
{
sp = s.Split(':');
switch (sp[0])
{
case " Creation Date": crt = sp[1].Substring(1); break;
case " Expiration Date": exp = sp[1].Substring(1); break;
}
}
}
Console.WriteLine(sta);
Console.WriteLine(crt);
Console.WriteLine(exp);
Socket Soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
byte [] buf = new byte [ 4096 ];
Soc.Connect( " www.oray.cn " , 80 );
Soc.Send(Encoding.UTF8.GetBytes(Properties.Resources.Post.Replace( " {0} " , ( 41 +
domain.Length).ToString()).Replace( " {1} " , domain)));
Soc.Receive(buf);
string s;
int sta = - 2 ;
string crt = string .Empty, exp = string .Empty;
StreamReader sr = new StreamReader( new MemoryStream(buf));
while (sr.ReadLine() != string .Empty) ;
s = sr.ReadLine();
if (sr.ReadLine() == " HTTP/1.1 200 OK " )
{
while (sr.ReadLine() != string.Empty) ;
s = sr.ReadLine();
if (s.IndexOf('') != -1) s = s.Substring(0, s.IndexOf(''));
switch (s.Split('|')[1])
{
case "0": sta = 10; break;
case "100": sta = 100; break;
default: sta = 0; break;
};
}
else sta = 0 ;
if (sta == 10 )
while ( ! sr.EndOfStream)
{
s = sr.ReadLine();
string[] sp;
if (s.IndexOf(':') != -1)
{
sp = s.Split(':');
switch (sp[0])
{
case " Creation Date": crt = sp[1].Substring(1); break;
case " Expiration Date": exp = sp[1].Substring(1); break;
}
}
}
Console.WriteLine(sta);
Console.WriteLine(crt);
Console.WriteLine(exp);
现在就只要多线程的控制了。这里用的是生产与消费的方式。生成与消费的控制代码
class
Cell
{
string Content;
bool readerFlag = false;
public string Read()//消费
{
lock (this)
{
if (!readerFlag)
{
try
{
Monitor.Wait(this);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
readerFlag = false;
Monitor.Pulse(this);
}
return Content;
}
public void Write(string Domain)//生产
{
lock (this)
{
if (readerFlag)
{
try
{
Monitor.Wait(this);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
Content = Domain;
readerFlag = true;
Monitor.Pulse(this);
}
}
}
{
string Content;
bool readerFlag = false;
public string Read()//消费
{
lock (this)
{
if (!readerFlag)
{
try
{
Monitor.Wait(this);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
readerFlag = false;
Monitor.Pulse(this);
}
return Content;
}
public void Write(string Domain)//生产
{
lock (this)
{
if (readerFlag)
{
try
{
Monitor.Wait(this);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
Content = Domain;
readerFlag = true;
Monitor.Pulse(this);
}
}
}
好了,基本的内容都出来了。然后就是整合代码。点击 这里下载完整的程序。