首页
社区
课程
招聘
[原创]解密教学第6章序列号方式之习题八分析
发表于: 2008-10-27 22:11 3728

[原创]解密教学第6章序列号方式之习题八分析

2008-10-27 22:11
3728
分析程序是本站解密教学第6章(软件保护技术)第一节(常见保护技巧)中的第1小节(序列号方式)第八题。

步骤一、运行程序查看提示信息
运行crackme3.exe,输入用户名yzlyzl,序列号123456,点击[check]按钮,跳出对话框提示“One of the Details you entered was wrong”。

步骤二、运行PEiD.exe查看该程序的实现语言
运行PEiD.exe,将crackme3.exe拉进来,可以看到提示“Microsoft Visual C++ 6.0”

步骤三、用IDA加载crackme3.exe
因为这是VC的程序,所以设置IDA的FLIRT(File->Load file->FLIRT signature file)为vc32mfc。

步骤四、查找[check]按钮的点击事件的代码位置
查找相关提示信息,在IDA的代码视图中,选择View->Open subviews->Strings,跳出字符串引用窗口,查找“One of the Details you entered was wrong”双击它,定位到:
.data:00403040 aOneOfTheDetail db 'One of the Details you entered was wrong',0
.data:00403040                                         ; DATA XREF: .text:004015CAo

再双击上面绿色的部分(004015CA)来到:
... ...
... ...
.text:004015C3                 push    0
.text:004015C5                 push    offset aError   ; "ERROR"
.text:004015CA                 push    offset aOneOfTheDetail ; "One of the Details you entered was wron"...
.text:004015CF                 mov     ecx, [ebp-20h]
.text:004015D2                 call    ?MessageBoxA@CWnd@@QAEHPBD0I@Z ; CWnd::MessageBoxA(char const *,char const *,uint)
.text:004015D7                 jmp     short loc_4015ED
... ...
... ...

我们向上移动到:
.text:004014B0                 push    ebp
.text:004014B1                 mov     ebp, esp
.text:004014B3                 push    0FFFFFFFFh
... ...

