吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4622|回复: 2
收起左侧

[原创] 160个crackme 之152---The AntiXryst 的MD5注册分析和注册机实现

[复制链接]
solly 发表于 2019-4-8 21:43
本帖最后由 solly 于 2019-4-13 16:22 编辑

看看160个crackme集合大多数都在这里有教程,只有少数几个没有,选择了一个没有的试一下。
我选择了第152个,The AntiXryst,好象这个还没有教程,于是动手了。

这个程序在 CHM集合的列表中説是delphi编写的。先检查一下看看。
1.png
没检测到壳,省事不少。
2.png
有个RCDATA资源表,并含有一个TFORM1的资源,再通过UltraEdit看一下:
3.png
标准的Delphi程序第1节内容,是Delphi编写没有错了,通过 DeDeDark打开程序文件:
4.png
只有一个表单,而且只有一个事件 OnTimer,一看就是定时器事件,进入事件:
5.png
记住事件的起始地址:0x00457AF8。并记住一些delphi的系统调用,这些系统调用在OD中就不用去跟踪了。
启动OD,载入Crackme程序,直接右键”转到->表达式“,输入前面的地址:
6.png
来到 OnTimer 事件处理程序,先不下断,F9进入程序,输入一个用户名。
10.png
这个crackme的注册码通过一个checkbox矩陈来输入注册码。
回到OD下断,稍等一下OD就断下了程序,原来是通过定时器不停的来验证注册码。
7.png
下面是其汇编代码:
[Asm] 纯文本查看 复制代码
; 以下是 Timer 的事件处理函数
00457AF8  /.  55            push    ebp
00457AF9  |.  8BEC          mov     ebp, esp
00457AFB  |.  83C4 8C       add     esp, -74
00457AFE  |.  53            push    ebx
00457AFF  |.  56            push    esi
00457B00  |.  57            push    edi
00457B01  |.  33C9          xor     ecx, ecx
00457B03  |.  894D 8C       mov     dword ptr [ebp-74], ecx
00457B06  |.  894D F8       mov     dword ptr [ebp-8], ecx
00457B09  |.  8BD8          mov     ebx, eax
00457B0B  |.  33C0          xor     eax, eax
00457B0D  |.  55            push    ebp
00457B0E  |.  68 337C4500   push    00457C33                                    ;  SEH 地址
00457B13  |.  64:FF30       push    dword ptr fs:[eax]                          ;  保存上一个SEH地址
00457B16  |.  64:8920       mov     dword ptr fs:[eax], esp                     ;  设置当前SEH地址为 0x00457C33
00457B19  |.  8D55 F8       lea     edx, dword ptr [ebp-8]
00457B1C  |.  8B83 68040000 mov     eax, dword ptr [ebx+468]
00457B22  |.  E8 A9F4FDFF   call    00436FD0                                    ;  GetText,读取注册名
00457B27  |.  8D55 8C       lea     edx, dword ptr [ebp-74]
00457B2A  |.  8B45 F8       mov     eax, dword ptr [ebp-8]                      ;  eax==>注册名
00457B2D  |.  E8 16FBFAFF   call    00407648                                    ;  Delphi 函数:Trim()
00457B32  |.  837D 8C 00    cmp     dword ptr [ebp-74], 0                       ;  是否空串
00457B36  |.  0F84 D9000000 je      00457C15
00457B3C  |.  8D45 A0       lea     eax, dword ptr [ebp-60]
00457B3F  |.  E8 0CE9FFFF   call    00456450                                    ;  MD5初始化,4个DWORD引子
00457B44  |.  8B45 F8       mov     eax, dword ptr [ebp-8]                      ;  eax==>注册名
00457B47  |.  E8 8CBFFAFF   call    00403AD8                                    ;  取注册码名的长度
00457B4C  |.  83F8 40       cmp     eax, 40                                     ;  eax=注册码的长度
00457B4F  |.  7D 18         jge     short 00457B69                              ;  长度大于或等于0x40则跳过注册名复制加长
00457B51  |>  8D45 F8       /lea     eax, dword ptr [ebp-8]
00457B54  |.  8B55 F8       |mov     edx, dword ptr [ebp-8]                     ;  edx==>注册名
00457B57  |.  E8 84BFFAFF   |call    00403AE0                                   ;  复制用户名并连接成一个新串,regName = regName + regName
00457B5C  |.  8B45 F8       |mov     eax, dword ptr [ebp-8]                     ;  eax==>克隆后的注册名
00457B5F  |.  E8 74BFFAFF   |call    00403AD8                                   ;  重新计算长度
00457B64  |.  83F8 40       |cmp     eax, 40                                    ;  eax 由 5,10,20,40,80...递增
00457B67  |.^ 7E E8         \jle     short 00457B51
00457B69  |>  8B45 F8       mov     eax, dword ptr [ebp-8]
00457B6C  |.  E8 67BFFAFF   call    00403AD8                                    ;  最后取得克隆后的字符串长度
00457B71  |.  83F8 40       cmp     eax, 40                                     ;  eax==0x50==80
00457B74  |.  7E 24         jle     short 00457B9A                              ;  长度小于或等于则跳转
00457B76  |>  8B45 F8       /mov     eax, dword ptr [ebp-8]                     ;  eax==>克隆加长后的注册名
00457B79  |.  E8 5ABFFAFF   |call    00403AD8                                   ;  取长度
00457B7E  |.  8BD0          |mov     edx, eax
00457B80  |.  8D45 F8       |lea     eax, dword ptr [ebp-8]
00457B83  |.  B9 01000000   |mov     ecx, 1                                     ;  删除的字符数
00457B88  |.  E8 8FC1FAFF   |call    00403D1C                                   ;  删除注册名最后1个字符
00457B8D  |.  8B45 F8       |mov     eax, dword ptr [ebp-8]
00457B90  |.  E8 43BFFAFF   |call    00403AD8                                   ;  计算长度
00457B95  |.  83F8 40       |cmp     eax, 40                                    ;  是否长度为0x40
00457B98  |.^ 75 DC         \jnz     short 00457B76                             ;  不是0x40则继续去删除最后1个字符
00457B9A  |>  33D2          xor     edx, edx                                    ;  int i = 0
00457B9C  |.  8D45 B0       lea     eax, dword ptr [ebp-50]                     ;  指向字符串第0字节,即delphi短String类型的保存长度的位置
00457B9F  |>  8B4D F8       /mov     ecx, dword ptr [ebp-8]                     ;  ecx==>缩短后注册名,长度为0x40
00457BA2  |.  8A4C11 FF     |mov     cl, byte ptr [ecx+edx-1]                   ;  取string(i-1)位置字符, 第1次读取的字符为delphi字符串长度的高8位,为0
00457BA6  |.  8808          |mov     byte ptr [eax], cl                         ;  复制注册名,第1个字节为'\0',前面缩短的注册名最后1字节没有复制
00457BA8  |.  42            |inc     edx
00457BA9  |.  40            |inc     eax
00457BAA  |.  83FA 40       |cmp     edx, 40
00457BAD  |.^ 75 F0         \jnz     short 00457B9F
00457BAF  |.  8D55 A0       lea     edx, dword ptr [ebp-60]                     ;  edx==>MD5算法引子,0019FCD8:  01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10
00457BB2  |.  8D45 B0       lea     eax, dword ptr [ebp-50]                     ;  eax==>'\0' + 注册名前0x3F个字符
00457BB5  |.  E8 FEE8FFFF   call    004564B8                                    ;  MD5运算
00457BBA  |.  8D75 A0       lea     esi, dword ptr [ebp-60]                     ;  esi==>MD5计算后的值
00457BBD  |.  8D7D 90       lea     edi, dword ptr [ebp-70]
00457BC0  |.  B9 04000000   mov     ecx, 4
00457BC5  |.  F3:A5         rep     movs dword ptr es:[edi], dword ptr [esi]
00457BC7  |.  8D55 90       lea     edx, dword ptr [ebp-70]                     ;  edx==>前面MD5计算值,当作下一次的MD5引子
00457BCA  |.  8D45 B0       lea     eax, dword ptr [ebp-50]                     ;  eax==>'\0' + 注册名前0x3F个字符
00457BCD  |.  E8 E6E8FFFF   call    004564B8                                    ;  MD5运算
00457BD2  |.  8B45 A0       mov     eax, dword ptr [ebp-60]                     ;  EAX=MD5_1[0],即第1次计算后的MD5第1个整数
00457BD5  |.  2B45 A4       sub     eax, dword ptr [ebp-5C]                     ;  EAX=MD5_1[0] - MD5_1[1]
00457BD8  |.  2B45 A8       sub     eax, dword ptr [ebp-58]                     ;  EAX=MD5_1[0] - MD5_1[1] - MD5_1[2]
00457BDB  |.  0345 AC       add     eax, dword ptr [ebp-54]                     ;  EAX=MD5_1[0] - MD5_1[1] - MD5_1[2] + MD5_1[3]
00457BDE  |.  8945 A0       mov     dword ptr [ebp-60], eax                     ;  [EBP-60]=MD5_1[0] - MD5_1[1] - MD5_1[2] + MD5_1[3], 保存第1个SN整数
00457BE1  |.  8B45 90       mov     eax, dword ptr [ebp-70]                     ;  EAX=MD5_2[0],即第2次计算后的MD5第1个整数
00457BE4  |.  2B45 94       sub     eax, dword ptr [ebp-6C]                     ;  EAX=MD5_2[0] - MD5_2[1]
00457BE7  |.  2B45 98       sub     eax, dword ptr [ebp-68]                     ;  EAX=MD5_2[0] - MD5_2[1] - MD5_2[2]
00457BEA  |.  0345 9C       add     eax, dword ptr [ebp-64]                     ;  EAX=MD5_2[0] - MD5_2[1] - MD5_2[2] + MD5_2[3]
00457BED  |.  8945 90       mov     dword ptr [ebp-70], eax                     ;  [ebp-70]=MD5_2[0] - MD5_2[1] - MD5_2[2] + MD5_2[3],保存第2个SN整数
00457BF0  |.  8D55 F0       lea     edx, dword ptr [ebp-10]                     ;  eax,edx两个整数缓冲区,用来保存checkbox的状态
00457BF3  |.  8D45 F4       lea     eax, dword ptr [ebp-C]
00457BF6  |.  E8 B1F8FFFF   call    004574AC                                    ;  取 CheckBox 的状态,生成两个32位无符号数,过程简单统一,不深入解释了
00457BFB  |.  8B45 F0       mov     eax, dword ptr [ebp-10]                     ;  参数4,第2个checkbox状态值
00457BFE  |.  50            push    eax
00457BFF  |.  8B4D F4       mov     ecx, dword ptr [ebp-C]                      ;  参数3,第1个checkbox状态值
00457C02  |.  8B55 90       mov     edx, dword ptr [ebp-70]                     ;  参数2,第2个MD5计算值变形运算后的数值
00457C05  |.  8B45 A0       mov     eax, dword ptr [ebp-60]                     ;  参数1,第1个MD5运算值变形运算后的数值
00457C08  |.  E8 AFFEFFFF   call    00457ABC                                    ;  注册码比较调用,对比两组整数,不相等则用随机数取得一个索引地址
00457C0D  |.  8945 FC       mov     dword ptr [ebp-4], eax                ; eax 为上面调用通过查表返回的一个地址
00457C10  |.  8B45 FC       mov     eax, dword ptr [ebp-4]                ; eax为调用入口地址,注册不成功是地址范围 0x0045746C~004574A8 内的一个随机地址,成功则是 0x004573C8
00457C13  |.  FFD0          call    eax                                         ;  如果注册成功,则显示成功注册,不然就继续显示失败。
00457C15  |>  33C0          xor     eax, eax                                    ;  指示 SEH 头的索引
00457C17  |.  5A            pop     edx                                         ;  取保存的SEH地址
00457C18  |.  59            pop     ecx
00457C19  |.  59            pop     ecx
00457C1A  |.  64:8910       mov     dword ptr fs:[eax], edx                     ;  恢复SEH
00457C1D  |.  68 3A7C4500   push    00457C3A                                    ;  下面的 retn 返回地址
00457C22  |>  8D45 8C       lea     eax, dword ptr [ebp-74]
00457C25  |.  E8 32BCFAFF   call    0040385C                                    ;  Delphi 资源释放过程
00457C2A  |.  8D45 F8       lea     eax, dword ptr [ebp-8]
00457C2D  |.  E8 2ABCFAFF   call    0040385C                                    ;  Delphi 资源释放过程
00457C32  \.  C3            retn                                                ;  跳转到 0x00457C3A 
00457C33   .^ E9 E4B6FAFF   jmp     0040331C                                    ;  SEH 异常处理
00457C38   .^ EB E8         jmp     short 00457C22                              ;  SEH 处理完成后,跳回到这里
00457C3A   .  5F            pop     edi
00457C3B   .  5E            pop     esi
00457C3C   .  5B            pop     ebx
00457C3D   .  8BE5          mov     esp, ebp
00457C3F   .  5D            pop     ebp
00457C40   .  C3            retn

