吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 10546|回复: 94
上一主题 下一主题
收起左侧

[.NET逆向] 记一次 .net逆向到注册机的编写(listary)

  [复制链接]
跳转到指定楼层
楼主
P.Y.G-亮亮 发表于 2023-5-29 10:34 回帖奖励
本帖最后由 P.Y.G-亮亮 于 2023-5-30 08:13 编辑

比较小白有不对的地方欢迎指正




记一次 .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 np
import random

def hash1(a: str) -> np.uint32:
    num = np.uint32(0)
    for c in a:
        num = np.uint32(43) * num + np.uint32(ord(c))
    return num

def 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 num

def 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 (283.64 KB, 下载次数: 747)
应各位要求补上编译好的成品 .net6.0编译

keygen.zip (77.99 KB, 下载次数: 868)

免费评分

参与人数 13吾爱币 +18 热心值 +12 收起 理由
wxhwz + 1 + 1 我很赞同!
vicky526356 + 1 谢谢@Thanks!厉害了大佬,学习了
wydfy + 1 6.3的版本,不行哦,注册不了
qingfengvvv + 1 + 1 用心讨论,共获提升!
wulala666 + 1 谢谢@Thanks!
safe-夏天 + 2 + 1 牛蛙!!!!
xkj + 1 + 1 谢谢@Thanks!
landon-zeng + 1 + 1 我很赞同!
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Courser + 1 + 1 用心讨论,共获提升!
Patches + 1 + 1 用心讨论,共获提升!
长得帅活得久 + 1 + 1 我很赞同!
yp17792351859 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

来自 #
 楼主| P.Y.G-亮亮 发表于 2023-5-29 18:14 |楼主
补充一个python 代码
[Python] 纯文本查看 复制代码
import numpy as np
import random


def hash1(a: str) -> np.uint32:
    num = np.uint32(0)
    for c in a:
        num = np.uint32(43) * num + np.uint32(ord(c))
    return num


def 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 num


def 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 = "www.52pojie.cn"
license = getLicense(email)
print(license)
推荐
SnowRen 发表于 2023-5-30 21:50
无意中发现,邮箱中不能含大写字母,否则注册码无效
推荐
zgzxp 发表于 2023-5-29 11:53
本帖最后由 zgzxp 于 2023-5-29 12:49 编辑

[C#] 纯文本查看 复制代码
public static bool CheckLicense(string email, string license)
{
        if (email == null || license == null)
        {
                return false;
        }
        if (license.Length != 192)
        {
                return false;
        }
        email = email.ToLowerInvariant();
        ulong num = ((ulong)LicenseChecker.smethod_0(email) << 32) + (ulong)LicenseChecker.smethod_1(email);
        string text = "";
        for (int i = 0; i < 12; i++)
        {
                int num2 = (int)(num >> 64 - (i + 1) * 5) & 31;
                text += Class466.smethod_0(48245)[num2].ToString();
        }
        if (license.Substring(160, 12) != text)
        {
                Clipboard.SetDataObject(string.Concat(new string[]
                {
                        license.Substring(0, 32),
                        "\r\n",
                        license.Substring(32, 32),
                        "\r\n",
                        license.Substring(64, 32),
                        "\r\n",
                        license.Substring(96, 32),
                        "\r\n",
                        license.Substring(128, 32),
                        "\r\n",
                        text,
                        license.Substring(172, 20)
                }));
                MessageBox.Show("注册码已复制到剪贴板!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
        }
        return license.Substring(160, 12) == text;
}

我直接改造原来的,这样的注册码虽然能组成成功,看起来怪怪的
3#
ernv 发表于 2023-5-29 10:52
大佬,我有个软件,能否帮忙看看。
4#
zgzxp 发表于 2023-5-29 11:41
顶楼主,这样1-159,173-190是随机的。有大神能提示下,这个软件正经的这些位置是怎么得来的吗?
5#
 楼主| P.Y.G-亮亮 发表于 2023-5-29 11:43 |楼主
zgzxp 发表于 2023-5-29 11:41
顶楼主,这样1-159,173-190是随机的。有大神能提示下,这个软件正经的这些位置是怎么得来的吗?

看源代码里面  写了哦    “return license.Substring(160, 12) == text; ”  也就这一段 能看出来
6#
zgzxp 发表于 2023-5-29 11:48
P.Y.G-亮亮 发表于 2023-5-29 11:43
看源代码里面  写了哦    “return license.Substring(160, 12) == text; ”  也就这一段 能看出来

谢谢回复。我的意思是他的1-159和173-190位是怎么得来的。
这个原软件里不可能是随机
7#
jyjjf 发表于 2023-5-29 12:20
zgzxp 发表于 2023-5-29 11:48
谢谢回复。我的意思是他的1-159和173-190位是怎么得来的。
这个原软件里不可能是随机

都随机了,那自己手动一个就行啊(或者为了发放注册码统计,自己按规则随便弄点就行了啊),都不用原软件生成了,只要判断长度,然后截取指定位置就行了。
8#
blindcat 发表于 2023-5-29 14:25
感谢分享,学习一下
9#
spray 发表于 2023-5-29 15:05
学习了,感谢分享。
10#
sdieedu 发表于 2023-5-29 15:08
如何用? 看不懂  在线运行?没有exe 啊
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-22 11:52

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表