以下开始分析:
.text:004014B0                 push    ebp
.text:004014B1                 mov     ebp, esp
.text:004014B3                 push    0FFFFFFFFh
.text:004014B5                 push    offset loc_401BC2
.text:004014BA                 mov     eax, large fs:0
.text:004014C0                 push    eax
.text:004014C1                 mov     large fs:0, esp
.text:004014C8                 sub     esp, 14h
.text:004014CB                 push    ebx
.text:004014CC                 push    esi
.text:004014CD                 push    edi
.text:004014CE                 mov     [ebp-20h], ecx
.text:004014D1                 lea     ecx, [ebp-1Ch]
.text:004014D4                 call    ??0CString@@QAE@XZ ; CString::CString(void)
.text:004014D9                 mov     dword ptr [ebp-4], 0
.text:004014E0                 lea     ecx, [ebp-10h]
.text:004014E3                 call    ??0CString@@QAE@XZ ; CString::CString(void)
.text:004014E8                 mov     byte ptr [ebp-4], 1
.text:004014EC                 mov     ecx, [ebp-20h]
.text:004014EF                 add     ecx, 0A0h       ; name控件
.text:004014F5                 call    ?GetWindowTextLengthA@CWnd@@QBEHXZ ; CWnd::GetWindowTextLengthA(void)
.text:004014FA                 mov     [ebp-14h], eax  ; [ebp-14h]=name的长度
.text:004014FD                 cmp     dword ptr [ebp-14h], 5
.text:00401501                 jg      short loc_401508
.text:00401503                 jmp     loc_4015C3      ; name的长度小于5出错
.text:00401508 ; ---------------------------------------------------------------------------
.text:00401508
.text:00401508 loc_401508:                             ; CODE XREF: .text:00401501j
.text:00401508                 mov     ecx, [ebp-20h]
.text:0040150B                 add     ecx, 60h        ; serial控件
.text:0040150E                 call    ?GetWindowTextLengthA@CWnd@@QBEHXZ ; CWnd::GetWindowTextLengthA(void)
.text:00401513                 mov     [ebp-18h], eax  ; [ebp-18h]=serial的长度
.text:00401516                 cmp     dword ptr [ebp-18h], 5
.text:0040151A                 jg      short loc_401521
.text:0040151C                 jmp     loc_4015C3      ; serial的长度小于5出错
.text:00401521 ; ---------------------------------------------------------------------------
.text:00401521
.text:00401521 loc_401521:                             ; CODE XREF: .text:0040151Aj
.text:00401521                 mov     eax, [ebp-20h]
.text:00401524                 add     eax, 0E0h       ; 0E0h - 存放name的CString
.text:00401529                 push    eax
.text:0040152A                 mov     ecx, [ebp-20h]
.text:0040152D                 add     ecx, 0A0h       ; name控件
.text:00401533                 call    ?GetWindowTextA@CWnd@@QBEXAAVCString@@@Z ; CWnd::GetWindowTextA(CString &)
.text:00401538                 mov     ecx, [ebp-20h]
.text:0040153B                 add     ecx, 0E4h       ; 0E4h - 存放serial的CString
.text:00401541                 push    ecx
.text:00401542                 mov     ecx, [ebp-20h]
.text:00401545                 add     ecx, 60h        ; serial控件
.text:00401548                 call    ?GetWindowTextA@CWnd@@QBEXAAVCString@@@Z ; CWnd::GetWindowTextA(CString &)
.text:0040154D                 mov     edx, [ebp-20h]
.text:00401550                 add     edx, 0E0h
.text:00401556                 push    edx
.text:00401557                 lea     ecx, [ebp-1Ch]  ; [ebp-1Ch] - 存放name的Copy值
.text:0040155A                 call    ??4CString@@QAEABV0@ABV0@@Z ; CString::operator=(CString const &)
.text:0040155F                 mov     eax, [ebp-20h]
.text:00401562                 add     eax, 0E4h
.text:00401567                 push    eax
.text:00401568                 lea     ecx, [ebp-10h]  ; [ebp-10h] - 存放serial的Copy值
.text:0040156B                 call    ??4CString@@QAEABV0@ABV0@@Z ; CString::operator=(CString const &)
.text:00401570                 xor     eax, eax        ; eax = 0
.text:00401572                 xor     ebx, ebx        ; ebx = 0
.text:00401574                 xor     ecx, ecx
.text:00401576                 mov     ecx, 1          ; ecx = 1
.text:0040157B                 xor     edx, edx        ; edx = 0
.text:0040157D                 mov     eax, [ebp-1Ch]  ; [ebp-1Ch] - 存放name的Copy值
.text:00401580
.text:00401580 loc_401580:                             ; CODE XREF: .text:0040158Bj
.text:00401580                 mov     bl, [eax]
.text:00401582                 xor     bl, cl
.text:00401584                 mov     [eax], bl       ; 处理name中的各个字符
.text:00401584                                         ; name[i] = name[i]^(i + 1)
.text:00401586                 inc     ecx
.text:00401587                 inc     eax
.text:00401588                 cmp     byte ptr [eax], 0
.text:0040158B                 jnz     short loc_401580
.text:0040158D                 xor     eax, eax        ; eax = 0
.text:0040158F                 xor     ebx, ebx        ; ebx = 0
.text:00401591                 xor     ecx, ecx
.text:00401593                 mov     ecx, 0Ah        ; ecx = 0Ah
.text:00401598                 xor     edx, edx        ; edx = 0
.text:0040159A                 mov     eax, [ebp-10h]  ; [ebp-10h] - 存放serial的Copy值
.text:0040159D
.text:0040159D loc_40159D:                             ; CODE XREF: .text:004015A8j
.text:0040159D                 mov     bl, [eax]
.text:0040159F                 xor     bl, cl
.text:004015A1                 mov     [eax], bl       ; 处理serial中的各个字符
.text:004015A1                                         ; serial[i] = serial[i]^(i + 0Ah)
.text:004015A3                 inc     ecx
.text:004015A4                 inc     eax
.text:004015A5                 cmp     byte ptr [eax], 0
.text:004015A8                 jnz     short loc_40159D
.text:004015AA                 mov     eax, [ebp-1Ch]  ; [ebp-1Ch] - 存放name的处理后的值
.text:004015AD                 mov     edx, [ebp-10h]  ; [ebp-10h] - 存放serial的处理后的值
.text:004015B0
.text:004015B0 loc_4015B0:                             ; CODE XREF: .text:004015BFj
.text:004015B0                 xor     ecx, ecx
.text:004015B2                 mov     bl, [eax]
.text:004015B4                 mov     cl, [edx]
.text:004015B6                 cmp     bl, cl          ; 逐个比较是否相等,不等则出错
.text:004015B8                 jnz     short loc_4015C3
.text:004015BA                 inc     eax
.text:004015BB                 inc     edx
.text:004015BC                 cmp     byte ptr [eax], 0
.text:004015BF                 jnz     short loc_4015B0
.text:004015C1                 jmp     short loc_4015D9
.text:004015C3 ; ---------------------------------------------------------------------------
.text:004015C3
.text:004015C3 loc_4015C3:                             ; CODE XREF: .text:00401503j
.text:004015C3                                         ; .text:0040151Cj ...
.text:004015C3                 push    0
.text:004015C5                 push    offset aError   ; "ERROR"
.text:004015CA                 push    offset aOneOfTheDetail ; "One of the Details you entered was wron"...
.text:004015CF                 mov     ecx, [ebp-20h]
.text:004015D2                 call    ?MessageBoxA@CWnd@@QAEHPBD0I@Z ; CWnd::MessageBoxA(char const *,char const *,uint)
.text:004015D7                 jmp     short loc_4015ED
.text:004015D9 ; ---------------------------------------------------------------------------
.text:004015D9
.text:004015D9 loc_4015D9:                             ; CODE XREF: .text:004015C1j
.text:004015D9                 push    0
.text:004015DB                 push    offset aYouDidIt ; "YOU DID IT"
.text:004015E0                 push    offset aWellDoneCracke ; "Well done,Cracker"
.text:004015E5                 mov     ecx, [ebp-20h]
.text:004015E8                 call    ?MessageBoxA@CWnd@@QAEHPBD0I@Z ; CWnd::MessageBoxA(char const *,char const *,uint)
.text:004015ED
.text:004015ED loc_4015ED:                             ; CODE XREF: .text:004015D7j
.text:004015ED                 push    64h
.text:004015EF                 call    ds:Sleep
.text:004015F5                 mov     byte ptr [ebp-4], 0
.text:004015F9                 lea     ecx, [ebp-10h]
.text:004015FC                 call    ??1CString@@QAE@XZ ; CString::~CString(void)
.text:00401601                 mov     dword ptr [ebp-4], 0FFFFFFFFh
.text:00401608                 lea     ecx, [ebp-1Ch]
.text:0040160B                 call    ??1CString@@QAE@XZ ; CString::~CString(void)
.text:00401610                 mov     ecx, [ebp-0Ch]
.text:00401613                 mov     large fs:0, ecx
.text:0040161A                 pop     edi
.text:0040161B                 pop     esi
.text:0040161C                 pop     ebx
.text:0040161D                 mov     esp, ebp
.text:0040161F                 pop     ebp
.text:00401620                 retn

