目录
1.Intro
爬虫在耳边萦绕,倾听着浏览器的呢喃,从urllib2到selenium,飞向scrapy,直至穿越服务器的心间,一切都只不过是Mongo下的微粒... 正当做着白日梦的时候,一声听起来无力又有点肾虚的呼唤搅屎了我的诗作:“猿儿!你快过来下!”
他撅起屁股,哦不,是张开嘴,我就知道绝逼没有比如请我吃饭的好事:“ ***那个软件太贵了!买不起啊兄弟!我看你一表人才,给破解下呗~”
一表人才还行,但我是一个罕见的十分正直的人:“淦!我们搞GIS的,又不是黑帽,不要再蹦逼了,整不来整不来”
X:“那个新来女同事的微信...”
我:“你我都是兄弟,凡事好商量”
就这样,继做爬虫之后,又从一个搞地信开发的变成了搞破解的,天天不务正业说的就是本猿。
2.Details
说起来这个软件,在GIS业内倒也不是很出名,只是有很多满足一些国土和地理信息生产业务的功能,而且做的也比较成熟,所以说不得不用,但是授权方式是每人一套,一套的价格大概是1w+,本着能用破解版就绝壁不买的原则(深受ArcGIS的影响,一套正版的高级版ArcGIS桌面产品大概是149000.....),就反编译了一下解密模块,值得庆幸的是这个软件厂商并没有加壳和进行源代码混淆,所以基本上所有的解密模块代码就都搞出来了....如果问为什么不直接Copy他的核心功能函数,因为功能比较多,类库依赖关系和动态链接库配置比较复杂,而且我又懒(主要原因),所以还不如逆向一下解密模块算求了。
逆向了一下这个软件的解密过程,大概就用到两种加密算法,Base64和RSA(比较鸡贼,居然用RSA)。
加密信息是获取CPU序列号、主板序列号、硬盘序列号转成大写后用字符 “_” 连接(就是一般的获取硬件序列号方法)。
加密方法是将加密信息先通过RSA不对称加密,再通过Base64对称加密,然后将许可时间写入到注册表,在把许可时间组合通过Base64加密,最后生成两行许可信息(具体内容在代码注释中可以找到)。
由于对方使用了RSA,所以没办法生成注册机,原因为RSA是对信息进行私(公)钥加密,然后用公(私)钥去验证,私钥只被加密方持有,我这只持有公钥,所以只能挥泪咒骂,这下好了,美女同事的微信也没了。但是这个加密解密的方法还是值得学习的,整理下,自己生成一个RSA密钥对,可以用在以后软件的加密模块上,倒也算一个收获。
3.Theory
网上找了几张图,图解一下两种加密方式的原理,具体的算法原理可以上别处找去,啧。
对称加密(Base64):具体来说,就是密钥是同一把,可以加密可以解密。
不对称加密(RSA):两把不同的密钥,一把加密,一把解密。
4.Environment
Environment:Windows All
Language:C#
IDE:Visual Studio 2012
5.Source
注册机概览:
注册码生成(加密模块):
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
namespace KeyGen
{
public class LicGenerate
{
private string _sysinfo = "";
public LicGenerate(string sysInfo)
{
this._sysinfo = sysInfo;
}
#region 许可参数
//许可时间信息
private string _fromDateTime = "";
private string _toDateTime = "";
//机器序列号
private static string _systemInfo = string.Empty;
//许可文件内容
private string keyLicenseCode = "";
private string timeLicenseCode = "";
/// <summary>
/// 许可开始时间
/// </summary>
public string fromDateTime
{
set { _fromDateTime = value; }
get { return _fromDateTime; }
}
/// <summary>
/// 许可结束时间
/// </summary>
public string toDateTime
{
set { _toDateTime = value; }
get { return _toDateTime; }
}
/// <summary>
/// 私钥
/// </summary>
private const string privateKey = "<RSAKeyValue><Modulus>r+Fknz/UEsPyB+rOJpRt6BLPUnPvYFEAuXFtL6x23NI7LrUf+Xvcfo1iPMMJruOdNPs+wYNpxNy1166n5mRuSLn7EPbt1aumfCmtgq150NDWWdmx1y5rHNGFu9sUSUm+EgNEgVNbrjTTq8ru7ZJU2X5CLuLMYevuXwBaLZoS8kk=</Modulus><Exponent>AQAB</Exponent><P>6UVOdO86q+jMO8pdQGivk1EW2AnO3LRzkULvKcsXhqXXlQAjDhjPEF192osfmmnLXiqMkYd9DxcVb9oa5sLxXw==</P><Q>wQSLzXpqLsdb2lExGRx2iNEGZvxgjQxIkgb21DLrzgKSu6dTUzhxnZ2Iag4XcB5AWedseqRVvcGEkPmchQ31Vw==</Q><DP>kS/X0yQKqnCsnRIo1CvUC6bOxwvjuq59t42neaW0MNQLx+tb5iw+xHrMGDe7JcpvD18AOpvPlJLTftiLIdF3lQ==</DP><DQ>C5YYRkdY5GH3M424IsfAncneVoRDz3OzT4C3hFliKkWhRT5wFAjJWSrBq4wZABPwzPTFYD9JHlDlgkZZjOsflQ==</DQ><InverseQ>hnXlKRysPRroqHNd8SlzAcEPnWpgExIxLU2McE6slDO0DrABEyb/LHG6BTc8eBvzO6G+JiaKddTVKhHCLVU/rA==</InverseQ><D>Vo6JU6o494dBTM4s6GWx9T2UlJKD4xXaUmlU/9pToPdBswnmk4R2jj2MdDTURiK0kod3agr/eafZQi0takBQ2V4Kq86JI/Ei2VvMP781sPE/pnfENMufwfbdcbHdrU4heyd3DBT0NtTfOA71jeAlVbvMrCJVYDo/H3VVukGntUU=</D></RSAKeyValue>";
/// <summary>
/// 第一行的许可信息
/// </summary>
public string KeyLicenseCode
{
set{ keyLicenseCode = value; }
get{ return keyLicenseCode; }
}
/// <summary>
/// 第二行的许可信息
/// </summary>
public string TimeLicenseCode
{
set{ timeLicenseCode = value; }
get{ return timeLicenseCode; }
}
/// <summary>
/// SHA1(Secure Hash Algorithm)安全哈希算法的哈希值,主要用于数字签名验证
/// </summary>
private static HashAlgorithm DefaultHashAlgorithm
{
get
{
return (HashAlgorithm)new SHA1CryptoServiceProvider();
}
}
/// <summary>
/// 默认字节顺序编码为UTF-16编码
/// </summary>
private static Encoding ByteConvertor
{
get
{
return Encoding.Unicode;
}
}
#endregion
#region 逆向许可方法
#region 生成许可文件
/// <summary>
/// 许可文件保存
/// </summary>
/// <returns>返回许可文件路径</returns>
private string licenseFileSave()
{
try
{
string licenseFilePath;
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.InitialDirectory = "D:\\";
saveFileDialog.Filter = "许可文件(*.lic)|*.lic";
saveFileDialog.RestoreDirectory = true;
DialogResult dr = saveFileDialog.ShowDialog();
if (dr == DialogResult.OK && saveFileDialog.FileName.Length > 0)
{
licenseFilePath = saveFileDialog.FileName;
}
else
{
return null;
}
return licenseFilePath;
}
catch
{
MessageBox.Show("许可文件存储失败!");
return null;
}
}
#endregion
#region 注册码生成
/// <summary>
/// 时间许可
/// </summary>
/// <returns>返回加密的时间许可代码</returns>
private string timeLicense()
{
try
{
DateTime fromDate;
DateTime toDate;
fromDate = DateTime.Parse(fromDateTime);
toDate = DateTime.Parse(toDateTime);
DateTime nowDate = DateTime.Now;
string str = Convert.ToBase64String(Encoding.Default.GetBytes(fromDate.ToString() + (object)"$" + toDate.ToShortDateString() + "$" + (object)nowDate.ToString()));
return str;
}
catch
{
MessageBox.Show("时间许可生成失败!");
return null;
}
}
/// <summary>
/// 私钥签名
/// </summary>
/// <param name="licenseFilePath">许可路径</param>
/// <param name="signatureData">需要签名的数据(机器码)</param>
/// <param name="privateKey">私钥</param>
/// <returns></returns>
private string privateKeySignature(byte[] signatureData, string privateKey)
{
try
{
//私钥签名
RSACryptoServiceProvider cryptoServiceProvider = new RSACryptoServiceProvider();
cryptoServiceProvider.FromXmlString(privateKey);
//用SHA1的哈希算法指定字节数组的哈希值,并对计算所得的哈希值进行签名,得到加密后的字节数组
byte[] signature = cryptoServiceProvider.SignData(signatureData, (object)DefaultHashAlgorithm);
//签名数据用Base64算法进行加密
string keyCode = Convert.ToBase64String(signature);
return keyCode;
}
catch
{
MessageBox.Show("许可签名失败!");
return null;
}
}
#endregion
//#region 系统信息
///// <summary>
///// 获得机器码信息
///// </summary>
//private static string SystemInfo
//{
// get
// {
// try
// {
// //如果字符串系统信息为空值
// if (string.IsNullOrEmpty(_systemInfo))
// {
// /*
// * 1.GetCpuId().ToUpper():获取CPU的ID信息(序列号),并转成大写
// * 2.GetMotherBoardId().ToUpper():获取主板的ID信息(序列号),并转成大写
// * 3.GetHarDiskId().ToUpper():获取硬盘的ID信息(序列号),并转成大写
// * 两个信息用"_"相连接,返回系统信息字符串。
// */
// _systemInfo = GetCpuId().ToUpper() + "_" + GetMotherBoardId().ToUpper() + "_" + GetHardDiskId().ToUpper();
// }
// return _systemInfo;
// }
// catch
// {
// MessageBox.Show("机器码序列号获取失败!");
// return null;
// }
// }
//}
///// <summary>
///// 获取CPU ID信息
///// </summary>
///// <returns>返回获取CPU ID</returns>
//private static string GetCpuId()
//{
// //传入"Win32_Processor"可获得CPU处理器信息
// ManagementObjectCollection instances = new ManagementClass("Win32_Processor").GetInstances();
// string str = (string)null;
// //
// using (ManagementObjectCollection.ManagementObjectEnumerator enumerator = instances.GetEnumerator())
// {
// if (enumerator.MoveNext())
// str = enumerator.Current.Properties["ProcessorId"].Value.ToString();
// }
// return str;
//}
///// <summary>
///// 获取硬盘ID信息
///// </summary>
///// <returns>返回硬盘ID信息</returns>
//private static string GetHardDiskId()
//{
// ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
// string str = (string)null;
// foreach (ManagementBaseObject managementBaseObject in managementObjectSearcher.Get())
// str = managementBaseObject["SerialNumber"].ToString().Trim();
// return str;
//}
///// <summary>
///// 获取主板信息
///// </summary>
///// <returns>返回主板信息</returns>
//private static string GetMotherBoardId()
//{
// //
// ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_BaseBoard");
// string str = string.Empty;
// using (ManagementObjectCollection.ManagementObjectEnumerator enumerator = managementObjectSearcher.Get().GetEnumerator())
// {
// if (enumerator.MoveNext())
// {
// object obj = enumerator.Current["SerialNumber"];
// if (obj != null)
// str = obj.ToString();
// }
// }
// return str;
//}
//#endregion
#region 注册表清理
/// <summary>
/// 注册表清理
/// </summary>
/// <returns>返回注册表清理结果</returns>
private bool regeditWrite()
{
DateTime fromDate;
DateTime toDate;
fromDate = DateTime.Parse(fromDateTime);
toDate = DateTime.Parse(toDateTime);
try
{
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\PrivateCMW\\TimeLimitKey", true))
{
//如果注册表存在,就删除注册表
if (registryKey != null)
{
//using (RegistryKey registryCreate = Registry.CurrentUser.CreateSubKey("SOFTWARE\\PrivateCMW\\TimeLimitKey"))
//{
// //写入许可开始时间
// registryCreate.SetValue("Start", (object)fromDate.ToString());
// //写入许可结束时间
// registryCreate.SetValue("End", (object)toDate.ToShortDateString());
//}
//return true;
try
{
RegistryKey registryDelete = Registry.CurrentUser;
registryDelete.DeleteSubKey("SOFTWARE\\PrivateCMW\\TimeLimitKey", true);
registryDelete.Close();
}
catch
{
MessageBox.Show("注册表清理失败!");
return false;
}
//using (RegistryKey registryCreate = Registry.CurrentUser.CreateSubKey("SOFTWARE\\PrivateCMW\\TimeLimitKey"))
//{
// //写入许可开始时间
// registryCreate.SetValue("Start", (object)fromDate.ToString());
// //写入许可结束时间
// registryCreate.SetValue("End", (object)toDate.ToShortDateString());
//}
}
////如果存在就清理并创建新的注册表
//else
//{
//}
}
return true;
}
catch
{
MessageBox.Show("注册表清理失败!");
return false;
}
}
#endregion
#region 许可文件写入
/// <summary>
/// 许可文件写入
/// </summary>
/// <param name="licenseFilePath">许可文件路径</param>
/// <param name="keyCode">密钥许可</param>
/// <param name="timeCode">时间许可</param>
/// <returns>返回许可文件写入结果</returns>
private bool licenseWrite(string licenseFilePath, string keyCode, string timeCode)
{
try
{
if (!File.Exists(licenseFilePath))
{
using (FileStream fileStream = new FileStream(licenseFilePath, FileMode.Create, FileAccess.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream)fileStream, Encoding.Default))
{
streamWriter.WriteLine(keyCode);
streamWriter.WriteLine(timeCode);
}
}
return true;
}
else
{
using (FileStream fileStream = new FileStream(licenseFilePath, FileMode.Open, FileAccess.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream)fileStream, Encoding.Default))
{
streamWriter.WriteLine(keyCode);
streamWriter.WriteLine(timeCode);
}
}
return true;
}
}
catch
{
MessageBox.Show("许可文件写入失败!");
return false;
}
}
#endregion
#endregion
#region 执行生成许可文件
/// <summary>
/// 生成注册码
/// </summary>
public void hackExcute()
{
/* 许可验证步骤:
* 1.许可文件过滤
* 2.许可文件读取
* 3.注册表验证(许可时间)
* 4.加密算法验证许可文件
*/
//反向生成注册码
// 1.许可过滤(存在、合法[.lic结尾]、不为空[文本内容])
if (fromDateTime == "" || toDateTime == "" || (fromDateTime == "" && toDateTime == ""))
{
MessageBox.Show("时间许可不能为空!");
return;
}
// 2.许可写入
//需要进行私钥签名的机器序列号数据
//byte[] signature = ByteConvertor.GetBytes(SystemInfo);
byte[] sys = Convert.FromBase64String(_sysinfo);
//获得第一行的许可注册码(经过RSA不对称算法私钥签名和Base64加密的机器码信息)
keyLicenseCode = privateKeySignature(sys, privateKey);
//获得第二行的许可注册吗(经过Base64加密的时间组合信息)
timeLicenseCode = timeLicense();
// 3.注册许可
//对注册表进行清理,并注册新的许可
bool regeditControllder = regeditWrite();
//返回结果
//if (regeditControllder)
// MessageBox.Show("注册表清理成功!");
}
/// <summary>
/// 生成许可文件
/// </summary>
/// <returns>返回生成结果</returns>
public bool licenseFileGenerate()
{
try
{
string licenseFilePath = licenseFileSave();
//写入许可文件,返回结果
bool licenseController = licenseWrite(licenseFilePath, keyLicenseCode, timeLicenseCode);
return licenseController;
}
catch
{
MessageBox.Show("写入文件失败!");
return false;
}
}
#endregion
}
}
注册码验证(解密模块):
using LicenseCommonUtil;
using Microsoft.Win32;
using System;
using System.IO;
using System.Security.Cryptography;
namespace LicenseClient
{
public sealed class LicenseClient
{
public static bool CheckLicense(string licenseFilePath, out string message)
{
const string PublicKey = "<RSAKeyValue><Modulus>r+Fknz/UEsPyB+rOJpRt6BLPUnPvYFEAuXFtL6x23NI7LrUf+Xvcfo1iPMMJruOdNPs+wYNpxNy1166n5mRuSLn7EPbt1aumfCmtgq150NDWWdmx1y5rHNGFu9sUSUm+EgNEgVNbrjTTq8ru7ZJU2X5CLuLMYevuXwBaLZoS8kk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
try
{
message = "";
#region 许可过滤(不存在、不合法、空)
if (!File.Exists(licenseFilePath))
{
message = "许可文件不存在!";
return false;
}
//.lic结尾的文件
Path.GetExtension(licenseFilePath).Trim().ToUpper();
if (!Path.GetExtension(licenseFilePath).Trim().ToUpper().Equals(LicenseUtil.DefaultLicenseFileExtension.ToUpper()))
{
message = "指定的许可文件不合法!";
return false;
}
string s = LicenseUtil.ReadContentFromFile2(licenseFilePath);
if (string.IsNullOrEmpty(s))
{
message = "许可内容为空!";
return false;
}
#endregion
#region 对许可解密获取时间信息(fromDate,toDate,lastDate)
DateTime fromDate;
DateTime toDate;
DateTime lastDate;
LicenseUtil.ReadDateTiFromFile(licenseFilePath, out fromDate, out toDate, out lastDate);
#endregion
#region 许可使用的注册表判断
bool flag1 = false; //注册表信息控制器
string str1 = "";
string str2 = "";
if (lastDate == fromDate) //如果起始时间等于最后时间
{
try
{
//检索 SOFTWARE\\PrivateCMW\\TimeLimitKey,是否在当前用户的注册表中,不将写访问权限应用于该项。
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\PrivateCMW\\TimeLimitKey", false))
{
//如果是空的话,注册表信息控制值为true
if (registryKey == null)
{
flag1 = true;
}
else
{
//如果不为空,则检索注册表中与指定名称关联的值
str1 = registryKey.GetValue("Start").ToString();
str2 = registryKey.GetValue("End").ToString();
//判断两个值中是否包含 fromDate 和 toDate 两个值
//如果包含了这两个值,则判断许可已经使用
if (str1.Contains(fromDate.ToString()) && str2.Contains(toDate.ToShortDateString()))
{
message = "许可已使用!";
return false;
}
//如果不包含 fromDate 和 toDate ,则返回true
flag1 = true;
}
}
}
catch (Exception)
{
message = "验证注册表失败";
}
}
#endregion
#region 许可使用的时间期限判断
/*
* fromDate(授权许可开始的时间)
* toDate(授权许可结束的时间)
* lastDate(授权许可最后一次生效的时间)
*
* DataTime.Now < lastData(现在的时间 小于 授权许可最后一次生效的时间)
* lastDate < fromDate(授权许可最后一次生效的时间 小于 授权许可开始的时间)
* lastDate > toDate(授权许可最后一次生效的时间 大于 授权许可结束的时间)
* DateTime.Now < fromDate(现在的时间 小于 授权许可开始的时间)
* DateTime.Now > toDate(现在的时间 大于 授权许可结束的时间)
*
*/
if (DateTime.Now < lastDate || lastDate < fromDate || (lastDate > toDate || DateTime.Now < fromDate) || DateTime.Now > toDate)
{
message = "许可已经过期!";
return false;
}
#endregion
#region 加密算法验证许可文件
//创建一个 RSA不对称加密解密算法 对象
RSACryptoServiceProvider cryptoServiceProvider = new RSACryptoServiceProvider();
//XML字符串中的密钥信息(包含公钥或者包含公钥和私钥):
//<RSAKeyValue><Modulus>uqYMs9AxuAfGsbVvo+ah8Z7c91qbYJ8ARbX/7585ZVH1Jl9V5ebnjUEv+cuMjDEYzMCbJujoKZbqSRD5X5f9I2b9lNhRBhvBNBJj6ntzYKYp7HxYGTOr5NQ+eqNUejPhv9+fGedNa1oe/KyyfvE//NshoUN/oxVvCMlBIgHS98s=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
/* PEM格式公钥
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6pgyz0DG4B8axtW+j5qHxntz3
WptgnwBFtf/vnzllUfUmX1Xl5ueNQS/5y4yMMRjMwJsm6OgplupJEPlfl/0jZv2U
2FEGG8E0EmPqe3NgpinsfFgZM6vk1D56o1R6M+G/358Z501rWh78rLJ+8T/82yGh
Q3+jFW8IyUEiAdL3ywIDAQAB
-----END PUBLIC KEY-----
*/
//初始化 RSA不对称加密解密算法
cryptoServiceProvider.FromXmlString(PublicKey);
bool flag2;
try
{
//将字符编码转为一个UTF-16格式的字节序列
byte[] bytes = LicenseUtil.ByteConvertor.GetBytes(LicenseUtil.SystemInfo);
//打开许可文件,读取第一行的秘钥信息(s),通过Base64算法解密
byte[] signature = Convert.FromBase64String(s);
//传入字符序列,SHA1加密算法的哈希值,Base64的解密信息进行验证
/*
* VerifyData(buffer, halg, signature)
* 通过使用提供的公钥计算签名中的哈希值,然后将其与提供的数据的哈希值进行比较,从而验证数字签名是否有效。
*
* 返回值:
* 如果签名有效,则为 true;否则为 false。
*
* 参数:
* buffer
* Type: Byte[]
* 已签名的数据。
*
* halg
* Type: Object
* 用于创建数据哈希值的哈希算法的名称。
*
* signature
* Type: System.Byte[]
* 要验证的签名数据。
*
*/
flag2 = cryptoServiceProvider.VerifyData(bytes, (object)LicenseUtil.DefaultHashAlgorithm, signature);
}
catch
{
message = "许可文件验证错误!";
return false;
}
#endregion
#region 注册表和许可文件更新
//加密解密算法验证通过
if (flag2)
{
//注册表验证通过
if (flag1)
{
//检索注册表 SOFTWARE\\PrivateCMW\\TimeLimitKey,并支持写入操作
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\PrivateCMW\\TimeLimitKey", true))
{
//如果注册表为空
if (registryKey == null)
{
//创建注册表信息
using (RegistryKey subKey = Registry.CurrentUser.CreateSubKey("SOFTWARE\\PrivateCMW\\TimeLimitKey"))
{
//写入许可开始时间
subKey.SetValue("Start", (object)fromDate.ToString());
//写入许可结束时间
subKey.SetValue("End", (object)toDate.ToShortDateString());
}
}
else
{
//如果不为空
//追加新的许可开始时间和结束时间
registryKey.SetValue("Start", (object)(str1 + ";" + fromDate.ToString()));
registryKey.SetValue("End", (object)(str2 + ";" + toDate.ToShortDateString()));
}
}
}
//
LicenseUtil.UpdateDateToFile(licenseFilePath, DateTime.Now);
}
else
{
message = "许可文件验证不通过!";
}
return flag2;
#endregion
}
catch
{
message = "许可文件可能被篡改!";
return false;
}
}
}
}
许可调用的功能模块:
using System;
using System.Collections.Generic;
using System.IO;
using System.Management;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
namespace LicenseCommonUtil
{
public static class LicenseUtil
{
private static string _systemInfo = string.Empty;
public static Encoding ByteConvertor
{
get
{
return Encoding.Unicode;
}
}
public static HashAlgorithm DefaultHashAlgorithm
{
get
{
return (HashAlgorithm) new SHA1CryptoServiceProvider();
}
}
public static string DefaultLicenseFileExtension
{
get
{
return ".lic";
}
}
public static string SystemInfo
{
get
{
//如果字符串系统信息为空值
if (string.IsNullOrEmpty(LicenseUtil._systemInfo))
{
/*
* 1.GetCpuId().ToUpper():获取CPU的ID信息(序列号),并转成大写
* 2.GetMotherBoardId().ToUpper():
*
*
*/
LicenseUtil._systemInfo = LicenseUtil.GetCpuId().ToUpper() + "_" + LicenseUtil.GetMotherBoardId().ToUpper() + "_" + LicenseUtil.GetHardDiskId().ToUpper();
}
return LicenseUtil._systemInfo;
}
}
private static string GetCpuId()
{
//传入"Win32_Processor"可获得CPU处理器信息
ManagementObjectCollection instances = new ManagementClass("Win32_Processor").GetInstances();
string str = (string) null;
//
using (ManagementObjectCollection.ManagementObjectEnumerator enumerator = instances.GetEnumerator())
{
if (enumerator.MoveNext())
str = enumerator.Current.Properties["ProcessorId"].Value.ToString();
}
return str;
}
private static string GetHardDiskId()
{
ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
string str = (string) null;
foreach (ManagementBaseObject managementBaseObject in managementObjectSearcher.Get())
str = managementBaseObject["SerialNumber"].ToString().Trim();
return str;
}
private static string GetMotherBoardId()
{
//
ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_BaseBoard");
string str = string.Empty;
using (ManagementObjectCollection.ManagementObjectEnumerator enumerator = managementObjectSearcher.Get().GetEnumerator())
{
if (enumerator.MoveNext())
{
object obj = enumerator.Current["SerialNumber"];
if (obj != null)
str = obj.ToString();
}
}
return str;
}
public static void SaveFile(string fileContent, string defaultExtension, string filter)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.AddExtension = true;
saveFileDialog.DefaultExt = defaultExtension;
saveFileDialog.Filter = filter;
saveFileDialog.FileName = "licenseInfo";
if (saveFileDialog.ShowDialog() != DialogResult.OK)
return;
using (FileStream fileStream = new FileStream(saveFileDialog.FileName, FileMode.Create, FileAccess.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream) fileStream, Encoding.Default))
{
streamWriter.Write(fileContent);
int num = (int) MessageBox.Show("文件保存成功!", "提示");
}
}
}
public static void SaveFile(string fileContent, string nyr, string defaultExtension, string filter)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.AddExtension = true;
saveFileDialog.DefaultExt = defaultExtension;
saveFileDialog.Filter = filter;
saveFileDialog.FileName = "license.lic";
if (saveFileDialog.ShowDialog() != DialogResult.OK)
return;
using (FileStream fileStream = new FileStream(saveFileDialog.FileName, FileMode.Create, FileAccess.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream) fileStream, Encoding.Default))
{
streamWriter.WriteLine(fileContent);
streamWriter.WriteLine(nyr);
int num = (int) MessageBox.Show("文件保存成功!", "提示");
}
}
}
public static void SaveFile(string fileContent, string nyr, string todate, string defaultExtension, string filter)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.AddExtension = true;
saveFileDialog.DefaultExt = defaultExtension;
saveFileDialog.Filter = filter;
saveFileDialog.FileName = "license.lic";
if (saveFileDialog.ShowDialog() != DialogResult.OK)
return;
using (FileStream fileStream = new FileStream(saveFileDialog.FileName, FileMode.Create, FileAccess.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream) fileStream, Encoding.Default))
{
streamWriter.WriteLine(fileContent);
string str = Convert.ToBase64String(Encoding.Default.GetBytes(nyr + "$" + todate));
streamWriter.WriteLine(str);
int num = (int) MessageBox.Show("文件保存成功!", "提示");
}
}
}
public static string ReadContentFromFile(string filePath)
{
using (FileStream fileStream = new FileStream(filePath, FileMode.Open))
{
using (StreamReader streamReader = new StreamReader((Stream) fileStream, Encoding.Default))
return streamReader.ReadToEnd();
}
}
public static string ReadContentFromFile2(string filePath)
{
using (FileStream fileStream = new FileStream(filePath, FileMode.Open))
{
using (StreamReader streamReader = new StreamReader((Stream) fileStream, Encoding.Default))
//返回第一行的许可信息
return streamReader.ReadLine();
}
}
public static DateTime ReadDateTiFromFile(string filePath)
{
string s = string.Empty;
string str1 = string.Empty;
using (FileStream fileStream = new FileStream(filePath, FileMode.Open))
{
using (StreamReader streamReader = new StreamReader((Stream) fileStream, Encoding.Default))
{
string str2;
do
{
str2 = streamReader.ReadLine();
s = str2 ?? s;
}
while (str2 != null);
}
}
return DateTime.Parse(s);
}
/// <summary>
/// 从许可中读取时间信息
/// </summary>
/// <param name="filePath"></param>
/// <param name="fromDate"></param>
/// <param name="toDate"></param>
/// <param name="lastDate"></param>
public static void ReadDateTiFromFile(string filePath, out DateTime fromDate, out DateTime toDate, out DateTime lastDate)
{
List<string> list = new List<string>();
using (FileStream fileStream = new FileStream(filePath, FileMode.Open)) //打开文件流
{
using (StreamReader streamReader = new StreamReader((Stream) fileStream, Encoding.Default)) //打开文件流读取内容
{
//逐行遍历文件
//如果行字符串不为空,则继续遍历
//每次读取新的一行
for (string str = streamReader.ReadLine(); !string.IsNullOrEmpty(str); str = streamReader.ReadLine())
{
//将每行的字符串信息添加到列表中存储
list.Add(str);
}
}
}
//将当前计算机的本地时间赋值给三个变量
fromDate = toDate = lastDate = DateTime.Now;
//获取到列表的第二个索引对应的值
string s = list[1];
//如果第二个索引对应的值为空,则返回空值
if (string.IsNullOrEmpty(s))
return;
//创建字符串数组
/* 传入第二行的值
* 从Base64加密算法解密再转换成字符串
* 通过'$'符号对字符串进行分割,得到字符串数组,并且返回值不包含空字符串
* 得到的三个值分别为 fromDate、toDate、lastDate(如果字符串数组的长度大于2)
* 通过out参数传出
*/
string[] strArray = Encoding.Default.GetString(Convert.FromBase64String(s)).Split(new char[1]{'$'}, StringSplitOptions.RemoveEmptyEntries);
//分别对应索引值进行赋值
fromDate = DateTime.Parse(strArray[0]);
toDate = DateTime.Parse(strArray[1]);
if (strArray.Length > 2)
lastDate = DateTime.Parse(strArray[2]);
else
lastDate = fromDate;
}
public static void UpdateDateToFile(string filePath, DateTime nowDate)
{
List<string> list = new List<string>();
//只读
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (StreamReader streamReader = new StreamReader((Stream) fileStream, Encoding.Default))
{
//如果文件行不为空,逐行遍历,并添加到列表中
for (string str = streamReader.ReadLine(); !string.IsNullOrEmpty(str); str = streamReader.ReadLine())
{
list.Add(str);
}
}
}
DateTime dateTime1;
DateTime dateTime2 = dateTime1 = DateTime.Now;
//许可第二行的内容
string s = list[1];
//如果许可第二行不为空
if (!string.IsNullOrEmpty(s))
{
//创建字符串数组
/* 传入第二行的值
* 从Base64加密算法解密再转换成字符串
* 通过'$'符号对字符串进行分割,得到字符串数组,并且返回值不包含空字符串
*/
string[] strArray = Encoding.Default.GetString(Convert.FromBase64String(s)).Split(new char[1]
{
'$'
}, StringSplitOptions.RemoveEmptyEntries);
//dataTime2是通过Base64解密的通过'$'进行分割得到的第一行时间数据
dateTime2 = DateTime.Parse(strArray[0]);
//dataTime1
dateTime1 = DateTime.Parse(strArray[1]);
}
//支持写入
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream) fileStream, Encoding.Default))
{
//写入许可文件的第一行内容
streamWriter.WriteLine(list[0]);
/* 通过Base64加密算法进行加密
* 传入参数类型:字节序列
* 参数:
* 1.fromDate
* 2.toDate
* 3.lastDate
*
*/
string str = Convert.ToBase64String(Encoding.Default.GetBytes(dateTime2.ToString() + (object)"$" + dateTime1.ToShortDateString() + (object)"$" + (object)nowDate.ToString()));
streamWriter.WriteLine(str);
}
}
}
public static string GetStringFromByte(byte[] datas)
{
if (datas == null)
return string.Empty;
string str = string.Empty;
foreach (byte num in datas)
str = str + (object) num + "_";
return str;
}
}
}
6.Conclusion
作为一个GIS开发者,我其实想当个房东,每个月开着玛莎拉蒂去收收租多好,想着想着,X突然闪现到我身后的绝对领域,准备gank我,然而我根本是毫无破绽,虽然眼神迷离但是手一刻也没有停歇的敲击着黑轴机械,大眼珠子已经贴在了屏幕上,随着指尖的高潮,这个项目破解算是告一段落了,美女新同事的微信也吹了。
GitHub地址:https://github.com/Asada2142/.Net_EncryptionAnddecryption