软件逆向分析注册机编写
前言
本软件会获取计算机的硬件信息(包括:CPU序列号、MAC地址、硬盘序列号),然后根据这些硬件信息生成一个序列号。用户将序列号发送给软件提供商,然后提供商将注册码(.lic格式文件)发送给用户,用户可以使用注册码完成注册。
本文将解决以下问题:
软件如何利用硬件信息生成序列号?(硬件信息与序列号的转换关系) 软件如何根据序列号判断注册码是否有效?如何根据序列号(或硬件信息)获取注册码?
注意:以下内容会屏蔽敏感信息!本文仅供技术研究!
未经注册
首先运行软件:
软件会直接弹出一个对话框。
点击“确定”后,点击上方菜单栏中的“注册”,点击“获取硬件信息”,软件安装目录下的“硬件信息收集工具.exe”会自动打开。
在界面中可以直接看到本软件读取的硬件信息:CPU序列号、MAC地址、硬盘序列号。
点击“硬件序列号”获取序列号。
正常流程下,我需要把这个序列号发送给软件提供商,然后从提供商那里获取注册码,然后点击图2中的“注册”。
破解过程中查看软件信息
同理,用看一下这个软件的编程语言,看看是不是打包的。
显然,这个软件是用 C# 语言编写的,基于 .NET 框架。
C#,一种将源代码编译成中间代码的语言,可以很容易地从中间代码中反编译出原始代码!
所以,大家可以用C#反编译ILSpy软件为所欲为~
反编译源代码
用 ILSpy 打开这个软件的主 exe 程序。
如您在左视图中所见,该软件有 3 个命名空间:.、..、. .
根据这些命名空间下的类名,很容易猜到注册功能就是在这个类中实现的!
接下来是分析类的代码。实现该功能的核心代码如下所示:
//流程第1步(笔者注释)
private bool Authorize()
{
try
{
string text = uiTxtRegisterKey.Text;
string text2 = "" ;
string text3 = "";
//流程第2步(笔者注释)
if (!text.Contains(text3) || !text.Contains(text2))
{
new Form().ShowErrorDialog("硬件序号异常,请在生成硬件序号时拷贝所有字符信息");
return false;
}
//流程第2步(笔者注释):首尾替换
text = text.Replace(text2, "").Replace(text3, "").Trim();
//流程第3步(笔者注释)
text = ExtendedUtils.Decrypt(text.Substring(0, text.Count() - 4), text.Substring(text.Count() - 4));
HardMessage hardMessage = JsonHepler.Json_DeserializeObject<HardMessage>(text);
if (hardMessage == null)
{
new Form().ShowErrorDialog("硬件序号异常,请在生成硬件序号时完整拷贝,且不要改动任意字符信息");
return false;
}
EnumHelper.GetEnumDescription(hardMessage.Duration);
if (hardMessage.CPUInfo != HardWareInformation.CPUInfo || hardMessage.DiskNo != HardWareInformation.DiskNo || hardMessage.MacAddress != HardWareInformation.MacAddress)
{
new Form().ShowErrorDialog("硬件信息不匹配");
return false;
}
ServerMessage serverMessage = new ServerMessage();
serverMessage.Clients = 1;
serverMessage.Code = Guid.NewGuid().ToString();
serverMessage.Date1 = DateTime.Now;
switch (hardMessage.Duration)
{
case EDuration.Forever:
serverMessage.Date2 = DateTime.Now.AddYears(100);
break;
case EDuration.OneMonth:
serverMessage.Date2 = DateTime.Now.AddMonths(1);
break;
case EDuration.ThreeMonth:
serverMessage.Date2 = DateTime.Now.AddMonths(3);
break;
case EDuration.SixMonth:
serverMessage.Date2 = DateTime.Now.AddMonths(6);
break;
case EDuration.OneYear:
serverMessage.Date2 = DateTime.Now.AddYears(1);
break;
case EDuration.TwoYear:
serverMessage.Date2 = DateTime.Now.AddYears(2);
break;
case EDuration.FiveYear:
serverMessage.Date2 = DateTime.Now.AddYears(5);
break;
default:
serverMessage.Date2 = DateTime.Now.AddMonths(1);
break;
}
serverMessage.HDMessage = new HardMessage
{
CPUInfo = HardWareInformation.CPUInfo,
DiskNo = HardWareInformation.DiskNo,
MacAddress = HardWareInformation.MacAddress
};
File.WriteAllText(Paths.AppLicfilePath, ExtendedUtils.Encrypts(JsonHepler.Json_SerializeObject(serverMessage)));
if (serverMessage != null)
{
skinLabelLastTime.Text = LimitTime(serverMessage);
}
UIMessageTip.ShowOk("注册完成");
skinLabelLastTime.Visible = true;
uiLabel.BringToFront();
uiLabel.Visible = true;
skinLabelLastTime.BringToFront();
MainForm.Instance.Text = MainForm.RegisteredTitle;
MainForm.Instance.SetStatusMsg(string.Empty);
return true;
}
catch (Exception ex)
{
LogHelper.Error(ex);
}
return false;
}
分析源代码
经过分析,读取注册码后的流程为:
用户指定注册码文件路径后注册机弹窗源码,软件调用k方法读取注册码文件,获取注册码文本。用户点击“注册”按钮,软件调用该方法(该方法为上图核心代码);如果文本中不包含字符串“”或“”,则会报错。否则,将""和""替换为空字符串,即删除文本中的""和"",得到文本;调用 . 解密文本的方法。密文是文本(text.(0, text.Count() - 4))的最后0到5位,解密密钥是文本的最后4位(text.(text.Count() - 4)).解密后的明文也存在于文本中;调用.ct方法对文本进行反序列化,获取;
数据大体流程图如下(注:图中除了三个字段,根据反编译源码,还有字段):
以上过程回答了问题2!
到目前为止注册机弹窗源码,回答问题1:
由于软件验证注册码,所以使用ct方法反序列化(字符串→硬件信息)
那么在生成注册码的时候注册机弹窗源码,就可以使用序列化的方法(硬件信息→字符串)!
最后回答问题3:
破解者需要编写程序(或注册机),输入硬件信息(CPU序列号、MAC地址、硬盘序列号),输出注册码。
参考上面的流程图,很容易想到只是把流程倒过来。
由于软件判断注册码是否有效,流程为:
(注册码)去掉两个字符串→解密(获取序列号)→反序列化→比较硬件信息
那么破解器的程序流程应该是:
输入硬件信息→序列化(获取序列号)→加密→添加两个字符串(获取注册码)!!
参考源代码:
软件使用。方法解密
然后就可以使用注册机了。方法加密!
软件使用.ct方法反序列化
然后注册机就可以连载了。方法!
需要注意的一个小细节是:根据源码,解密用的密文在前面,解密密钥的4位长度跟在密文后面,密文和解密密钥不重叠!密文后面首先是解密密钥,形成一个字符串。因此,用于解密的密钥不是固定的,完全是字符串的后四位!
并继续检查 ILSpy。方法的实现方法(如下图),发现使用DES算法进行加密,是一种对称加密算法。加密密钥和解密密钥相等,所以可以任意指定加密密钥。4位字符串!
写注册机
接下来就可以写注册机了,这才是最激动人心的时刻!
和软件一样,注册机也是用C#语言编写的,用来做一个小表单界面。
输入:硬件信息(包括CPU序列号、MAC地址、硬盘序列号)。
输出:注册码文件。
注意:以下仅显示核心代码!
首先,您需要定义一个类作为序列化的基础。
class HardMessage
{
public string CPUInfo { get; set; }
public string DiskNo { get; set; }
public string MacAddress { get; set; }
public int Clients { get; set; }
}
然后我们到了注册机的核心部分:
//构造硬件信息变量hardmessage,对hardmessage序列化为SerializeMessage
HardMessage hardmessage = new HardMessage { CPUInfo = MyCPUInfo, DiskNo = MyDiskNo, MacAddress = MyMacAddress, Clients = 1 };
string SerializeMessage = JsonHepler.Json_SerializeObject(hardmessage);
//加密。明文为SerializeMessage,加密密钥为"abcd"(密钥可任意指定一个长度为4的字符串)
//加密后的密文为EncryptMessage
string EncryptMessage = ExtendedUtils.Encrypt(SerializeMessage, "abcd");
//在密文EncryptMessage前加"",后加" "
string License = "" + EncryptMessage + "";
//生成注册码文件
StreamWriter sw = new StreamWriter("注册码.lic");
sw.Write(License);
sw.Dispose();
生成注册码
代码写好后,编译运行。
输入硬件信息后,在注册机所在目录下生成文件“ code.lic”。
最后在图2界面点击“”,选择“ Code.lic”文件,点击。. . . . .
答对了!!
版权保护: 本文由 8BDU软件分享博客-8BDU软件园 原创,转载请保留链接: /zhuceji/342.html
- 上一篇: 一直播批量注册机 媒体直播视频批量引流方法详解
- 下一篇: 音乐库注册机 混音编辑大师注册机