步骤五、编写注册机
#include <stdio.h>

void KeyGen(char *name, int len)
{
        int i = 0;
        char *serial = (char *)malloc(len + 1);
       
        for(; i < len; i ++)
        {
                serial[i] = name[i]^(i + 1)^(i + 0xA);
        }
       
        serial[i] = '\0';
       
        printf("name=%s,serial=%s",name,serial);
       
        free(serial);               
}

int main(int argc,char **argv)
{
        if(argc != 2)
        {
                printf("Usage: KeyGen [username]");
                return 1;
        }
       
        if(strlen(argv[1]) <= 5)
        {
                printf("Username'Length must be greater than 5");
                return 1;       
        }
       
        KeyGen(argv[1],strlen(argv[1]));
       
        return 0;               
}

编译:
cl KeyGen.c

运行
KeyGen yzlyzl

得到
name=yzlyzl,serial=rscpqe

我的分析参杂了些猜测,但是我觉得这并不是最终的解决办法 ,所以想请教一下大家。

疑惑地方:
1、如果我不用OD来配合我怎么知道下面的代码是指向name文本框?
.text:004014EC                 mov     ecx, [ebp-20h]
.text:004014EF                 add     ecx, 0A0h       ; name文本框控件

2、如果不通过查找引用字符串,我如何找到这个Check按钮事件代码的位置呢?
.text:004014B0                 push    ebp
.text:004014B1                 mov     ebp, esp
... ...
... ...

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//