以上是主验证过程,其取得用户名,如果长度没有64个字符,就一直重复拼接直到超过64个字符,然后再截短为64个字符。
再进行MD5处理。不过,其传入的用户名在进行MD5处理时,只取了前63个字符填充在MD5输入缓冲区的后63字节中,而缓冲区第1个字符位置填充的是'\0'(这个在C/C++中就不好计算长度了,需要从第2个字符开始处理)。
这个生成的  '\0' + 重复注册名  字符串,进行两次 MD5处理,头一次是标准的,并且不需要padding填充。第二次直接用第一次的MD5码作为初始化引子,进行MD5计算。
下面是  MD 5 运算调用的过程,汇编代码太长,反正是一个标准过程,因此中间删除了一部分,免得显示得太长:
[Asm] 纯文本查看 复制代码
0045646C  /$  53            push    ebx
0045646D  |.  56            push    esi
0045646E  |.  57            push    edi
0045646F  |.  83C4 C0       add     esp, -40
00456472  |.  8BF0          mov     esi, eax
00456474  |.  8D3C24        lea     edi, dword ptr [esp]
00456477  |.  B9 10000000   mov     ecx, 10                                   ;  长度,16 * 4 字节
0045647C  |.  F3:A5         rep     movs dword ptr es:[edi], dword ptr [esi]  ;  一次移动4字节,一共移动16次
0045647E  |.  BB 10000000   mov     ebx, 10                                   ;  循环16次 int n = 16
00456483  |.  8BC4          mov     eax, esp
00456485  |.  8BCA          mov     ecx, edx
00456487  |>  0FB630        /movzx   esi, byte ptr [eax]                      ;  读取注册名第1个字符,第1个是'\0'
0045648A  |.  0FB678 01     |movzx   edi, byte ptr [eax+1]                    ;  读取注册名第2个字符,其实就是注册名的第1个字符
0045648E  |.  C1E7 08       |shl     edi, 8
00456491  |.  0BF7          |or      esi, edi
00456493  |.  0FB678 02     |movzx   edi, byte ptr [eax+2]                    ;  第3个
00456497  |.  C1E7 10       |shl     edi, 10
0045649A  |.  0BF7          |or      esi, edi
0045649C  |.  0FB678 03     |movzx   edi, byte ptr [eax+3]                    ;  第4个
004564A0  |.  C1E7 18       |shl     edi, 18
004564A3  |.  0BF7          |or      esi, edi
004564A5  |.  8931          |mov     dword ptr [ecx], esi                     ;  将每4字节一组转换成16进制数字保存
004564A7  |.  83C1 04       |add     ecx, 4
004564AA  |.  83C0 04       |add     eax, 4
004564AD  |.  4B            |dec     ebx                                      ;  n--
004564AE  |.^ 75 D7         \jnz     short 00456487                           ;  循环转换
004564B0  |.  83C4 40       add     esp, 40
004564B3  |.  5F            pop     edi
004564B4  |.  5E            pop     esi
004564B5  |.  5B            pop     ebx
004564B6  \.  C3            retn
004564B7      90            nop
004564B8  /$  55            push    ebp
004564B9  |.  8BEC          mov     ebp, esp
004564BB  |.  81C4 64FFFFFF add     esp, -9C
004564C1  |.  53            push    ebx
004564C2  |.  56            push    esi
004564C3  |.  57            push    edi
004564C4  |.  33C9          xor     ecx, ecx
004564C6  |.  894D E4       mov     dword ptr [ebp-1C], ecx                   ;  [ebp-1C] = 0
004564C9  |.  8BF0          mov     esi, eax                                  ;  esi==>'\0' + 注册名前0x3F字符
004564CB  |.  8D7D A4       lea     edi, dword ptr [ebp-5C]                   ;  edi=0x0019FC48
004564CE  |.  B9 10000000   mov     ecx, 10
004564D3  |.  F3:A5         rep     movs dword ptr es:[edi], dword ptr [esi]  ;  复制16*4字节注册名
004564D5  |.  8955 FC       mov     dword ptr [ebp-4], edx                    ;  [ebp-4]==>MD5引子
004564D8  |.  33C0          xor     eax, eax
004564DA  |.  55            push    ebp
004564DB  |.  68 B9734500   push    004573B9
004564E0  |.  64:FF30       push    dword ptr fs:[eax]
004564E3  |.  64:8920       mov     dword ptr fs:[eax], esp
004564E6  |.  8D95 64FFFFFF lea     edx, dword ptr [ebp-9C]
004564EC  |.  8D45 A4       lea     eax, dword ptr [ebp-5C]                   ;  eax==>注册名
004564EF  |.  E8 78FFFFFF   call    0045646C                                  ;  字符串复制,复制64字节
004564F4  |.  E8 13C3FAFF   call    0040280C                                  ;  随机数引子初始化,即当前时间的毫秒值
004564F9  |.  8B45 FC       mov     eax, dword ptr [ebp-4]                    ;  EAX==>MD5算法引子
004564FC  |.  8B00          mov     eax, dword ptr [eax]                      ;  eax=第1个整数,0x67452301
004564FE  |.  8945 F8       mov     dword ptr [ebp-8], eax
00456501  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
00456504  |.  8B40 04       mov     eax, dword ptr [eax+4]
00456507  |.  8945 F0       mov     dword ptr [ebp-10], eax
0045650A  |.  8B75 FC       mov     esi, dword ptr [ebp-4]
0045650D  |.  8B76 08       mov     esi, dword ptr [esi+8]
00456510  |.  8B5D FC       mov     ebx, dword ptr [ebp-4]
00456513  |.  8B5B 0C       mov     ebx, dword ptr [ebx+C]
00456516  |.  8B45 F0       mov     eax, dword ptr [ebp-10]
00456519  |.  8945 F4       mov     dword ptr [ebp-C], eax
0045651C  |.  8B7D F8       mov     edi, dword ptr [ebp-8]
0045651F  |.  8975 F8       mov     dword ptr [ebp-8], esi
00456522  |.  F755 F4       not     dword ptr [ebp-C]
00456525  |.  8B45 F0       mov     eax, dword ptr [ebp-10]
00456528  |.  2145 F8       and     dword ptr [ebp-8], eax
0045652B  |.  215D F4       and     dword ptr [ebp-C], ebx
0045652E  |.  8B45 F4       mov     eax, dword ptr [ebp-C]
00456531  |.  0945 F8       or      dword ptr [ebp-8], eax
00456534  |.  B8 65000000   mov     eax, 65
00456539  |.  E8 92C4FAFF   call    004029D0                                  ;  生成0~100的随机数
0045653E  |.  8B1485 F09245>mov     edx, dword ptr [eax*4+4592F0]             ;  查一个表(0~0x64)取地址,不过该表保存是同一个地址0x0045642C,该地址(edx)指向“MatrixxxMadness1 - UNREGISTERED!”
00456545  |.  8D45 E4       lea     eax, dword ptr [ebp-1C]                   ;  保存上面读取到的字符串地址
00456548  |.  E8 A7D3FAFF   call    004038F4                                  ;  保存地址到[eax]
0045654D  |.  8B85 64FFFFFF mov     eax, dword ptr [ebp-9C]
00456553  |.  8945 F4       mov     dword ptr [ebp-C], eax
00456556  |.  8B45 F4       mov     eax, dword ptr [ebp-C]
00456559  |.  0145 F8       add     dword ptr [ebp-8], eax
0045655C  |.  037D F8       add     edi, dword ptr [ebp-8]
0045655F  |.  81EF 885B9528 sub     edi, 28955B88                             ; MD5 标准写法是加法,因此这里实际上是 edi += 0xd76aa478
00456565  |.  897D F4       mov     dword ptr [ebp-C], edi
00456568  |.  8B45 F4       mov     eax, dword ptr [ebp-C]
0045656B  |.  8945 F8       mov     dword ptr [ebp-8], eax
0045656E  |.  C165 F8 07    shl     dword ptr [ebp-8], 7                      ;  左7右25,模拟循环左移7位
00456572  |.  C16D F4 19    shr     dword ptr [ebp-C], 19
00456576  |.  8B45 F4       mov     eax, dword ptr [ebp-C]
00456579  |.  0945 F8       or      dword ptr [ebp-8], eax
0045657C  |.  8B45 F0       mov     eax, dword ptr [ebp-10]
0045657F  |.  8945 F4       mov     dword ptr [ebp-C], eax
00456582  |.  8B45 F0       mov     eax, dword ptr [ebp-10]
00456585  |.  0145 F8       add     dword ptr [ebp-8], eax
00456588  |.  8B7D F8       mov     edi, dword ptr [ebp-8]
0045658B  |.  8B45 F8       mov     eax, dword ptr [ebp-8]
0045658E  |.  2145 F4       and     dword ptr [ebp-C], eax
00456591  |.  F7D7          not     edi
00456593  |.  23FE          and     edi, esi
00456595  |.  097D F4       or      dword ptr [ebp-C], edi
00456598  |.  8BBD 68FFFFFF mov     edi, dword ptr [ebp-98]
0045659E  |.  017D F4       add     dword ptr [ebp-C], edi
;
;此处省略n行汇编代码,都是MD5算法的代码
;
004572EC  |.  0375 F8       add     esi, dword ptr [ebp-8]
004572EF  |.  81C6 BBD2D72A add     esi, 2AD7D2BB
004572F5  |.  8B5D 88       mov     ebx, dword ptr [ebp-78]
004572F8  |.  8975 F8       mov     dword ptr [ebp-8], esi
004572FB  |.  C165 F8 0F    shl     dword ptr [ebp-8], 0F
004572FF  |.  C1EE 11       shr     esi, 11
00457302  |.  0975 F8       or      dword ptr [ebp-8], esi
00457305  |.  8BF7          mov     esi, edi
00457307  |.  8B45 F0       mov     eax, dword ptr [ebp-10]
0045730A  |.  0145 F8       add     dword ptr [ebp-8], eax
0045730D  |.  F7D6          not     esi
0045730F  |.  0B75 F8       or      esi, dword ptr [ebp-8]
00457312  |.  3375 F0       xor     esi, dword ptr [ebp-10]
00457315  |.  03F3          add     esi, ebx
00457317  |.  B8 65000000   mov     eax, 65
0045731C  |.  E8 AFB6FAFF   call    004029D0
00457321  |.  8B1485 F09245>mov     edx, dword ptr [eax*4+4592F0]
00457328  |.  8D45 E4       lea     eax, dword ptr [ebp-1C]
0045732B  |.  E8 C4C5FAFF   call    004038F4
00457330  |.  8B5D FC       mov     ebx, dword ptr [ebp-4]
00457333  |.  8B1B          mov     ebx, dword ptr [ebx]
00457335  |.  03DF          add     ebx, edi
00457337  |.  0375 F4       add     esi, dword ptr [ebp-C]
0045733A  |.  81EE 6F2C7914 sub     esi, 14792C6F
00457340  |.  8975 F4       mov     dword ptr [ebp-C], esi
00457343  |.  8B75 FC       mov     esi, dword ptr [ebp-4]
00457346  |.  8B76 04       mov     esi, dword ptr [esi+4]
00457349  |.  8B7D F4       mov     edi, dword ptr [ebp-C]
0045734C  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
0045734F  |.  8918          mov     dword ptr [eax], ebx
00457351  |.  C1EF 0B       shr     edi, 0B
00457354  |.  C165 F4 15    shl     dword ptr [ebp-C], 15
00457358  |.  0B7D F4       or      edi, dword ptr [ebp-C]
0045735B  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
0045735E  |.  8B40 08       mov     eax, dword ptr [eax+8]
00457361  |.  8945 F4       mov     dword ptr [ebp-C], eax
00457364  |.  037D F8       add     edi, dword ptr [ebp-8]
00457367  |.  8B45 F8       mov     eax, dword ptr [ebp-8]
0045736A  |.  0145 F4       add     dword ptr [ebp-C], eax
0045736D  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
00457370  |.  8B40 0C       mov     eax, dword ptr [eax+C]
00457373  |.  8945 F8       mov     dword ptr [ebp-8], eax
00457376  |.  03F7          add     esi, edi
00457378  |.  8B45 F0       mov     eax, dword ptr [ebp-10]
0045737B  |.  0145 F8       add     dword ptr [ebp-8], eax
0045737E  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
00457381  |.  8B55 F4       mov     edx, dword ptr [ebp-C]
00457384  |.  8950 08       mov     dword ptr [eax+8], edx
00457387  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
0045738A  |.  8B55 F8       mov     edx, dword ptr [ebp-8]
0045738D  |.  8950 0C       mov     dword ptr [eax+C], edx
00457390  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
00457393  |.  8970 04       mov     dword ptr [eax+4], esi
00457396  |.  8B55 E4       mov     edx, dword ptr [ebp-1C]                   ;  edx==>“MatrixxxMadness1 - UNREGISTERED!”
00457399  |.  A1 08A84500   mov     eax, dword ptr [45A808]
0045739E  |.  E8 5DFCFDFF   call    00437000                                  ;  SetText,显示上面的字符串
004573A3  |.  33C0          xor     eax, eax
004573A5  |.  5A            pop     edx
004573A6  |.  59            pop     ecx
004573A7  |.  59            pop     ecx
004573A8  |.  64:8910       mov     dword ptr fs:[eax], edx
004573AB  |.  68 C0734500   push    004573C0
004573B0  |>  8D45 E4       lea     eax, dword ptr [ebp-1C]
004573B3  |.  E8 A4C4FAFF   call    0040385C
004573B8  \.  C3            retn
004573B9   .^ E9 5EBFFAFF   jmp     0040331C
004573BE   .^ EB F0         jmp     short 004573B0
004573C0   .  5F            pop     edi
004573C1   .  5E            pop     esi
004573C2   .  5B            pop     ebx
004573C3   .  8BE5          mov     esp, ebp
004573C5   .  5D            pop     ebp
004573C6   .  C3            retn

