验证码多URL演示破解-安装版.rar
这个是制作的安装版。用于演示用。
验证码多URL演示破解-源码(DotNet2).rar
这个便是上面安装版的源码。
这两个附件首发于博客园。sban保证博客园的版本没有病毒,请勿在其它地址下载。
这个是制作的安装版。用于演示用。
验证码多URL演示破解-源码(DotNet2).rar
这个便是上面安装版的源码。
这两个附件首发于博客园。sban保证博客园的版本没有病毒,请勿在其它地址下载。
这个小软件,是我06年初的时候写的,时隔两年了。那时急用,也没考虑什么面向对象,设计模式,垃圾处理等,暇疵甚多。今天把它拿出来,旨在抛砖引玉,与大家共同探讨一下C#的图文识别。
演示中的验证码的URL有的已不能用。大部分验证码图像都简单,破解尚且容易。倘若能够破解google或yahoo的验证码,那才是高手。
这是当时写的演示软件说明,其中有些话有些过了。
◇ 本软件为验证码破解示例软件. 纯绿色,可完全卸载,不含任何插件、恶意代码。
◇ 支持不同色彩,不同大小,不同个数,不同亮度.
◇ 支持不同格式,不同形式,不同方法.
◇ 由于是针对大众验证码的演示软件,准确率以及破解速度远不及针对单一验证码的破解.
◇ 关于设置URI等参数的功能,由于对于不同的验证码参数是不定的,需要调试得出,所以没有列出. ◇ 凡是小软件,应力求功能简单,效率与实用性才能提高.一个无所不能的软件也就是一个什么也不能的软件.
◇ 支持不同色彩,不同大小,不同个数,不同亮度.
◇ 支持不同格式,不同形式,不同方法.
◇ 由于是针对大众验证码的演示软件,准确率以及破解速度远不及针对单一验证码的破解.
◇ 关于设置URI等参数的功能,由于对于不同的验证码参数是不定的,需要调试得出,所以没有列出. ◇ 凡是小软件,应力求功能简单,效率与实用性才能提高.一个无所不能的软件也就是一个什么也不能的软件.
好了,且看源码。
源码中有一个Access数据库[suncode06.mdb]。
这个表用于存储验证码的地址及破解配置信息。其中,maxLt与minLt是躁点取舍范围。nCode是验证码的个数。
如图所示,这个表便存储了验证码的图片信息。
这个小软件破解验证码的原理,是记忆性破解。读取验证码图片,分成一个个小图片,如果库中有记录,则返回它的验证码字符;如果不存在,则插入新记录。对于没有记忆过的验证码图片,它是识别不出来的。这个破解方法只可用于验证码字符范围固定的验证码。对于不固定范围的,如QQ的注册验证则不能破解。
其中,所有破解代码都在Form1中,form2可以不看。
在Form1中,首先init读取当前要破解的验证码的url及破解参数:
init(int id)
private void init(int id)
{
textBox1.Enabled = false;
button2.Enabled = false;
//
cmdUncode.CommandText = "select * from [uri] where [id] = @id";
cmdUncode.Connection = conUncode;
cmdUncode.Parameters.Clear();
cmdUncode.Parameters.Add("@id", OleDbType.Integer);
cmdUncode.Parameters["@id"].Value = id;
closeDtr();
dtrUncode = cmdUncode.ExecuteReader();
if (dtrUncode.Read())
{
uri = dtrUncode["uri"].ToString();
nCode = Convert.ToInt16(dtrUncode["nCode"]);
maxLight = Convert.ToDouble(dtrUncode["maxLt"]);
minLight = Convert.ToDouble(dtrUncode["minLt"]);
iEdge = Convert.ToInt16(dtrUncode["iEdge"]);
compairLimit = Convert.ToInt16(dtrUncode["iLmt"]);
remark = dtrUncode["remark"].ToString();
}
//uriID = 5;
//uri = "http://customer.realname.alibaba.com.cn/cap_image.php";
//nCode = 5;
//maxLight = 0.85;
//minLight = 0.55;
//iEdge = 1;
//compairLimit = 12;
//remark = "http://customer.realname.alibaba.com.cn/newapply/newwhois.htm";
linkLabel1.Text = remark;
dtrUncode.Close();
//
X0 = new int[1 + nCode*2];
Y0 = new int[1 + nCode * 2];
//
Bitmap0 = new Bitmap[3 + nCode];
CharRlt = new Char[nCode];
for (int i = 0; i < nCode; i++)
{
CharRlt[i] = ' ';
}
textBox1.Enabled = false;
button2.Enabled = false;
}
private void init(int id)
{
textBox1.Enabled = false;
button2.Enabled = false;
//
cmdUncode.CommandText = "select * from [uri] where [id] = @id";
cmdUncode.Connection = conUncode;
cmdUncode.Parameters.Clear();
cmdUncode.Parameters.Add("@id", OleDbType.Integer);
cmdUncode.Parameters["@id"].Value = id;
closeDtr();
dtrUncode = cmdUncode.ExecuteReader();
if (dtrUncode.Read())
{
uri = dtrUncode["uri"].ToString();
nCode = Convert.ToInt16(dtrUncode["nCode"]);
maxLight = Convert.ToDouble(dtrUncode["maxLt"]);
minLight = Convert.ToDouble(dtrUncode["minLt"]);
iEdge = Convert.ToInt16(dtrUncode["iEdge"]);
compairLimit = Convert.ToInt16(dtrUncode["iLmt"]);
remark = dtrUncode["remark"].ToString();
}
//uriID = 5;
//uri = "http://customer.realname.alibaba.com.cn/cap_image.php";
//nCode = 5;
//maxLight = 0.85;
//minLight = 0.55;
//iEdge = 1;
//compairLimit = 12;
//remark = "http://customer.realname.alibaba.com.cn/newapply/newwhois.htm";
linkLabel1.Text = remark;
dtrUncode.Close();
//
X0 = new int[1 + nCode*2];
Y0 = new int[1 + nCode * 2];
//
Bitmap0 = new Bitmap[3 + nCode];
CharRlt = new Char[nCode];
for (int i = 0; i < nCode; i++)
{
CharRlt[i] = ' ';
}
textBox1.Enabled = false;
button2.Enabled = false;
}
当用户点击破解的时候,首先在GetBitmapOriginal(ref Bitmap0[0])中取出原始图像:
GetBitmapOriginal
public Bitmap GetBitmapOriginal(ref Bitmap oriBmp)
{
WebRequest webRqst = WebRequest.Create(uri);
WebResponse webRpns = webRqst.GetResponse();
Stream0 = webRpns.GetResponseStream();
oriBmp = new Bitmap(Stream0);
return oriBmp;
}
public Bitmap GetBitmapOriginal(ref Bitmap oriBmp)
{
WebRequest webRqst = WebRequest.Create(uri);
WebResponse webRpns = webRqst.GetResponse();
Stream0 = webRpns.GetResponseStream();
oriBmp = new Bitmap(Stream0);
return oriBmp;
}
取出原始图像后,在GetXYOfEightPoint()中取出验证码图像中每一个小图像的临界点,这将在下一步的裁图中用到:
GetXYOfEightPoint
private bool GetXYOfEightPoint()
{
int m_countX = 1;
int m_countY = 1;
bool IsBound = false;
for (X0[0] = 0; X0[0] < Bitmap0[1].Size.Width; X0[0]++)
{
IsBound = false;
for (Y0[0] = 0; Y0[0] < Bitmap0[1].Size.Height; Y0[0]++)
{
if (Bitmap0[1].GetPixel(X0[0], Y0[0]).GetBrightness() == 0)
{
IsBound = true;
continue;
}
}
if (m_countX <= nCode*2)
{
if ((m_countX % 2) == 0)
{
if (!IsBound)
{
X0[m_countX] = X0[0] - 1;
m_countX++;
}
}
else
{
if (IsBound)
{
X0[m_countX] = X0[0];
m_countX++;
}
}
}
//
}
if (m_countX < nCode*2)
{
//label1.Text = m_countX.ToString();
return false;
}
//
for (Y0[0]=0; Y0[0]<(nCode*2); Y0[0]++)
{
if ((Y0[0]%2) == 0)
{
Y0[Y0[0] + 1] = Bitmap0[1].Size.Height;
}
else
{
Y0[Y0[0] + 1] = 0;
}
}
//
for (Y0[0] = 0; Y0[0] < Bitmap0[1].Size.Height; Y0[0]++)
{
//
for (int i = 0; i < nCode * 2; i = i + 2)
{
//
for (X0[0] = X0[i + 1]; X0[0] < X0[i + 2]; X0[0]++)
{
if (Bitmap0[1].GetPixel(X0[0], Y0[0]).GetBrightness() == 0)
private bool GetXYOfEightPoint()
{
int m_countX = 1;
int m_countY = 1;
bool IsBound = false;
for (X0[0] = 0; X0[0] < Bitmap0[1].Size.Width; X0[0]++)
{
IsBound = false;
for (Y0[0] = 0; Y0[0] < Bitmap0[1].Size.Height; Y0[0]++)
{
if (Bitmap0[1].GetPixel(X0[0], Y0[0]).GetBrightness() == 0)
{
IsBound = true;
continue;
}
}
if (m_countX <= nCode*2)
{
if ((m_countX % 2) == 0)
{
if (!IsBound)
{
X0[m_countX] = X0[0] - 1;
m_countX++;
}
}
else
{
if (IsBound)
{
X0[m_countX] = X0[0];
m_countX++;
}
}
}
//
}
if (m_countX < nCode*2)
{
//label1.Text = m_countX.ToString();
return false;
}
//
for (Y0[0]=0; Y0[0]<(nCode*2); Y0[0]++)
{
if ((Y0[0]%2) == 0)
{
Y0[Y0[0] + 1] = Bitmap0[1].Size.Height;
}
else
{
Y0[Y0[0] + 1] = 0;
}
}
//
for (Y0[0] = 0; Y0[0] < Bitmap0[1].Size.Height; Y0[0]++)
{
//
for (int i = 0; i < nCode * 2; i = i + 2)
{
//
for (X0[0] = X0[i + 1]; X0[0] < X0[i + 2]; X0[0]++)
{
if (Bitmap0[1].GetPixel(X0[0], Y0[0]).GetBrightness() == 0)