首页
论坛
课程
招聘
[原创]某.net软件注册算法分析
2014-1-8 19:10 14112

[原创]某.net软件注册算法分析

2014-1-8 19:10
14112
一个.net软件的算法分析
之前给一个群里的朋友做的记录,今天看到有人求破同样的软件但不同的版本,留着也没什么用,发上来,给有需要的人吧,简单的记录,大牛就不用看了

可能会影响一些人的利益,有人提醒我删掉帖子,我把相关的名字改成xx吧
--------------

XXXX程序算法分析简单记录
一、        简单去混淆和定位算法的关键位置
首先打开程序,点帮助里面的注册,输入任意的注册码,提示注册码不对

有了明显提示,对于我这样的菜鸟来说,信心增加了不少。
下面用ILSpy打开安装完的程序xx.exe
任意点一个进去,发现名称全部被是两个随机的字母,这样找关键点,有点头疼,下面用神器de4dot-2.0.3 来处理一下
进入cmd,把De4dot的主程序拖到cmd窗口,空格,然后再把需要处理的xx.exe
拖动进去,按回车,如图:

下面再把处理过的xx用ILSpy打开,
很快可以找到frmRegister这个位置,从名字就可以看到,这里应该就是注册窗口了。
下面来找注册这个按钮事件的相关代码
展开,可以看到frmLoade的事件,但其他的都看不到明显的名称,往下一点找,   
可以看到method_0(object,EverArgs):void,看这个事件里面的代码,可以看到类似注册失败的字符串,那应该就是这里没错了

关键位置定位完毕,下面来简单的看看注册部分的代码

二、        分解注册码里面的秘密
本人也是菜鸟,有不对的地方大牛指导一下,免得误导他人

开始是一些判断,
if (Class18.bool_30)
    {
        this.Close();
    }
不知道这是干嘛的,应该是判断是不是注册了吧
if (Strings.Len(Class16.string_0) == 0)
        {
            Interaction.MsgBox("机器码不能为空,如不能解决,请与XX联系。", MsgBoxStyle.OkOnly, null);
        }
这里比较明显,如果传入的参数string-0长度等于0,那就是机器码获取错误了,
继续往下:
string text = Strings.Trim(this.vmethod_0().Text);//获取机器码保存到text
                        string str = "";
                        string text2 = Strings.Trim(this.vmethod_6().Text);//获取注册码保存到text2
                        string text3 = Strings.Mid(text2, 1, 4) + Strings.Mid(text2, 9, 4);
        //text3读取注册码的前四位和后四位
                        string text4 = Strings.Mid(text2, 5, 1);// text4读取注册码里面的第5位
                        string text5 = Strings.Mid(text2, 7, 1);// text5读取注册码的第7位
分别记下
Text=机器码
Text2=注册码
text3读取注册码的前四位和后四位
text4读取注册码里面的第5位
text5读取注册码的第7位
if (Operators.CompareString(text4, "6", false) == 0 | Operators.CompareString(text4, "7", false) == 0 | Operators.CompareString(text4, "B", false) == 0)
            {
                text4 = "1";
            }
            if (Operators.CompareString(text4, "8", false) == 0 | Operators.CompareString(text4, "9", false) == 0 | Operators.CompareString(text4, "C", false) == 0)
            {
                text4 = "2";
            }
比较注册码里面的第五位如果等于6或者7或者B那将注册码的第五位赋值等于1
如果等于8或者0或者C,那就等于2
//==============================
string value = "20" + text4 + Strings.Mid(text2, 6, 1);
看看这句,value等于20+1或者是2(由前面判断得到)+注册码的第六位
组合起来就是201X  202X  
那这样就明显了,如果第六位等于3那值应该就是2013或者2023
很熟悉,知道了这代表年,既然有年,那应该就有月吧,继续往下
//=====================
    if (Operators.CompareString(text5, "6", false) == 0 | Operators.CompareString(text5, "7", false) == 0 | Operators.CompareString(text5, "B", false) == 0)
//text5等于读取注册码里面的第七位,这里分析可以看到,如果第七位等于6或者等于7或者等于B,那第七位等于1
            {
                text5 = "1";
            }
            if (Operators.CompareString(text5, "4", false) == 0 | Operators.CompareString(text5, "5", false) == 0 | Operators.CompareString(text5, "A", false) == 0)
//如果第七位等于4或等于5或等于A,那第七位等于0
            {
                text5 = "0";
            }
            string value2 = text5 + Strings.Mid(text2, 8, 1);
