首页
社区
课程
招聘
[原创][增长信心篇]序列号保护基础知识之习题四详解(算法分析+注册机)
发表于: 2014-9-22 17:45 8216

[原创][增长信心篇]序列号保护基础知识之习题四详解(算法分析+注册机)

2014-9-22 17:45
8216

【适合人群】热爱算法分析的初学者
【破解工具】OllyDbg
【下载地址】KSSD---->第4篇 调试篇---->序列号保护----> 基础知识---->序列号方式习题四
【程序下载】 chap6-1-1-04.zip
-----------------------------------------------------------------------------------------------------------------------------

一、前言
    鉴于上篇破解文章是在破解完之后写出来的,由于本人记忆力不是很好,所以个中细节记得不是很清,所以让初学者看起来可能觉得顺理成章,但是这明显不符合破解的规律,所以本篇文章我边破解边记录,也把自己在破解过程中的一些心得与大家分享。顺便在这提一句,虽然这些习题在看雪都有答案,但是答案无法代替我们自己对问题的思考过程,如果你做过习题一,看过看雪的答案,你就会发现答案也是有问题的,不知朋友们有没有发现? 虽然习题四这个例子被很多人引用过也讲解过,但是里面有些东西还是可以再提一下的。

----------------------------------------------------------------------------------------------------------------------------

二、找关键跳转
    记得在上篇文章中是利用查找字符串的方法来找关键跳转的,虽然这题也可以用,但该方法被许多有识之士所不耻,所以这题我用下断法。好,我们先对GetWindowTextA/W函数下断,当然你也可以对GetDlgItemTextA/W函数下断,这里顺便提一句,我们是利用了这个API来获取字符串的,那你想,假设有一天我们的能力足够强,强到能够自己来实现一个获取字符串的函数,那么是不是就不容易被别人下断。下断之后F9运行起来,点开Help,然后Register,输入Name和Serial,接着来到图1。

                            
                                                  图1

一看发现程序的领空在USER32里,我们很自然想到Alt+F9跳出去,来到图2

                            ;
                                                图2

到这儿你看到一个GetDlgItemTextA,你应该能发现点什么,在GetDlgItemTextA里居然调用到了GetWindowTextA,你应该明白了吧。然后我们接着F8一步步往下走,不一会儿你会发现又进入了USER32的领空,那么我们就再来一次Alt+F9,来到图3关键地方。

                            ;
                                               图3

到了这儿应该很容易就看出这就是关键跳转的地方了,为什么?首先就是我们看到了输入的Name和Serial都在这儿,其次就是有作比较并且进行跳转。在上一篇文章中,我的建议是:不急于去分析每条指令的作用,理清程序的逻辑结构更为关键。如果我们之前的猜测是对的,那么我们只需验证下跳转到的地方是不是成功或失败信息即可,马上去看下call 0040134D,来到图4。

                            ;
                                               图4

看来我们的直觉是正确的。关键地方找到了,接下来就是要分析关键的算法了,图3向上看我们发现有两个函数call  0040137E和call  004013D8.下一段我们就重点来分析这两个函数。

-----------------------------------------------------------------------------------------------------------------------------
三、关键算法分析
1.分析call  0040137E,F7跟进看到如下代码:

0040137E  /$  8B7424 04     mov     esi, dword ptr [esp+4]           ;  CRACKME.0040218E
00401382  |.  56            push    esi
00401383  |>  8A06          /mov     al, byte ptr [esi]
00401385  |.  84C0          |test    al, al
00401387  |.  74 13         |je      short 0040139C                  ;  字符串结束就跳出
00401389  |.  3C 41         |cmp     al, 41
0040138B  |.  72 1F         |jb      short 004013AC                  ;  当字符小于65(A)时就失败
0040138D  |.  3C 5A         |cmp     al, 5A
0040138F  |.  73 03         |jnb     short 00401394                  ;  大于等于90就跳转
00401391  |.  46            |inc     esi
00401392  |.^ EB EF         |jmp     short 00401383
00401394  |>  E8 39000000   |call    004013D2                        ;  将小写转化为大写
00401399  |.  46            |inc     esi
0040139A  |.^ EB E7         \jmp     short 00401383
0040139C  |>  5E            pop     esi
0040139D  |.  E8 20000000   call    004013C2
004013A2  |.  81F7 78560000 xor     edi, 5678                        ;  EDI 为处理后的各个字符相加之和,然后与0x5678异或
004013A8  |.  8BC7          mov     eax, edi                         ;  结果存入EAX
004013AA  |.  EB 15         jmp     short 004013C1
004013AC  |>  5E            pop     esi
004013AD  |.  6A 30         push    30                               ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
004013AF  |.  68 60214000   push    00402160                         ; |Title = "No luck!"
004013B4  |.  68 69214000   push    00402169                         ; |Text = "No luck there, mate!"
004013B9  |.  FF75 08       push    dword ptr [ebp+8]                ; |hOwner
004013BC  |.  E8 79000000   call    <jmp.&USER32.MessageBoxA>        ; \MessageBoxA
004013C1  \>  C3            retn
004013C2  /$  33FF          xor     edi, edi
004013C4  |.  33DB          xor     ebx, ebx
004013C6  |>  8A1E          /mov     bl, byte ptr [esi]
004013C8  |.  84DB          |test    bl, bl
004013CA  |.  74 05         |je      short 004013D1
004013CC  |.  03FB          |add     edi, ebx
004013CE  |.  46            |inc     esi
004013CF  |.^ EB F5         \jmp     short 004013C6
004013D1  \>  C3            retn
004013D2  /$  2C 20         sub     al, 20                           ;  将小写转化为大写
004013D4  |.  8806          mov     byte ptr [esi], al
004013D6  \.  C3            retn

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 3
支持
分享
最新回复 (8)
雪    币: 1821
活跃值: (1928)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
沙发
2014-9-22 17:53
0
雪    币: 248
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
绿色,亮瞎了
2014-9-22 18:56
0
雪    币: 102
活跃值: (31)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
我做的也是这个哎哈哈.
#include <stdio.h>
#include <string.h>
int main()
{
    char name[128] = {0}, serial[128] = {0};
    int i, j, k;
    printf("name:");
    scanf("%s",name);
    getchar();
    j = 0;
    for (i = 0; i < strlen(name); i++)
    {
        if (name[i] < 'A') return -1;
        if (name[i] >= 'Z') name[i] -= 0x20;
        j += name[i];
    }
    j = (j ^ 0x5678) ^ 0x1234;
    printf("Serial: %d\n",j);
    getchar();
    return 0;
}
2014-9-22 19:29
0
雪    币: 492
活跃值: (51)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
唉,代码都有溢出漏洞......
2014-9-22 20:03
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
No Luck there,mate!笑死
2014-9-23 01:17
0
雪    币: 168
活跃值: (823)
能力值: ( LV10,RANK:173 )
在线值:
发帖
回帖
粉丝
7
[QUOTE=谷月轩;1318424]我做的也是这个哎哈哈.
#include <stdio.h>
#include <string.h>
int main()
{
    char name[128] = {0}, serial[128] = {0};
    int i, j, k;
    printf("name:&q...[/QUOTE]

居然在同一天和你发了相同的东西
2014-9-23 10:30
0
雪    币: 3279
活跃值: (1997)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
精华贴的节奏。
2014-9-24 08:26
0
雪    币: 11
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
考研哥,我们一起加油!!
2014-10-29 22:57
0
游客
登录 | 注册 方可回帖
返回
//