160个CrackMe之123

来源:互联网 发布:二维动漫制作软件 编辑:程序博客网 时间:2024/06/05 21:02

我并不是大神,所以哪里写的不对,还请各位大佬们指出来。

0x0 分析算法
OD载入,搜索字符串,发现关键函数0x004013C0,给这个函数下断点,然后随便输入一串注册码,程序成功断下。

首先,程序将字符串”ABCDEFGHIJKLMNOPQRSTUVWXYZ”拷贝到一个新的地址处

00401421    B9 06000000     mov     ecx, 0x600401426    BE 4C304000     mov     esi, 0040304C                               ; ABCDEFGHIJKLMNOPQRSTUVWXYZ0040142B    8D7C24 24       lea     edi, dword ptr [esp+0x24]0040142F    8D4424 14       lea     eax, dword ptr [esp+0x14]00401433    F3:A5           rep     movs dword ptr es:[edi], dword ptr [esi]00401435    66:A5           movs    word ptr es:[edi], word ptr [esi]

然后取出Code和Serial

00401437    50              push    eax00401438    68 EA030000     push    0x3EA0040143D    8BCD            mov     ecx, ebp0040143F    C64424 50 04    mov     byte ptr [esp+0x50], 0x400401444    A4              movs    byte ptr es:[edi], byte ptr [esi]00401445    E8 0A030000     call    <jmp.&MFC42.#3097>                          ; 取出Code0040144A    8D4C24 10       lea     ecx, dword ptr [esp+0x10]0040144E    51              push    ecx0040144F    68 E9030000     push    0x3E900401454    8BCD            mov     ecx, ebp00401456    E8 F9020000     call    <jmp.&MFC42.#3097>                          ; 取出Serial

然后用sscanf函数将Serial转换成整数

0040145B    8B4424 10       mov     eax, dword ptr [esp+0x10]0040145F    8D5424 18       lea     edx, dword ptr [esp+0x18]00401463    52              push    edx                                         ; Serial的整数形式00401464    68 48304000     push    00403048                                    ; %d00401469    50              push    eax                                         ; Serial0040146A    FF15 84214000   call    dword ptr [<&MSVCRT.sscanf>]                ; msvcrt.sscanf

然后程序用srand函数设置一个随机数种子,种子值就是Serial的整数形式。

00401470    8B4C24 24       mov     ecx, dword ptr [esp+0x24]                   ; Serial的整数形式00401474    51              push    ecx                                         ; Serial的整数形式00401475    FF15 B0214000   call    dword ptr [<&MSVCRT.srand>]                 ; msvcrt.srand

然后调用rand函数,将rand函数返回的随机数除以0x1A,用余数取出”ABCDEFGHIJKLMNOPQRSTUVWXYZ”中的一个字符,一共进行12次。

0040147B    8B3D B8214000   mov     edi, dword ptr [<&MSVCRT.rand>]             ; msvcrt.rand00401481    83C4 10         add     esp, 0x1000401484    BE 0C000000     mov     esi, 0xC00401489    FFD7            call    edi0040148B    99              cdq0040148C    B9 1A000000     mov     ecx, 0x1A00401491    F7F9            idiv    ecx00401493    8D4C24 0C       lea     ecx, dword ptr [esp+0xC]00401497    8A5414 24       mov     dl, byte ptr [esp+edx+0x24]0040149B    52              push    edx0040149C    E8 AD020000     call    <jmp.&MFC42.#940>                           ; 转换成字符串004014A1    4E              dec     esi004014A2  ^ 75 E5           jnz     short 00401489

其中,Code所对应的每个余数如下:

int DATA[] = {0x13,0x12,0x12,0x5,0x13,0xC,0x4,0x19,0x3,0xF,0xA,0x12};

最后将转换成的字符串和Code比较,如果相等就成功,否则失败。

004014A4    8B4424 14       mov     eax, dword ptr [esp+0x14]004014A8    8B4C24 0C       mov     ecx, dword ptr [esp+0xC]004014AC    50              push    eax                                         ; Code004014AD    51              push    ecx004014AE    FF15 BC214000   call    dword ptr [<&MSVCRT._mbscmp>]               ; msvcrt._mbscmp004014B4    83C4 08         add     esp, 0x8004014B7    85C0            test    eax, eax004014B9    75 12           jnz     short 004014CD                              ; 失败则转移

0x1 计算注册码
首先看一下srand函数是如何实现的:
函数取出保存随机数种子的地址,然后将参数1(即种子值)保存进去。

7404CAB0 >  8BFF            mov     edi, edi7404CAB2    55              push    ebp7404CAB3    8BEC            mov     ebp, esp7404CAB5    E8 AAA20000     call    74056D647404CABA    8B4D 08         mov     ecx, dword ptr [ebp+0x8]         ; 取出种子值7404CABD    8948 14         mov     dword ptr [eax+0x14], ecx        ; 保存种子值7404CAC0    5D              pop     ebp7404CAC1    C3              retn

然后再看一下rand函数是如何实现的:
函数首先取出保存随机数种子的地址,然后取出种子值,进行如下运算:

Seed = Seed * 0x343FD + 0x269EC3

其中,Seed就是取出的种子值。
最后程序将Seed进行如下运算,返回结果,这个结果就是随机数。

Seed >> 0x10 & 0x7FFF

在程序中的代码如下:

7404CA80 >  E8 DFA20000     call    74056D647404CA85    6948 14 FD43030>imul    ecx, dword ptr [eax+0x14], 0x343FD7404CA8C    81C1 C39E2600   add     ecx, 0x269EC37404CA92    8948 14         mov     dword ptr [eax+0x14], ecx7404CA95    C1E9 10         shr     ecx, 0x107404CA98    81E1 FF7F0000   and     ecx, 0x7FFF7404CA9E    8BC1            mov     eax, ecx7404CAA0    C3              retn

因为程序中有进行模运算(即取余数),因此无法逆向,考虑枚举。
枚举代码如下:
这里写图片描述
运行结果如图所示:
这里写图片描述
放到CM中测试一下,可以通过。
这里写图片描述

全文完。

原创粉丝点击