.net逆向到注册机的编写(listary)
记一次 .net逆向到注册机的编写(C# 还原算法)
参考了Hangle大佬发布帖子:https://www.52pojie.cn/forum.php?mod=viewthread&tid=1785147
需要工具
1. dnSpy
2. Listary(6.1.0.38)
dnspy反编译
找到 Listary.Core.Pro 命名空间下的 LicenseChecker类
看到 CheckLicense 里面的代码 一开始我想使用 直接让函数返回 true来进行爆破的 奈何编译不了 只能编写注册机
复制代码 隐藏代码
using System;namespace Listary.Core.Pro{
// Token: 0x020001BB RID: 443 public class LicenseChecker {
// Token: 0x0600080D RID: 2061 RVA: 0x0001905C File Offset: 0x0001725C public static bool CheckLicense(string email, string license) {
if (email == null || license == null)
{
return false;
}
if (license.Length != 192) // license长度必须为192 {
return false;
}
email = email.ToLowerInvariant(); // 将email转换成小写 ulong num = ((ulong)LicenseChecker.\uE000(email) << 32) + (ulong)LicenseChecker.\uE001(email); // 获取一个 num 这个很关键 string text = "";
for (int i = 0; i < 12; i++)
{
int index = (int)(num >> 64 - (i + 1) * 5) & 31;
text += \uE185.\uE071(43381)[index].ToString(); // 取 "23456789ABCDEFGHJKLMNPQRSTUVWXYZ" 字符串的 第i位 拼接 }
return license.Substring(160, 12) == text;
// 判断 输入的license第160位到172位是不是等于text // 这样说明 注册码的前160位和后18位都可以是随机数 }
// Token: 0x0600080E RID: 2062 RVA: 0x000190F4 File Offset: 0x000172F4 private static uint \uE000(string \uE000)
{
uint num = 0U;
foreach (char c in \uE000)
{
num = 43U * num + (uint)c;
}
return num;
}
// Token: 0x0600080F RID: 2063 RVA: 0x00019128 File Offset: 0x00017328 private static uint \uE001(string \uE000)
{
uint num = 0U;
foreach (char c in \uE000)
{
num = (num << 4) + (uint)c;
uint num2 = num & 4026531840U;
if (num2 != 0U)
{
num ^= num2 >> 24;
num ^= num2;
}
}
return num;
}
// Token: 0x040004B7 RID: 1207 internal const int \uE000 = 192;
// Token: 0x040004B8 RID: 1208 private const string \uE001 = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
}
}编写注册机
复制代码 隐藏代码
using System;public class Program {
private static uint hash1(string a) {
uint num = 0U;
foreach (char c in a)
{
num = 43U * num + (uint)c;
}
return num;
}
private static uint hash2(string a) {
uint num = 0U;
foreach (char c in a)
{
num = (num << 4) + (uint)c;
uint num2 = num & 4026531840U;
if (num2 != 0U)
{
num ^= num2 >> 24;
num ^= num2;
}
}
return num;
}
public static string getLicense(string email) {
string ALPHA_NUMERIC = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
ulong num = ((ulong)hash1(email) << 32) + (ulong)hash2(email);
string license = "";
for (int i = 0; i < 12; i++)
{
int index = (int)(num >> 64 - (i + 1) * 5) & 31;
license += ALPHA_NUMERIC[index];
}
Random random = new Random();
string text = "";
for (int i = 0; i < 192; i++)
{
if (i == 172)
{
text = text.Substring(0, 160) + license;
}
text += ALPHA_NUMERIC[random.Next(0, ALPHA_NUMERIC.Length)];
}
return text;
}
public static void Main() {
string email = "www.52pojie.cn";
string license = getLicense(email);
Console.WriteLine(license);
}
}Python代码
复制代码 隐藏代码
import numpy as npimport randomdef hash1(a: str) -> np.uint32:
num = np.uint32(0)
for c in a:
num = np.uint32(43) * num + np.uint32(ord(c))
return numdef hash2(a: str) -> np.uint32:
num = np.uint32(0)
for c in a:
num = (num << np.uint32(4)) + np.uint32(ord(c))
num2 = num & np.uint32(4026531840)
if num2 != np.uint32(0):
num ^= num2 >> np.uint32(24)
num ^= num2
return numdef getLicense(email: str) -> str:
ALPHA_NUMERIC = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ" num = np.uint64(hash1(email)) << np.uint64(32) | np.uint64(hash2(email))
license = "" for i in range(12):
index = int((num >> np.uint64(64 - (i + 1) * 5)) & np.uint64(31))
license += ALPHA_NUMERIC[index]
random.seed()
text = "" for i in range(192):
if i == 172:
text = text[:160] + license
text += ALPHA_NUMERIC[np.random.randint(0, len(ALPHA_NUMERIC))]
return text
email = "2035776757@qq.com"license = getLicense(email)print(license)Gui界面注册机
Listary.zip
应各位要求补上编译好的成品 .net6.0编译
keygen.zip
上一篇:某专业起名程序注册码分析与注册机
下一篇:VMP 3.x 通用注册机