一个注册机的破解

在分析报告的开始之前,这是我的MachineCode以及调试时采用的SerialNumber

一、 采用DestroyWindow方式进行破解。

此时MachineCode为9385C461

输入序列号12345678

点击Register,出现弹窗Bad



Ctrl+G,输入DestroyWindow.


,此处设置一个断点。

点击Ok。

此时来到


用F8,回到上一次函数调用。此时来到这里



向上翻没有发现什么特别的东西。于是再回到上一次函数调用。来到这里


我先前调用了004A4068,是破坏的。前面发现了一个je,并且跳开了中间的函数。有点可疑,于是在je前设置断点。

再次注册,发现依旧弹出了Bad。可见这个函数并没有什么特别的东西,还是在判断失败以后。所以直接离开这一块内容。再回到上级调用。此时来到


发现上面并没有跳开什么地方,于是继续回到上一级。此时来到



此时这个地方相当可疑。注意到直接跳开了我们断开的函数。

在这里我再次设置了一个断点,跑起来之后发现还是产生了错误,故继续下一级调用,此时来到


再回到上一级,来到



向上翻发现可疑点


image.png

发现jump跳开了函数。

设下断点。点击注册,发现没有弹出Bad,而是挺住了。同时,我令下处的跳转不实现,点击run。发现弹出了Good


image.png

image.png

那么我们就追究这个函数跳转的原因。观察



此时有


这个值为软盘指纹的值。

那么对函数上面代码进行分析。分析结果如下。


首先我们看到最后的一个异或

也就是[ebp-3C]^0x13572468 = Machine Code

同时我也查看了此时的ebp-3C指向的数据


第一步的逆向、

[ebp-3C] = Machine Code ^ 0x13572468.

代码如下


紧接着向上看,


关注到上面的这一系列代码。运行到004017BA,下面窗口定位到[ebp-3C]


image.png

发现如下情况



,也就是这一串似乎与我的12345678有点相像。

基于这个情况,我再向上找,找到了12345678的完整情况。


image.png

当我运行到004017A4时,ebp-3C处的数据如下


也就是说,在这中间,发生了什么事情,使得这一串发生了改变。但是有意思的是,123456并没有发生改变。

但是我们先前(在第一步的逆向之前)发现这一串数字是发生改变了的。

那么分析这call函数以后的代码。


此时,ebp指向原来78的位置,ebp+1指向56的位置。依次类推

按F7,56的情况发生了改变。

很容易可以明白,56的改变,发生于上一个函数。

此时我们对我图中俩红色之间的代码分析。

分析结果是,它将原来1234的顺序改为了1324。

由此我们可以得到

第二步的逆向、

先获得result的每一个位。取出其相应的十六进制表示,归到原来的位置中。


紧接着我们来分析56的情况。

进入函数


F7过后,在此时这个点时,eax出现了我们想要的56


此时情况如下

ecx = 8->(减去edx的2)à6->(edx赋值2)à2

ebx = eax(为56)向左移位6个。

eax向右移位2。

此处的2来自调用函数前的

image.png

此时万分注意,有一个非非非常重要的点

算术右移。

然后对结果进行或。

分析结果如下:

56位所代表的的8位中

x1x2x3x4y1y2y3y4

à y3y4x1x2x3x4y1y2

但是,y3y4并不一定是y3y4基于算术右移的可能性,有可能直接变成了11。故此位置有可能是任何值,这取决于X1的值,因为数量不多,就不分析X1了,直接给出所有可能结果。

第三步的逆向、

逆向,将其规规矩矩得到

y3y4x1x2x3x4y1y2

再将其进行


如果与11进行或的话,那么可以得到4个不同的结果。

如果与00进行或的话,那么可以password就是作为结果。(其他的意义不大)

———————————————————————————————————————

接下来分析78的情况。

传入ebp-3C地址,还有push1,以及al是78的得到。


image.png

紧接着我们来到了函数内部。


分析代码:

同样注意到


image.png

此处分析结果是

x1x2x3x4y1y2y3y4

à x2x3x4y1y2y3y4x1

有可能是跟1111111 x1进行或的。

假如和1111111x1进行或的话,就依次进行。密码有2^7种。我的代码不作分析。(罗列所有可能情况),实际取决于x1的结果。

所以得到

第四步的逆向、

image.png

#include 

#include 

int main()

{

 unsigned temp=0, password=0;

 unsigned result=0;

 unsigned Machine_Code=0;

 unsigned ch1=0, ch2=0, ch3=0, ch4=0;

 printf("请输入Machine Code\n");

 scanf("%xu", &Machine_Code);

 result = Machine_Code^(0x13572468);

 ch4 = result & (0x0FF);

 ch3 = (result>>8) & (0x0FF);

 ch2 = (result>>16) & (0x0FF);//24状态

 ch1 = (result>>24) & (0x0FF);//13状态

 password |= ((ch1&0x0F)<<20);//第三个十六进制归位

 password |= ( ((ch1&0x0F0)>>4) << 28);//第一个十六进制归位

 password |= ((ch2&0x0F)<<16);//第四个十六进制归位

 password |= ( ((ch2&0x0F0)>>4) << 24);//第二个十六进制归位

 unsigned password11 = 0;

 unsigned password21 = 0;

 unsigned password22 = 0;

 unsigned password23 = 0;

 unsigned password24 = 0;

 password |= (ch4>>1);//最后两位十六进制右移一位

 password |= (ch4&0x1)<<7;

/*

有两种情况,左移后把1弄没了,那么右移有两种情况,+0x80或者不加

*/

 password |= ((ch3>>6) + ( ((ch3&0x3F) << 2)) )<<8;//56两位十六进制,的78位放在12位上。

 password21 = (password&0x0FFFFFFFF);

 password22 = (password&0x0FFFFBFFF);

 password23 = (password&0x0FFFF3FFF);

 password24 = (password&0x0FFFF7FFF);

/*

如果和00或的话,原来的就是结果。

如果与11或的话,那两位必然就为11

此时有四个可能

*/   

 printf("注册码:Password = %x\n", password);

 printf("其他可能也OK的注册码如下:\n");

 /*printf("Password 1 = %x\n", password21);

 printf("Password 2 = %x\n", password22);

 printf("Password 3 = %x\n", password23);

 printf("Password 4 = %x\n", password24);

*/

 system("pause");

}

几个要点:

一、 在算术移位的情况下,可能出现并行的注册码(多个注册码都可以成功)。

我在代码中列出了一种类型。

二、跟踪分析的时候其实我还跟踪了关于将字符串转换成为普通的字符。本来以为是字符串比较,后来才发现是直接转化成十六位进制的比较。

三、找到调用的函数要逐个分析,不要一棍子打死。(这里有两种分析类型,险些出了岔子)。

你可能感兴趣的:(一个注册机的破解)