下面是注册码比较过程:
[Asm] 纯文本查看 复制代码
00457ABC  /$  55            push    ebp
00457ABD  |.  8BEC          mov     ebp, esp
00457ABF  |.  53            push    ebx
00457AC0  |.  56            push    esi
00457AC1  |.  57            push    edi
00457AC2  |.  8BF9          mov     edi, ecx                                     ;  参数3,第1个checkbox状态值
00457AC4  |.  8BF2          mov     esi, edx                                     ;  参数2,第2个MD5计算值变形运算后的数值
00457AC6  |.  8BD8          mov     ebx, eax                                     ;  参数1,第1个MD5运算值变形运算后的数值
00457AC8  |.  E8 3FADFAFF   call    0040280C
00457ACD  |.  2BDF          sub     ebx, edi                                     ;  参数1与参数3比较
00457ACF  |.  75 09         jnz     short 00457ADA
00457AD1  |.  2B75 08       sub     esi, dword ptr [ebp+8]                       ;  参数2与参数4比较,[ebp+8]为参数4,第2个checkbox状态值
00457AD4  |.  75 04         jnz     short 00457ADA
00457AD6  |.  33C0          xor     eax, eax                                     ;  都相等则生成索引 0
00457AD8  |.  EB 0A         jmp     short 00457AE4
00457ADA  |>  B8 00010000   mov     eax, 100                                     ;  生成0~0xFF范围内的随机数
00457ADF  |.  E8 ECAEFAFF   call    004029D0                                     ;  生成随机数
00457AE4  |>  25 FF000000   and     eax, 0FF                                     ; 限制索引在0~0xFF范围内
00457AE9  |.  8B0485 849445>mov     eax, dword ptr [eax*4+459484]                ; 通过索引查表返回调用地址
00457AF0  |.  5F            pop     edi
00457AF1  |.  5E            pop     esi
00457AF2  |.  5B            pop     ebx
00457AF3  |.  5D            pop     ebp
00457AF4  \.  C2 0400       retn    4

