当前位置首页 > 注册机> 正文

注册机弹窗源码 【我爱破解】一个软件的逆向分析注册机编写

2022-04-30 09:04:52 暂无评论 注册机

软件逆向分析注册机编写

前言

本软件会获取计算机的硬件信息(包括: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

猜你喜欢

博客主人倒杯水
男,单身,无聊上班族,闲着没事喜欢研究代码,密集恐怖深度患者,资深技术宅。
  • 5435 文章总数
  • 135630访问次数
  • 2782建站天数
  • 标签