//简单的解释这句value2等于第七位加注册码里面的第8位
If text5=1  第8位设置一个2
那就是12
If text5等于0
那就是02
这下看出来了这里是作者为了掩饰,防止别人一眼就看出来到期的时间,加了些混淆的东西,
下面整理一下这部分:
年:等于20+注册码的第5位+第6位
月:等于注册码的第7位+第8位
if (text2.Length == 13 & Operators.CompareString(Strings.Mid(text2, 13, 1), "1", false) == 0)
这里是判断注册码长度是不是13位,第13位是不是1
//---------------------------
继续看下面的判断:
int num;定义两个整数型的变量 年和月
            int num2;
            try
            {
                num = Conversions.ToInteger(value);//转换为整数,如果不是数字,那就会出错,返回注册码错误
                num2 = Conversions.ToInteger(value2);
            }
            catch (Exception expr_341)
            {
                ProjectData.SetProjectError(expr_341);
                this.vmethod_2().Text = "注册码不对!";
                ProjectData.ClearProjectError();
                return;
            }
if (num < 2013 | num > 2030 | num2 < 1 | num2 > 12 | num < DateAndTime.Now.Year | (num == DateAndTime.Now.Year & num2 < DateAndTime.Now.Month))
            {
                this.vmethod_2().Text = "注册码不对!";
            }