如果注册码不相等,则会调用下面这些函数,都是空函数,只有一个retn:
[Asm] 纯文本查看 复制代码
///////////////// 注册失败时的 call eax 调用的函数列表 ////////////////////////
0045746C   .  C3            retn
0045746D      8D40 00       lea     eax, dword ptr [eax]
00457470   .  C3            retn
00457471      8D40 00       lea     eax, dword ptr [eax]
00457474   .  C3            retn
00457475      8D40 00       lea     eax, dword ptr [eax]
00457478   .  C3            retn
00457479      8D40 00       lea     eax, dword ptr [eax]
0045747C   .  C3            retn
0045747D      8D40 00       lea     eax, dword ptr [eax]
00457480   .  C3            retn
00457481      8D40 00       lea     eax, dword ptr [eax]
00457484   .  C3            retn
00457485      8D40 00       lea     eax, dword ptr [eax]
00457488   .  C3            retn
00457489      8D40 00       lea     eax, dword ptr [eax]
0045748C   .  C3            retn
0045748D      8D40 00       lea     eax, dword ptr [eax]
00457490   .  C3            retn
00457491      8D40 00       lea     eax, dword ptr [eax]
00457494   .  C3            retn
00457495      8D40 00       lea     eax, dword ptr [eax]
00457498   .  C3            retn
00457499      8D40 00       lea     eax, dword ptr [eax]
0045749C   .  C3            retn
0045749D      8D40 00       lea     eax, dword ptr [eax]
004574A0   .  C3            retn
004574A1      8D40 00       lea     eax, dword ptr [eax]
004574A4   .  C3            retn
004574A5      8D40 00       lea     eax, dword ptr [eax]
004574A8   .  C3            retn
004574A9      8D40 00       lea     eax, dword ptr [eax]

