本帖最后由 zjh16529 于 2019-6-6 18:21 编辑
软件名称:XXX八字专业程序 V7.30
下载地址:http://www.nfzhouyi.com/qita/Download.htm
工具地址:http://down.52pojie.cn/Tools/NET/
2017-4-22
这2天出差,利用时间把注册机重新写了一下。换用vb .net语言,可能比Vb运行起来,兼容性要好一些吧,同时修复了上一版的一个Bug,
计算出来的码,部分会注册不成功,是原算法里面有一处替换,O与0要替换成8,在Dnspy显示的时候,分不清是字母还是数字,出了一
点小差错,这次修复了,同时把南方周易系列可以收集到的,都整合在了一起,分别是排八字、批八字、起名。其中批八字是坛友提供的
安装包,感觉和排八字没有大差别。
新注册机下载地址:
注册机.zip
(12.38 KB, 下载次数: 6544)
有需要的下载这个,大家发现有注册不上的,随时联系我
用户组升级了,可以上传3M的附件,咱们不用百度云那个了,我把注册机重新传一下。
那个因为是VB6写的,用了个图标是32位色的,有些系统会 抛出 "末预期错误“
就又更新了一下。对不住大家了。
更新批八字注册机。
只会用一点点的VB,来写出这么个注册机。大家不要玩坏它,不会捕捉Error,这个就会老老实实根据机器码来算注册码。
还有,我是在win10环境下编译的,其它环境没试验,不知道可不可以运行。另外就是界面丑的不忍直视
2017-4-18:
在这里感谢steven2016、Mopoo 这两位坛友,是他们提醒和指导我,注册码验证计算的第2步骤,那个是MD5的计算。至此,注册机应该可以写出来了。
新鲜的小白在逆向这条路上,还有好多东西都不知道,谢谢这些乐于助人的坛友,帮助我们来提高。再一次的对吾爱的兄弟姐妹们表示感谢!!
注册机稍后奉上
备注一下:下载回去的补丁,随便输入个假码,就注册成功了:1234CKBA1234B81 输入这个吧。
通过认真学习本贴,80%的可以追到注册码,30%的同学,可以将类似的软件追到注册码,还有10%的同学,应该可以写出注册机。
感谢@spguangz 提醒及处理此贴
前言:之前好像看见过论坛里面有人发这个软件的破解教程,正好想着来学习一下。自去年开始接触逆向,小小的爆破了一个软件后,
就再也没有大进展,还是小白新人一枚。多说一些费话,刚接触逆向的时候,怕.net的程序,现在有些喜欢.net的程序。因为.net的逆向
可以看见源码,比汇编的代码能更加容易的看见程序的逻辑结构和走向。特别是找到了注册验证的核心后,就能够找到注册码(由于刚
刚逆向成功一个软件,不知道其它的软件是不是也这样,就妄自猜测一下。),如果有编程功底的,更是可以追出算法,写出注册机。这
次我们在找出注册码的同时、爆破程序,并且向写"注册机"来挑战,言归正传,开始小白的.net逆向之旅。
需要准备的工具和了解的概念。
1.1、工具篇。
刚开始接触这个,就知道有个Reflector这软件是专门针对.net程序的,而之前常用的OD就不在适用.net的逆向。工具可以论坛的爱盘
去下载。有几款工具超级值得推荐,Dnspy、De4dot、Reflector、Reflexi插件、Sanid、Dot Net id,其中Dnspy是动态调试.net程序的,
特别的好用。Reflector需要配合Reflexi插件,就可以修改程序了。工具大致就是这些,后面使用到的时候,会在接着介绍。
1.2、概念或者术语
需要了解的一些概念或者叫做术语,由于也是刚刚接触.net的程序,很多东西都不懂。搜索论坛及百度,大致知道一些“行话”,列出
来,让和我一样的入门的小白,能更多的了解一些。也不知道理解的对不对,如果有不对的,请大神指点一下。谢谢:)
混淆:
我理解的意思就是相当于给.net的程序加壳,还有就是使程序中调用的各种方法或者类(不知道这样叫准确不准确,姑且这样叫)都重
新命名,使得调用的关系混乱,不能根据名称来大致猜测出代码的功能。
强命名:
本意应该是.net的一个特性,就是不充许对软件的修改,造成名称的变化,而影响软件的运行。看一下截图,红线框住的部分,那些用
”单字母”命名的应该是有问题的。我开始以为是强命名的问题,后来我觉得应该是混淆造成的。具体是啥样的,望大神指点。
Dnspy 混淆
二、开工 Let's GO
2.1、查壳
老套路,开始干活之前,咱们都是先查一下壳,用Peid查一下,看是.net的程序。接着又用ScanID也扫描一下
.
Scan ID显示有Dotfuscator>>>>>Dotfuscator 208030:0:0:5.26.0.4551,这个是Dotfusctor混淆,通过这2天的调试,
除了上面截图那个,跟踪有些费力,到没有影响分析。
小结:在我们拿到软件,查壳是必需先要做的事情,我们可以知道是否加壳,软件是用什么语言编写的,心里面有一个大概的了解。
同时也可以有针对性的使用不同的工具,比如Delphi就有DD,另外,对于加壳,.net的程序应该就得要想办法去掉,也叫反混淆。而
非.net的程序,有时脱不掉,也可以带壳在OD里面运行起来,同样也可以调试,特别是在载入的时候,搜索不到关键字符的时候,可以
试着把运行F9运行起来,这时壳应该把原程序的代码都释放出来,在搜索关键字就差不多能搜索到了。
2.2、调试开始
费话这么多,终于进入主题了,开始是使用Reflector来分析的,可是想着这要是能够像OD那样动态调试就好了,在论坛找找,
才知道有Dnspy这神器。太霸道了,之后的分析都是在Dnspy中完成,后面的爆破是用的Reflector+Reflexi完成的。首先把dnspy打
开,载入南方排八字。
打开程序,点击注册,随便输入个假码,会出现"注册码不对"的提示信息,我们在Dnspy中就搜索 "注册"这个关键字,会返回5个调
用的方法其中m那个为注册的关键方法。双击 m 进到代码区。
[C#] 纯文本查看 复制代码 string text3 = Strings.Trim(this.o().Text);
IL_AE:
num2 = 14;
bool flag2 = text3.Length < 14 | text3.Length > 15;
if (!flag2)
{
goto IL_E8;
}
IL_CE:
num2 = 15;
this.m().Text = "注册码不对!";
IL_E2:
goto IL_84E;
IL_E8:
IL_E9:
num2 = 18;
通过上面代码,知道注册码的长度要符合15位,否则注册失败。
[C#] 纯文本查看 复制代码 string text4 = Strings.Mid(text3, 1, 4) + Strings.Mid(text3, 9, 4);
IL_106:
num2 = 19;
string text5 = Strings.Mid(text3, 5, 1);
IL_114:
num2 = 20;
string text6 = Strings.Mid(text3, 6, 1);
IL_122:
num2 = 21;
string text7 = Strings.Mid(text3, 7, 1);
IL_130:
num2 = 22;
string text8 = Strings.Mid(text3, 8, 1);
IL_13E:
num2 = 23;
string text9 = Strings.Mid(text3, 13, 1);
IL_14D:
num2 = 24;
string str2 = Strings.Mid(text3, 14, 1);
IL_15C:
num2 = 25;
bool flag3 = Operators.CompareString(text5, "6", true) == 0 | Operators.CompareString(text5, "7", true) == 0 | Operators.CompareString(text5, "B", true) == 0;
if (!flag3)
{
goto IL_1A1;
}
IL_197:
num2 = 26;
text5 = "1";
IL_1A1:
num2 = 27;
bool flag4 = Operators.CompareString(text5, "8", true) == 0 | Operators.CompareString(text5, "9", true) == 0 | Operators.CompareString(text5, "C", true) == 0;
if (!flag4)
{
goto IL_1E6;
}
IL_1DC:
num2 = 28;
text5 = "2";
IL_1E6:
num2 = 29;
bool flag5 = Operators.CompareString(text6, "A", true) == 0;
if (!flag5)
{
goto IL_209;
}
IL_1FF:
num2 = 30;
text6 = "0";
IL_209:
num2 = 31;
bool flag6 = Operators.CompareString(text6, "B", true) == 0;
if (!flag6)
{
goto IL_22C;
}
IL_222:
num2 = 32;
text6 = "1";
IL_22C:
num2 = 33;
bool flag7 = Operators.CompareString(text6, "C", true) == 0;
if (!flag7)
{
goto IL_24F;
}
IL_245:
num2 = 34;
text6 = "2";
IL_24F:
num2 = 35;
bool flag8 = Operators.CompareString(text6, "D", true) == 0;
if (!flag8)
{
goto IL_272;
}
IL_268:
num2 = 36;
text6 = "3";
IL_272:
num2 = 37;
bool flag9 = Operators.CompareString(text6, "E", true) == 0;
if (!flag9)
{
goto IL_295;
}
IL_28B:
num2 = 38;
text6 = "4";
IL_295:
num2 = 39;
bool flag10 = Operators.CompareString(text6, "F", true) == 0;
if (!flag10)
{
goto IL_2B8;
}
IL_2AE:
num2 = 40;
text6 = "5";
IL_2B8:
num2 = 41;
bool flag11 = Operators.CompareString(text6, "G", true) == 0;
if (!flag11)
{
goto IL_2DB;
}
IL_2D1:
num2 = 42;
text6 = "6";
IL_2DB:
num2 = 43;
bool flag12 = Operators.CompareString(text6, "H", true) == 0;
if (!flag12)
{
goto IL_2FE;
}
IL_2F4:
num2 = 44;
text6 = "7";
IL_2FE:
num2 = 45;
bool flag13 = Operators.CompareString(text6, "J", true) == 0;
if (!flag13)
{
goto IL_321;
}
IL_317:
num2 = 46;
text6 = "8";
IL_321:
num2 = 47;
bool flag14 = Operators.CompareString(text6, "K", true) == 0;
if (!flag14)
{
goto IL_344;
}
IL_33A:
num2 = 48;
text6 = "9";
IL_344:
num2 = 49;
string value = "20" + text5 + text6;
IL_357:
num2 = 50;
bool flag15 = Operators.CompareString(text7, "6", true) == 0 | Operators.CompareString(text7, "7", true) == 0 | Operators.CompareString(text7, "B", true) == 0;
if (!flag15)
{
goto IL_39C;
}
IL_392:
num2 = 51;
text7 = "1";
IL_39C:
num2 = 52;
bool flag16 = Operators.CompareString(text7, "4", true) == 0 | Operators.CompareString(text7, "5", true) == 0 | Operators.CompareString(text7, "A", true) == 0;
if (!flag16)
{
goto IL_3E1;
}
IL_3D7:
num2 = 53;
text7 = "0";
IL_3E1:
num2 = 54;
bool flag17 = Operators.CompareString(text8, "A", true) == 0;
if (!flag17)
{
goto IL_404;
}
IL_3FA:
num2 = 55;
text8 = "0";
IL_404:
num2 = 56;
bool flag18 = Operators.CompareString(text8, "B", true) == 0;
if (!flag18)
{
goto IL_427;
}
IL_41D:
num2 = 57;
text8 = "1";
IL_427:
num2 = 58;
bool flag19 = Operators.CompareString(text8, "C", true) == 0;
if (!flag19)
{
goto IL_44A;
}
IL_440:
num2 = 59;
text8 = "2";
IL_44A:
num2 = 60;
bool flag20 = Operators.CompareString(text8, "D", true) == 0;
if (!flag20)
{
goto IL_46D;
}
IL_463:
num2 = 61;
text8 = "3";
IL_46D:
num2 = 62;
bool flag21 = Operators.CompareString(text8, "E", true) == 0;
if (!flag21)
{
goto IL_490;
}
IL_486:
num2 = 63;
text8 = "4";
IL_490:
num2 = 64;
bool flag22 = Operators.CompareString(text8, "F", true) == 0;
if (!flag22)
{
goto IL_4B3;
}
IL_4A9:
num2 = 65;
text8 = "5";
IL_4B3:
num2 = 66;
bool flag23 = Operators.CompareString(text8, "G", true) == 0;
if (!flag23)
{
goto IL_4D6;
}
IL_4CC:
num2 = 67;
text8 = "6";
IL_4D6:
num2 = 68;
bool flag24 = Operators.CompareString(text8, "H", true) == 0;
if (!flag24)
{
goto IL_4F9;
}
IL_4EF:
num2 = 69;
text8 = "7";
IL_4F9:
num2 = 70;
bool flag25 = Operators.CompareString(text8, "J", true) == 0;
if (!flag25)
{
goto IL_51C;
}
IL_512:
num2 = 71;
text8 = "8";
IL_51C:
num2 = 72;
bool flag26 = Operators.CompareString(text8, "K", true) == 0;
if (!flag26)
{
goto IL_53F;
}
IL_535:
num2 = 73;
text8 = "9";
IL_53F:
num2 = 74;
string value2 = text7 + text8;
IL_54D:
num2 = 75;
bool flag27 = Operators.CompareString(text9, "A", true) == 0;
if (!flag27)
{
goto IL_570;
}
IL_566:
num2 = 76;
text9 = "0";
IL_570:
num2 = 77;
bool flag28 = Operators.CompareString(text9, "B", true) == 0;
if (!flag28)
{
goto IL_593;
}
IL_589:
num2 = 78;
text9 = "1";
IL_593:
num2 = 79;
bool flag29 = Operators.CompareString(text9, "C", true) == 0;
if (!flag29)
{
goto IL_5B6;
}
IL_5AC:
num2 = 80;
text9 = "2";
IL_5B6:
num2 = 81;
string value3 = text9 + str2;
IL_5C4:
num2 = 82;
[C#] 纯文本查看 复制代码 int num3 = Conversions.ToInteger(value);
IL_663:
num2 = 88;
int num4 = Conversions.ToInteger(value2);
IL_66F:
num2 = 89;
int num5 = Conversions.ToInteger(value3);
IL_67B:
num2 = 90;
bool flag32 = num5 < 1 | num5 > 28 | num3 < 2013 | num3 > 2030 | num4 < 1 | num4 > 12 | num3 < DateAndTime.Now.Year | (num3 == DateAndTime.Now.Year & num4 < DateAndTime.Now.Month);
if (!flag32)
{
goto IL_704;
}
IL_6EA:
num2 = 91;
this.m().Text = "注册码不对!";
[C#] 纯文本查看 复制代码 bool flag36 = aa.a(ref text2, ref text4) & !File.Exists(ac.j + "\\syspbaz730.dll");
if (!flag36)
{
IL_837:
num2 = 111;
this.m().Text = "注册码不对!";
IL_84B:
goto IL_84C;
}
IL_7CB:
num2 = 106;
c.e().Registry.SetValue("HKEY_CURRENT_USER\\Software\\NanfangSoft .net\\PaiBazi730", "Name", this.n().Text);
IL_7F3:
num2 = 107;
string text10 = Strings.UCase(text4);
ac.a(ref text2, ref text10, ref value, ref value2, ref value3);
IL_80F:
num2 = 108;
ac.l = true;
IL_818:
num2 = 109;
this.m().Text = "注册成功!点击'退出'。" + str;
IL_833:
IL_84C:
IL_84D:
goto IL_84E;
通过这3段的代码,一点点的跟踪,我们知道了以下几个信息,这个程序的注册验证过程分为2个步骤。
2.2.1、根据注册码中的第5、6、7、8、13、14位来计算出授权日期,这个日期要在2030年12月份以内,并且大于当前日期。
其中:5/6位拼接年份数据的后2位,然后和20拼接;7/8位拼接月份、13/14位拼接日子数据,第15位应该算是校验位,没发现有啥用。
举例:以第5、6位为例子详解,第5位只能取6、7、B、8、9、C这6个字符,如果是6、7、B则返回1,8、9、C返回2,第
6位只能取A/B/C/D/E/F/G/H/I/K这10个字符,分别对应0-9,
如果假码我们输入:1234CKBA1234B81,
小结:这个假码,开始的时候是用123456789012345来试的,然后又参照程序的代码,大致分析出来每一位表示什么意思,这
个过程,有时不是一下子就能看清,特别是刚刚接触的小白,都是反复的试验。幸好我们所用的工具可以随时跟踪显示变量的值。
让我们可以看见代码执行后,是不是我们想要的,在这里,.net的反汇编出来的内容和OD反汇编出来的可读性要好很多,OD里面
的汇编代码是真心的看不懂,只能根据/jnz/jz /je、test之类的硬猜。
对应下面的表,我们可以计算出注册码的第一部分日期授权的数据。
5、6位查表可知年份日期为2029年,7、8位对应的是10月份、13、14位的日期是18号,上面的注册码计算出的授权日期是:2029-10-18日。
注册码授权日期对应计算表。
2.2.2、取机器码的前10位,后5位进行一系列的计算后生成一个8位的码,要和注册码的1-4位与9-12位拼接的8位相等,即注册成功。
得出上面2个结论,花了相当多的时间,这个幸好有Dnspy这工具,可以动态的来调试程序,让我这样的初入门的小白,可以边调试
、边猜测语句的意思,然后用运行结果来验证猜测。在没有一个可以商量的同伴,只有这样摸索的前行。
3、机器码计算部分
经过前面的这一段分析,信心满满,就继续往后走,见下图,从下面的代码往后不远处,有一个Flag36的标志位,那里就是计算机器
码的关键部分,在Dnspy反汇编出来的方法是aa.a(这名字,看着都恶心,应该就是混淆后的结果,下午找资料用De4dot去混淆,提示成功
却又变成Class+数字的形式,还没现在这样看着舒服,有大神看到这,回帖指点一下。),这个位置的关键点是,要用鼠标点击那个aa.a
向更深入的函数进军。
从这个aa.a单击跟进后,仔细的阅读代码,凡是遇见有判断,要越过的地方,就相应的进去,在这里有一点要注意的是,就是观察Dnspy下方的局部变量窗口
凡是我认为挺重要的地方,我红色大字号标出来,新人会有用的,通过观察各个变量的值,有助于我们了解程序的代码计算过程,帮助我们推测和验证我们的猜想。
在这里接着点y.a进行核心算法。
[C#] 纯文本查看 复制代码 public static bool a(ref string A_0, ref string A_1)
{
bool flag = Operators.CompareString(A_0, "", true) == 0 | Operators.CompareString(A_1, "", true) == 0;
bool result;
if (flag)
{
result = false;
}
else
{
global::y.a(ref A_0);
bool flag2 = Operators.CompareString(Strings.UCase(global::y.c), Strings.UCase(A_1), true) == 0;
if (flag2)
{
global::y.c = "a@^*(^*ga$(&%io";
result = true;
}
else
{
result = false;
}
}
return result;
在机器码计算这一部分,又大致分了三个过程,分别是y.a、x.a、y.b,这里仍然要跟踪进去,进行详细的分析。
2.3.1、y.a过程:
将20位机器码取前10、后5拼接成15位,然后通过位移、逻辑运算,取右边的6位,用于第2步计算。
2.3.2、x.a过程:
第1步传过来的数据,通过计算(在这里我跟丢了,转晕了,看不太明白,想过将代码直接利用,但是没有成功,可能里面有
自定义的函数,或者是引用的命名空间,不是太懂这些。在这里希望能得到高人的指点。),依据2.3.1的值计算出32位长的字符
2.3.3、y.b过程:
将2.3.2计算出的32位的值,分别从6、8、14、12、17、9位截取2位拼接出一个12位长度的字符。对这12位字符进行循环,继续
在7、5、11、9位取2位数字拼接成最终的结果。
[C#] 纯文本查看 复制代码 public static string a(ref string A_0)
{
x.d[0] = 1;
x.d[1] = 3;
x.d[2] = 7;
x.d[3] = 15;
x.d[4] = 31;
x.d[5] = 63;
x.d[6] = 127;
x.d[7] = 255;
x.d[8] = 511;
x.d[9] = 1023;
x.d[10] = 2047;
x.d[11] = 4095;
x.d[12] = 8191;
x.d[13] = 16383;
x.d[14] = 32767;
x.d[15] = 65535;
x.d[16] = 131071;
x.d[17] = 262143;
x.d[18] = 524287;
x.d[19] = 1048575;
x.d[20] = 2097151;
x.d[21] = 4194303;
x.d[22] = 8388607;
x.d[23] = 16777215;
x.d[24] = 33554431;
x.d[25] = 67108863;
x.d[26] = 134217727;
x.d[27] = 268435455;
x.d[28] = 536870911;
x.d[29] = 1073741823;
x.d[30] = 2147483647;
x.e[0] = 1;
x.e[1] = 2;
x.e[2] = 4;
x.e[3] = 8;
x.e[4] = 16;
x.e[5] = 32;
x.e[6] = 64;
x.e[7] = 128;
x.e[8] = 256;
x.e[9] = 512;
x.e[10] = 1024;
x.e[11] = 2048;
x.e[12] = 4096;
x.e[13] = 8192;
x.e[14] = 16384;
x.e[15] = 32768;
x.e[16] = 65536;
x.e[17] = 131072;
x.e[18] = 262144;
x.e[19] = 524288;
x.e[20] = 1048576;
x.e[21] = 2097152;
x.e[22] = 4194304;
x.e[23] = 8388608;
x.e[24] = 16777216;
x.e[25] = 33554432;
x.e[26] = 67108864;
x.e[27] = 134217728;
x.e[28] = 268435456;
x.e[29] = 536870912;
x.e[30] = 1073741824;
object value = A_0;
object arg_42E_0 = x.c(ref value);
A_0 = Conversions.ToString(value);
object[] array = (object[])arg_42E_0;
object obj = 1732584193;
object obj2 = -271733879;
object obj3 = -1732584194;
object obj4 = 271733878;
object obj5;
object loopObj;
bool flag = ObjectFlowControl.ForLoopControl.ForLoopInitObj(obj5, 0, Information.UBound(array, 1), 16, ref loopObj, ref obj5);
if (flag)
{
do
{
object objectValue = RuntimeHelpers.GetObjectValue(obj);
object objectValue2 = RuntimeHelpers.GetObjectValue(obj2);
object objectValue3 = RuntimeHelpers.GetObjectValue(obj3);
object objectValue4 = RuntimeHelpers.GetObjectValue(obj4);
object[] arg_4EA_4_cp_0 = array;
int arg_4EA_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 0));
value = 7;
object obj6 = -680876936;
x.d(ref obj, ref obj2, ref obj3, ref obj4, ref arg_4EA_4_cp_0[arg_4EA_4_cp_1], ref value, ref obj6);
object[] arg_528_4_cp_0 = array;
int arg_528_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 1));
obj6 = 12;
value = -389564586;
x.d(ref obj4, ref obj, ref obj2, ref obj3, ref arg_528_4_cp_0[arg_528_4_cp_1], ref obj6, ref value);
object[] arg_566_4_cp_0 = array;
int arg_566_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 2));
value = 17;
obj6 = 606105819;
x.d(ref obj3, ref obj4, ref obj, ref obj2, ref arg_566_4_cp_0[arg_566_4_cp_1], ref value, ref obj6);
object[] arg_5A4_4_cp_0 = array;
int arg_5A4_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 3));
obj6 = 22;
value = -1044525330;
x.d(ref obj2, ref obj3, ref obj4, ref obj, ref arg_5A4_4_cp_0[arg_5A4_4_cp_1], ref obj6, ref value);
object[] arg_5E1_4_cp_0 = array;
int arg_5E1_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 4));
value = 7;
obj6 = -176418897;
x.d(ref obj, ref obj2, ref obj3, ref obj4, ref arg_5E1_4_cp_0[arg_5E1_4_cp_1], ref value, ref obj6);
object[] arg_61F_4_cp_0 = array;
int arg_61F_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 5));
obj6 = 12;
value = 1200080426;
x.d(ref obj4, ref obj, ref obj2, ref obj3, ref arg_61F_4_cp_0[arg_61F_4_cp_1], ref obj6, ref value);
object[] arg_65D_4_cp_0 = array;
int arg_65D_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 6));
value = 17;
obj6 = -1473231341;
x.d(ref obj3, ref obj4, ref obj, ref obj2, ref arg_65D_4_cp_0[arg_65D_4_cp_1], ref value, ref obj6);
object[] arg_69B_4_cp_0 = array;
int arg_69B_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 7));
obj6 = 22;
value = -45705983;
x.d(ref obj2, ref obj3, ref obj4, ref obj, ref arg_69B_4_cp_0[arg_69B_4_cp_1], ref obj6, ref value);
object[] arg_6D8_4_cp_0 = array;
int arg_6D8_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 8));
value = 7;
obj6 = 1770035416;
x.d(ref obj, ref obj2, ref obj3, ref obj4, ref arg_6D8_4_cp_0[arg_6D8_4_cp_1], ref value, ref obj6);
object[] arg_717_4_cp_0 = array;
int arg_717_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 9));
obj6 = 12;
value = -1958414417;
x.d(ref obj4, ref obj, ref obj2, ref obj3, ref arg_717_4_cp_0[arg_717_4_cp_1], ref obj6, ref value);
object[] arg_756_4_cp_0 = array;
int arg_756_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 10));
value = 17;
obj6 = -42063;
x.d(ref obj3, ref obj4, ref obj, ref obj2, ref arg_756_4_cp_0[arg_756_4_cp_1], ref value, ref obj6);
object[] arg_795_4_cp_0 = array;
int arg_795_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 11));
obj6 = 22;
value = -1990404162;
x.d(ref obj2, ref obj3, ref obj4, ref obj, ref arg_795_4_cp_0[arg_795_4_cp_1], ref obj6, ref value);
object[] arg_7D3_4_cp_0 = array;
int arg_7D3_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 12));
value = 7;
obj6 = 1804603682;
x.d(ref obj, ref obj2, ref obj3, ref obj4, ref arg_7D3_4_cp_0[arg_7D3_4_cp_1], ref value, ref obj6);
object[] arg_812_4_cp_0 = array;
int arg_812_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 13));
obj6 = 12;
value = -40341101;
x.d(ref obj4, ref obj, ref obj2, ref obj3, ref arg_812_4_cp_0[arg_812_4_cp_1], ref obj6, ref value);
object[] arg_851_4_cp_0 = array;
int arg_851_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 14));
value = 17;
obj6 = -1502002290;
x.d(ref obj3, ref obj4, ref obj, ref obj2, ref arg_851_4_cp_0[arg_851_4_cp_1], ref value, ref obj6);
object[] arg_890_4_cp_0 = array;
int arg_890_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 15));
obj6 = 22;
value = 1236535329;
x.d(ref obj2, ref obj3, ref obj4, ref obj, ref arg_890_4_cp_0[arg_890_4_cp_1], ref obj6, ref value);
object[] arg_8CD_4_cp_0 = array;
int arg_8CD_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 1));
value = 5;
obj6 = -165796510;
x.c(ref obj, ref obj2, ref obj3, ref obj4, ref arg_8CD_4_cp_0[arg_8CD_4_cp_1], ref value, ref obj6);
object[] arg_90B_4_cp_0 = array;
int arg_90B_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 6));
obj6 = 9;
value = -1069501632;
x.c(ref obj4, ref obj, ref obj2, ref obj3, ref arg_90B_4_cp_0[arg_90B_4_cp_1], ref obj6, ref value);
object[] arg_94A_4_cp_0 = array;
int arg_94A_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 11));
value = 14;
obj6 = 643717713;
x.c(ref obj3, ref obj4, ref obj, ref obj2, ref arg_94A_4_cp_0[arg_94A_4_cp_1], ref value, ref obj6);
object[] arg_988_4_cp_0 = array;
int arg_988_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 0));
obj6 = 20;
value = -373897302;
x.c(ref obj2, ref obj3, ref obj4, ref obj, ref arg_988_4_cp_0[arg_988_4_cp_1], ref obj6, ref value);
object[] arg_9C5_4_cp_0 = array;
int arg_9C5_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 5));
value = 5;
obj6 = -701558691;
x.c(ref obj, ref obj2, ref obj3, ref obj4, ref arg_9C5_4_cp_0[arg_9C5_4_cp_1], ref value, ref obj6);
object[] arg_A04_4_cp_0 = array;
int arg_A04_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 10));
obj6 = 9;
value = 38016083;
x.c(ref obj4, ref obj, ref obj2, ref obj3, ref arg_A04_4_cp_0[arg_A04_4_cp_1], ref obj6, ref value);
object[] arg_A43_4_cp_0 = array;
int arg_A43_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 15));
value = 14;
obj6 = -660478335;
x.c(ref obj3, ref obj4, ref obj, ref obj2, ref arg_A43_4_cp_0[arg_A43_4_cp_1], ref value, ref obj6);
object[] arg_A81_4_cp_0 = array;
int arg_A81_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 4));
obj6 = 20;
value = -405537848;
x.c(ref obj2, ref obj3, ref obj4, ref obj, ref arg_A81_4_cp_0[arg_A81_4_cp_1], ref obj6, ref value);
object[] arg_ABF_4_cp_0 = array;
int arg_ABF_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 9));
value = 5;
obj6 = 568446438;
x.c(ref obj, ref obj2, ref obj3, ref obj4, ref arg_ABF_4_cp_0[arg_ABF_4_cp_1], ref value, ref obj6);
object[] arg_AFE_4_cp_0 = array;
int arg_AFE_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 14));
obj6 = 9;
value = -1019803690;
x.c(ref obj4, ref obj, ref obj2, ref obj3, ref arg_AFE_4_cp_0[arg_AFE_4_cp_1], ref obj6, ref value);
object[] arg_B3C_4_cp_0 = array;
int arg_B3C_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 3));
value = 14;
obj6 = -187363961;
x.c(ref obj3, ref obj4, ref obj, ref obj2, ref arg_B3C_4_cp_0[arg_B3C_4_cp_1], ref value, ref obj6);
object[] arg_B7A_4_cp_0 = array;
int arg_B7A_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 8));
obj6 = 20;
value = 1163531501;
x.c(ref obj2, ref obj3, ref obj4, ref obj, ref arg_B7A_4_cp_0[arg_B7A_4_cp_1], ref obj6, ref value);
object[] arg_BB8_4_cp_0 = array;
int arg_BB8_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 13));
value = 5;
obj6 = -1444681467;
x.c(ref obj, ref obj2, ref obj3, ref obj4, ref arg_BB8_4_cp_0[arg_BB8_4_cp_1], ref value, ref obj6);
object[] arg_BF6_4_cp_0 = array;
int arg_BF6_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 2));
obj6 = 9;
value = -51403784;
x.c(ref obj4, ref obj, ref obj2, ref obj3, ref arg_BF6_4_cp_0[arg_BF6_4_cp_1], ref obj6, ref value);
object[] arg_C34_4_cp_0 = array;
int arg_C34_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 7));
value = 14;
obj6 = 1735328473;
x.c(ref obj3, ref obj4, ref obj, ref obj2, ref arg_C34_4_cp_0[arg_C34_4_cp_1], ref value, ref obj6);
object[] arg_C73_4_cp_0 = array;
int arg_C73_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 12));
obj6 = 20;
value = -1926607734;
x.c(ref obj2, ref obj3, ref obj4, ref obj, ref arg_C73_4_cp_0[arg_C73_4_cp_1], ref obj6, ref value);
object[] arg_CB0_4_cp_0 = array;
int arg_CB0_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 5));
value = 4;
obj6 = -378558;
x.b(ref obj, ref obj2, ref obj3, ref obj4, ref arg_CB0_4_cp_0[arg_CB0_4_cp_1], ref value, ref obj6);
object[] arg_CEE_4_cp_0 = array;
int arg_CEE_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 8));
obj6 = 11;
value = -2022574463;
x.b(ref obj4, ref obj, ref obj2, ref obj3, ref arg_CEE_4_cp_0[arg_CEE_4_cp_1], ref obj6, ref value);
object[] arg_D2D_4_cp_0 = array;
int arg_D2D_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 11));
value = 16;
obj6 = 1839030562;
x.b(ref obj3, ref obj4, ref obj, ref obj2, ref arg_D2D_4_cp_0[arg_D2D_4_cp_1], ref value, ref obj6);
object[] arg_D6C_4_cp_0 = array;
int arg_D6C_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 14));
obj6 = 23;
value = -35309556;
x.b(ref obj2, ref obj3, ref obj4, ref obj, ref arg_D6C_4_cp_0[arg_D6C_4_cp_1], ref obj6, ref value);
object[] arg_DA9_4_cp_0 = array;
int arg_DA9_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 1));
value = 4;
obj6 = -1530992060;
x.b(ref obj, ref obj2, ref obj3, ref obj4, ref arg_DA9_4_cp_0[arg_DA9_4_cp_1], ref value, ref obj6);
object[] arg_DE7_4_cp_0 = array;
int arg_DE7_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 4));
obj6 = 11;
value = 1272893353;
x.b(ref obj4, ref obj, ref obj2, ref obj3, ref arg_DE7_4_cp_0[arg_DE7_4_cp_1], ref obj6, ref value);
object[] arg_E25_4_cp_0 = array;
int arg_E25_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 7));
value = 16;
obj6 = -155497632;
x.b(ref obj3, ref obj4, ref obj, ref obj2, ref arg_E25_4_cp_0[arg_E25_4_cp_1], ref value, ref obj6);
object[] arg_E64_4_cp_0 = array;
int arg_E64_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 10));
obj6 = 23;
value = -1094730640;
x.b(ref obj2, ref obj3, ref obj4, ref obj, ref arg_E64_4_cp_0[arg_E64_4_cp_1], ref obj6, ref value);
object[] arg_EA2_4_cp_0 = array;
int arg_EA2_4_cp_1 = Conversions.ToInteger(Operators.AddObject(obj5, 13));
value = 4;
obj6 = 681279174;
y.a过程计算出第一步注册码,6位数字 818768
x.a过程,通过818768,计算出第2过程的注册码,32位长度:EFE1499CED0B97FE91CFCBB71E0F2C98
这个过程太过于复杂,没有看明白,只能略过去了。
(备注:整体的计算过程如此,由于之前破解的时候,已经把软件注册了,这个是刚安装的虚拟机,在里面计算出来的,机器码
是:67154-29574-61760-40730,最终计算出来的注册为:2TTUCKBA2181B81)
y.b过程:此过程是通过上面的步骤计算出来的字符串,通过循环计算、取ASC码,再间隔取位拼接出最终的8位值:2TTU2181
排八字注册流程
这是该软件的整个注册流程示意。
小结:能从头一步一步看到这里,如果还能跟着动手实践过来,那么这款软件,或者同同样类型的软件,我们就可以尝试着来破解了。
我们回过头来,在从新看一下过程,
软件查壳---->(如有De4dot去混淆)----->扔进Dnspy进行动态分析----->依据注册提示搜索关键字(注册、注册错误等提示信息)
---->根据找到的方法或者函数或者调用,单步跟踪---->观察局部变量窗口,注意其中的每个值----->遇到关键的调用,F11步进跟踪
或者Ctrl+鼠标单击调用开新窗口跟踪过去。--->能到这里,基本上可以有80%的可能性找到注册码。余下的就是耐心和不断遇到新问题,
遇新问题,多多论坛搜索或者百度。
至此,已经完成整个注册过程的分析,虽然很短,也可能讲的不太明白。但是对于一个新入门的小白来说,已经是很不容易了。
也希望得到更多的坛友与大神的帮助,共同成长。
三、最后的最后
由于算法中关于机器码的第2个步骤没有看懂,太过冗长与复杂,只能选择先爆破,还做不出注册机来。只能先做个爆破的版本,给
坛友使用。
最后附上爆破的主程序地址:http://pan.baidu.com/s/1mimIAIO
[C#] 纯文本查看 复制代码 catch (Exception exception1)
{
ProjectData.SetProjectError(exception1);
Exception exception = exception1;
ProjectData.ClearProjectError();
}
if (Operators.CompareString(y.b, right, true) <= 0)
{
y.a(ref right);
if (Operators.CompareString(left, y.c, true) == 0)
{
y.c = "a@^*(^*ga$(&%io";
return true;
}
}
return false;
}
return false;
}
编辑了好长好长时间,那个将word中粘贴过来的功能好像不太好用。不知道编辑出来的效果好不好。
编辑完看了一下,图片的顺序好像有点乱,最后面还多出一张,重新编辑,还看不到。大家对付看吧,
有不明白的地方,可以留言,我看见了会回复,也可以一起来学习,更希望得到大神的指点。
总结:;
1、通过本次的破解体验,基本上掌握和了解了.net破解的流程与使用的工具。其中大爱Scan id/Dot net id用来查壳,De4dot脱壳,
Dnspy动态调试追码,Reflector+Reflexi爆破。本次调试由于软件可以看出反汇编的代码,没有用De4dot反混淆。这个软件的使用
相对简单,在cmd模式下,执行 de4dot 空格 待反混淆软件名称 回车就OK,我看他们有带/df参数的,结果都报错,直接de4dot
加软件的路径名称就可以脱掉。但是它们说DN Guard这种干不掉,好像是个强壳。
2、了解了.net的混淆、反混淆、强命名、命名空间等的一些概念,如果能会一些编程语言,对调试程序有很多益处,哪怕只有一点点。
知道一些基础语法,对于逆向调试的软件整个流程的逻辑结构会有个大致的掌握。
3、软件的注册机制,个人感觉绝大部分或者全部,都应该会在软件内有一个验证机制,也就是在软件内部一定会有注册码的计算过程。
通过跟踪到特定的领空,就可以把码拿出来。(也可能会有网络验证的那种,读取到注册码,直接服务器比对,来验证软件的授权情况,
不过针对这种情况,也可以处理,就是跟踪到验证的部位,直接修改代码的返回值,还和爆破差不多。),在这里就是思考注册的流程
然后想不同的办法来对付它。
能想到的就这些,寻求逆向的小伙伴一起上路。
|