//这里也比较好看得懂,判断年是不是小于2013或者大于2030,月是不是小于1大于12并判断当前时间是不是超过了注册码的时间,也就是是不是到期了。到期了就返回注册码错误
//
    if (this.short_0 == 1)
                {
                    this.method_1(this.vmethod_8(), new EventArgs());
                }
                else
                {
                    if (Operators.CompareString(this.vmethod_4().Text, "", false) == 0)
                    {
                        this.vmethod_2().Text = "您没有输入姓名。";
                    }
                    else
                    {
                        if (Strings.Len(text3) == 0)
                        {
                            this.vmethod_2().Text = "您没有输入注册码。";
                        }
                        else
                        {
//这里也比较容易看懂,判断用户名和注册码是不是输入了
if (Class18.smethod_21(ref text, ref text3) & !File.Exists(Class21.string_8 + "\\syspbaz713.dll"))
                            {
                                Class1.smethod_0().Registry.SetValue("HKEY_CURRENT_USER\\Software\\NanfangSoft .net\\PaiBazi713", "Name", this.vmethod_4().Text);
                                string text6 = Strings.UCase(text3);
                                Class21.smethod_11(ref text, ref text6, ref value, ref value2);
                                Class21.bool_0 = true;
                                this.vmethod_2().Text = "注册成功!点击'退出'。" + str;
                            }
                            else
                            {
                                this.vmethod_2().Text = "注册码不对!";
                            }
这里来到真正的判断注册码是不是正确的地方了,
Class18.smethod_21(ref text, ref text3)
这句是关键
Class18.smethod_21(ref text, ref text3)
调用函数smethod_21(机器码,注册码的前面4位和后面4位)
两个参数 机器码,注册码前后四位
关于这个函数,应该就是机器码的对比了,接下来继续分析

//---------------------------
那初步估计,注册码只能输入12位了
//来整理下这段的思路
1、        注册码长度12位
2、        注册码的第5第6等于年的后两位
3、        注册码的第7第8位等于月份
//End
到期时间分析完了,接下来就是注册码的前面4位加上后面四位是干嘛的了
继续。。。

三、        程序是怎样判断机器码是否对应的
       Class18.smethod_21(ref text, ref text3
       从这里接着看,点击进入.smethod_21
       看到下面代码:

传入两个参数string_54等于机器码,string55等于分离后的注册码
if (Operators.CompareString(string_54, "", false) == 0 | Operators.CompareString(string_55, "", false) == 0)
    {
        result = false;
    }
这里好看懂,注册码或机器码其中一个为空,返回False
string text = Class15.smethod_14(ref string_54);
这里又调用了一个函数smethod_14(机器码)
这里传入一个参数,也就是机器码,根据经验,这里肯定是机器码的加密或者解密
,进去看看里面到底干了什么,这里进去看代码像是MD5的加密,可以自己复制代码在C#的工程里面,调用一下就知道了
返回加密后的md5,这里记录一下smethod_14的作用,之后还会用到
///-------------------------
string text = Class15.smethod_14(ref string_54);
也就是说,text等于加密后的MD5
Class16.smethod_5(ref text);
又一个调用,进去看看都干了什么?

if (text.Length > 10)
    {
        text = Strings.Left(text, 10) + Strings.Right(text, 5);
    }
text等于取机器码的左边10位+右边5位
//----------------
string text2 = Class15.smethod_14(ref text);//这句将text进行md5加密
text2等于 机器码MD5加密然后取左边10位+右边5位,再进行md5加密
这样就比较明显了
//======================
Class16.string_1 = Class16.smethod_4(ref text2);//继续分析这个
进smethod—4看看

可以看到这里没有调用其他的子程序,可以直接复制到VS里面,然后直接调用,这里也不太难,取出第8、3、15、12、17、2、17、1、14、13、9、8后面的就不分析了,技术太菜,不好献丑了,直接放到代码里面调用
再返回去看看比较
if (Operators.CompareString(Strings.UCase(Strings.Mid(Class16.string_1, 5, 8)), Strings.UCase(string_55), false) == 0)
        {
            Class16.string_1 = "a@^*(^*ga$(&%io";
            result = true;
        }
        else
        {
            result = false;
        }
从返回的字符串里面从第5位起读取8个,然后和传入的参数注册码前后4位比较

//End
改分析的也分析完了,最后来整理一下思路吧
四、        整理思路,做算法注册机
1、        注册码的第5第6等于年的后两位
2、        注册码的第7第8位等于月份
3、        将机器码进行MD5加密
4、        加密然后取左边10位+右边5位
5、        再进行一次md5加密
6、        调用直接复制的函数,传入参数md5
7、        返回的字符串从第5位起读取8个
8、        组合分离返回的前4位+年(两位)+月(两位)+返回的后面四位
   
---------------
论坛排版不太习惯,没显示图,直接上传word文档吧

下载word版本

算法分析记录.doc

[2022冬季班]《安卓高级研修班(网课)》月薪三万班招生中~

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (17)
雪    币: 8
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
YUEN 活跃值 2014-1-8 19:29
2
0
非常感谢!我对照找看看,不懂的地方,还需要多多指点
雪    币: 57
活跃值: 活跃值 (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wkxq 活跃值 2014-1-8 21:51
3
0
必须加分
雪    币: 8634
活跃值: 活跃值 (1570)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xie风腾 活跃值 2014-1-8 22:44
4
0
强大哟,来学习了
雪    币: 155
活跃值: 活跃值 (13)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
<<Lanneret 活跃值 1 2014-1-9 11:23
5
0
分析的挺细致的,赞一个。
雪    币: 325
活跃值: 活跃值 (47)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
地狱怪客 活跃值 2 2014-1-9 11:53
6
0
下载龟速。。。
雪    币: 5646
活跃值: 活跃值 (676)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tydzjing 活跃值 2014-1-9 15:28
7
0
分析过程非常详尽 学习了
雪    币: 1534
活跃值: 活跃值 (263)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
红绡枫叶 活跃值 6 2014-1-9 18:40
8
0
谢谢楼主分享,很不错
雪    币: 135
活跃值: 活跃值 (16)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
王者之剑 活跃值 1 2014-1-9 22:41
9
0
支持一下大N的作品
雪    币: 458
活跃值: 活跃值 (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小龙程序 活跃值 2014-1-9 23:39
10
0
感谢分享!学习了!
雪    币: 31
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
icemars 活跃值 2014-1-10 14:55
11
0
没有word版本啊
雪    币: 31
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
icemars 活跃值 2014-1-10 14:56
12
0
我错了 刚刚没刷新好········
雪    币: 262
活跃值: 活跃值 (16)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
yunfeng 活跃值 1 2014-1-11 16:11
13
0
写得不错,支持一下。
雪    币: 189
活跃值: 活跃值 (544)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xingbing 活跃值 2014-1-12 13:41
14
0
这个是不是反编译出来以后分析的?
雪    币: 280
活跃值: 活跃值 (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
似曾相识 活跃值 2014-1-13 15:40
15
0
这一看就是南方黑芝麻糊。
雪    币: 5374
活跃值: 活跃值 (958)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
logkiller 活跃值 2014-1-15 22:24
16
0
我很确定这款软件我也搞过2次,当时觉得很蛋疼的软件,因为我不太懂算法。。。。
雪    币: 1781
活跃值: 活跃值 (79)
能力值: ( LV9,RANK:370 )
在线值:
发帖
回帖
粉丝
fosom 活跃值 8 2014-1-16 09:26
17
0
贵宾,这个称号怎么来的?
雪    币: 189
活跃值: 活跃值 (544)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xingbing 活跃值 2014-2-7 14:17
18
0
net的分析是不是有他固定的模式。
游客
登录 | 注册 方可回帖
返回