这个Crackme 输入注册码的方式比较特别,是通过一个checkbox矩陈来输入的。
序列号共两个整数,每个整数32bits,分成4行,每行输入8bits,一起8行x8位,完成SN的输入。
通过上面分析,输入用户名:solly,得到  SN:919D5B79-3826ACAC,再转成二进制矩陈显示如下,”1“表示选中,”0“表示不选中:
SN Matrix:
1  0  0  1  0  0  0  1
1  0  0  1  1  1  0  1
0  1  0  1  1  0  1  1
0  1  1  1  1  0  0  1
0  0  1  1  1  0  0  0
0  0  1  0  0  1  1  0
1  0  1  0  1  1  0  0
1  0  1  0  1  1  0  0
输入注册码,成功画面如下:
8.png
注册码验证过程分析完毕,以下是注册机,其中MD5代码参考网上代码,并按crackme的要求作一定修改,源码如下,共3个文件:
[C++] 纯文本查看 复制代码
/*
main.cpp
*/
#include <stdio.h>
#include <stdlib.h>
#include "MD5.hpp"

int main(int argc, char** argv) {
        
        unsigned char decrypt[16];
        //unsigned char regname[] = "\0sollysollysollysollysollysollysollysollysollysollysollysollysol";
        char temp[256];
        char regname[80];

        printf("Keygen for 152 - 'The AntiXryst' of 160 crackme.\n");
        //// 输入用户名 
        printf("Enter your name: ");
        gets(temp); //// 输入用户名 

        //// 用户名处理 
        int n = strlen(temp);
        char * p = regname[1]; /// 从第2个字节开始保存连接的用户名 
        strncpy(p, temp, 64);
        int m = n;
        while(m<63) {
                strcat(p+n, temp);
                m += n;
        }
        regname[0]  = '\0';  /// 第1个字节设为'\0'
        regname[64] = '\0';  /// 字符串null结束符 
        //printf("Name: %s\n", p);
        
        ////MD5算法 
        int len = 0x40; /// 固定长度为64 
        MD5_CTX md5;

        MD5Init(&md5);
        MD5Update(&md5, (unsigned char *)regname, len);
        MD5Final(&md5, decrypt);

        //////
        unsigned int sn[2];
        sn[0] = md5.state2[0] - md5.state2[1] - md5.state2[2] + md5.state2[3];
        sn[1] = md5.state[0] - md5.state[1] - md5.state[2] + md5.state[3];
        ////
        printf("\n\nSN: %08X-%08X\n", sn[0], sn[1]);
        
        printf("SN Matrix:\n");
        for(int i=0; i<2; i++) {
                unsigned int a = sn[i];
                unsigned int b = 0x80000000;
                for(int j=1; j<=32; j++) {
                        if(a & b) {
                                printf("1  ");
                        } else {
                                printf("0  ");
                        }
                        b >>=1;
                        if((j % 8) == 0) {
                                printf("\n");
                        }
                }
        }
        
        system("pause");

        return 0;
}

第二个是 MD5.cpp:
[C++] 纯文本查看 复制代码
#include "Md5.hpp"
unsigned char PADDING[] = {
    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

void MD5Init(MD5_CTX *context){
    context->count[0]=0;
    context->count[1]=0;
    context->state[0]=0x67452301;
    context->state[1]=0xEFCDAB89;
    context->state[2]=0x98BADCFE;
    context->state[3]=0x10325476;
    //// context->buffer[64];
}

void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen){
    unsigned int i=0,index=0,partlen=0;
    index=(context->count[0]>>3)&0x3F;
    partlen=64-index;
    context->count[0]+=inputlen<<3;
    if(context->count[0]<(inputlen<<3)) context->count[1]++;
    context->count[1]+=inputlen>>29;
    
    if(inputlen>=partlen){
        memcpy(&context->buffer[index], input, partlen);
        MD5Transform(context->state, context->buffer);
        for(i=partlen;i+64<=inputlen;i+=64) MD5Transform(context->state,&input[i]);
        index=0;
        //// 相对标准MD5第1处改动, 在第1次基础上直接进行第2次MD5计算/////////////
        context->state2[0] = context->state[0]; //// 保存第1次的MD5值 
        context->state2[1] = context->state[1]; //// 保存第1次的MD5值 
        context->state2[2] = context->state[2]; //// 保存第1次的MD5值 
        context->state2[3] = context->state[3]; //// 保存第1次的MD5值 
        MD5Transform(context->state, context->buffer);
        for(i=partlen;i+64<=inputlen;i+=64) MD5Transform(context->state,&input[i]);
        index=0;
        //////////////////////////////////////////////////////////////////////////
    }
    else i=0;
    memcpy(&context->buffer[index], &input[i], inputlen-i);
}

void MD5Final(MD5_CTX *context, unsigned char digest[16]){
    unsigned int index=0,padlen=0;
    unsigned char bits[8];
    index=(context->count[0]>>3)&0x3F;
    padlen=(index<56)?(56-index):(120-index);
    ////// 相对标准MD5第2处改动, 因为主注册名已经有64字节,并且由于其第1字节为'\0',会padding掉全部内容,所以不进行Padding处理 
    // MD5Update(context,PADDING,padlen); //// no padding, comments by solly
    //////////////////////////////////////////////////////////////////////////////////   
    MD5Update(context,bits,8);//index=0
    /////
    MD5Encode(digest,context->state,16);
}

void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len){
    unsigned int i = 0, j = 0;
    while (j<len){
        output[j]=input[i] & 0xFF;
        output[j+1]=(input[i]>>8)&0xFF;
        output[j+2]=(input[i]>>16)&0xFF;
        output[j+3]=(input[i]>>24)&0xFF;
        i++;
        j += 4;
    }
}

void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len){
    unsigned int i = 0, j = 0;
    while (j < len){
        output[i] = (input[j]) |
        (input[j + 1] << 8) |
        (input[j + 2] << 16) |
        (input[j + 3] << 24);
        i++;
        j += 4;
    }
}

void MD5Transform(unsigned int state[4], unsigned char block[64]){
    unsigned int a = state[0];
    unsigned int b = state[1];
    unsigned int c = state[2];
    unsigned int d = state[3];
    unsigned int x[16];
    
    MD5Decode(x, block, 64);
    FF(a, b, c, d, x[0], 7, 0xd76aa478);
    FF(d, a, b, c, x[1], 12, 0xe8c7b756);
    FF(c, d, a, b, x[2], 17, 0x242070db);
    FF(b, c, d, a, x[3], 22, 0xc1bdceee);
    FF(a, b, c, d, x[4], 7, 0xf57c0faf);
    FF(d, a, b, c, x[5], 12, 0x4787c62a);
    FF(c, d, a, b, x[6], 17, 0xa8304613);
    FF(b, c, d, a, x[7], 22, 0xfd469501);
    FF(a, b, c, d, x[8], 7, 0x698098d8);
    FF(d, a, b, c, x[9], 12, 0x8b44f7af);
    FF(c, d, a, b, x[10], 17, 0xffff5bb1);
    FF(b, c, d, a, x[11], 22, 0x895cd7be);
    FF(a, b, c, d, x[12], 7, 0x6b901122);
    FF(d, a, b, c, x[13], 12, 0xfd987193);
    FF(c, d, a, b, x[14], 17, 0xa679438e);
    FF(b, c, d, a, x[15], 22, 0x49b40821);
    
    
    GG(a, b, c, d, x[1], 5, 0xf61e2562);
    GG(d, a, b, c, x[6], 9, 0xc040b340);
    GG(c, d, a, b, x[11], 14, 0x265e5a51);
    GG(b, c, d, a, x[0], 20, 0xe9b6c7aa);
    GG(a, b, c, d, x[5], 5, 0xd62f105d);
    GG(d, a, b, c, x[10], 9, 0x2441453);
    GG(c, d, a, b, x[15], 14, 0xd8a1e681);
    GG(b, c, d, a, x[4], 20, 0xe7d3fbc8);
    GG(a, b, c, d, x[9], 5, 0x21e1cde6);
    GG(d, a, b, c, x[14], 9, 0xc33707d6);
    GG(c, d, a, b, x[3], 14, 0xf4d50d87);
    GG(b, c, d, a, x[8], 20, 0x455a14ed);
    GG(a, b, c, d, x[13], 5, 0xa9e3e905);
    GG(d, a, b, c, x[2], 9, 0xfcefa3f8);
    GG(c, d, a, b, x[7], 14, 0x676f02d9);
    GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);
    
    
    HH(a, b, c, d, x[5], 4, 0xfffa3942);
    HH(d, a, b, c, x[8], 11, 0x8771f681);
    HH(c, d, a, b, x[11], 16, 0x6d9d6122);
    HH(b, c, d, a, x[14], 23, 0xfde5380c);
    HH(a, b, c, d, x[1], 4, 0xa4beea44);
    HH(d, a, b, c, x[4], 11, 0x4bdecfa9);
    HH(c, d, a, b, x[7], 16, 0xf6bb4b60);
    HH(b, c, d, a, x[10], 23, 0xbebfbc70);
    HH(a, b, c, d, x[13], 4, 0x289b7ec6);
    HH(d, a, b, c, x[0], 11, 0xeaa127fa);
    HH(c, d, a, b, x[3], 16, 0xd4ef3085);
    HH(b, c, d, a, x[6], 23, 0x4881d05);
    HH(a, b, c, d, x[9], 4, 0xd9d4d039);
    HH(d, a, b, c, x[12], 11, 0xe6db99e5);
    HH(c, d, a, b, x[15], 16, 0x1fa27cf8);
    HH(b, c, d, a, x[2], 23, 0xc4ac5665);
    
    
    II(a, b, c, d, x[0], 6, 0xf4292244);
    II(d, a, b, c, x[7], 10, 0x432aff97);
    II(c, d, a, b, x[14], 15, 0xab9423a7);
    II(b, c, d, a, x[5], 21, 0xfc93a039);
    II(a, b, c, d, x[12], 6, 0x655b59c3);
    II(d, a, b, c, x[3], 10, 0x8f0ccc92);
    II(c, d, a, b, x[10], 15, 0xffeff47d);
    II(b, c, d, a, x[1], 21, 0x85845dd1);
    II(a, b, c, d, x[8], 6, 0x6fa87e4f);
    II(d, a, b, c, x[15], 10, 0xfe2ce6e0);
    II(c, d, a, b, x[6], 15, 0xa3014314);
    II(b, c, d, a, x[13], 21, 0x4e0811a1);
    II(a, b, c, d, x[4], 6, 0xf7537e82);
    II(d, a, b, c, x[11], 10, 0xbd3af235);
    II(c, d, a, b, x[2], 15, 0x2ad7d2bb);
    II(b, c, d, a, x[9], 21, 0xeb86d391);
    state[0] += a;
    state[1] += b;
    state[2] += c;
    state[3] += d;
}

第三个是 MD5.hpp:
[C++] 纯文本查看 复制代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
 
typedef struct{
    unsigned int count[2];
    unsigned int state[4];
    unsigned char buffer[64];
    unsigned int state2[4];  //// 这里是改动之三,不对算法产生影响,只是用来备份第1次MD5结果
} MD5_CTX;
 
#define F(x,y,z) ((x&y)|(~x&z))
#define G(x,y,z) ((x&z)|(y&~z))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y^(x|~z))
#define ROTATE_LEFT(x,n) ((x<<n)|(x>>(32-n)))
#define FF(a,b,c,d,x,s,ac) { a+=F(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
#define GG(a,b,c,d,x,s,ac) { a+=G(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
#define HH(a,b,c,d,x,s,ac) { a+=H(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
#define II(a,b,c,d,x,s,ac) { a+=I(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
 
void MD5Init(MD5_CTX *context);
void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);
void MD5Final(MD5_CTX *context, unsigned char digest[16]);
void MD5Transform(unsigned int state[4], unsigned char block[64]);
void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);
void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);
 

以上代码是在 Dev-C++上调试通过的。
///////
完毕,码字不易!!!!评分免费!!!!
9.png
8.png

免费评分

参与人数 5威望 +1 吾爱币 +11 热心值 +4 收起 理由
suifeng165 + 1 + 1 用心讨论,共获提升!
Hmily + 1 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
52lxw + 1 我很赞同!
朱朱你堕落了 + 1 + 1 师傅好牛B。
于洪生 + 1 + 1 用心讨论,共获提升!

查看全部评分

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

于洪生 发表于 2019-4-8 22:05
楼主辛苦了,虽然我不懂这个
yangtianqi 发表于 2019-4-9 12:27
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-15 18:37

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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