-
-
[原创]一个简单的linux crackme分析
-
发表于: 2014-8-18 12:17 6214
-
软件下载地址:6b4K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3y4J5j5h3y4C8L8h3g2K6i4K6u0W2k6r3g2Q4x3V1k6#2M7$3g2J5M7#2)9J5c8Y4c8%4K9i4y4@1k6h3c8@1N6i4S2Q4x3V1k6X3K9i4u0K6N6q4)9#2k6X3E0W2P5h3N6W2L8X3#2W2i4K6u0r3
这个软件是我昨天浏览网站发现的,顿时勾起了我的兴趣,一是软件级别不高,适合我这样的新手,二是linux crackme比较难找,好不容易发现一个,又这么适合我,还不赶紧下载练练 大牛请直接忽略吧~~ 貌似这个网站更新比较慢,大家有没有比较好的这方面的网站推荐一下,在此深表感谢!
大概了解一下文件,无壳、无反调试反逆向技术、动态链接、32位小端序,程序结构比较简单,从main函数进入反汇编分析:
.text:08048450 main proc near ; DATA XREF: start+17o
.text:08048450
.text:08048450 arg_0 = dword ptr 8
.text:08048450 arg_4 = dword ptr 0Ch
.text:08048450
.text:08048450 push ebp
.text:08048451 mov ebp, esp
.text:08048453 mov eax, [ebp+arg_0]
.text:08048456 cmp eax, 3
.text:0804845B jnb short loc_8048485
.text:0804845D mov esi, [ebp+arg_4]
.text:08048460 mov edi, [esi]
.text:08048462 sub esp, 8
.text:08048468 mov esi, offset format ; "Utilisation : %s <pseudo> <clef>\n"
.text:0804846D mov [esp], esi ; format
.text:08048470 mov [esp+4], edi
.text:08048474 call _printf
.text:08048479
.text:08048479 loc_8048479: ; CODE XREF: main+6Fj
.text:08048479 ; main+9Bj ...
.text:08048479 mov eax, 1
.text:0804847E mov ebx, 1 ; status
.text:08048483 int 80h ; LINUX - sys_exit
.text:08048485 ; ---------------------------------------------------------------------------
.text:08048485
.text:08048485 loc_8048485: ; CODE XREF: main+Bj
.text:08048485 sub esp, 0Ch
.text:0804848B mov ebx, [ebp+arg_4]
.text:0804848E mov edx, ebx
.text:08048490 add edx, 4
.text:08048496 mov edx, [edx]
.text:08048498 mov [esp+4], edx ; 将pseudo参数的起始地址放到esp+4的位置
.text:0804849C mov edx, ebx
.text:0804849E add edx, 8
.text:080484A4 mov edx, [edx]
.text:080484A6 mov [esp+8], edx ; 将clef参数的起始地址放到esp+8的位置
.text:080484AA mov esi, [esp+8]
.text:080484AE push esi ; s
.text:080484AF call _strlen ; 计算clef字符串的长度
.text:080484B4 add esp, 4
.text:080484BA cmp eax, 6 ; 将clef字符串的长度与6比较
.text:080484BF jnz short loc_8048479 ; 如果长度不等于6退出系统 所以clef的第一个正确条件是长度等于6
.text:080484C1 mov edi, [esp+4]
.text:080484C5 push edi ; s
.text:080484C6 call _strlen ; 计算pseudo字符串的长度
.text:080484CB add esp, 4
.text:080484D1 mov [esp], eax ; format
.text:080484D4 push eax ; 将pseudo字符串的长度压入栈
.text:080484D5 call sub_80485CD ; 调用第一个处理函数,该函数返回正确的clef的第一个字符
.text:080484DA mov ebx, offset aAChrdw87lns0e9 ; "A-CHRDw87lNS0E9B2TibgpnMVys5XzvtOGJcYLU"...
.text:080484DF add ebx, eax ; 将字符串的起始地址+调用上一个函数返回的值,也就是计算偏移
.text:080484E1 mov dl, [ebx] ; 将计算的偏移地址对应的值赋给dl
.text:080484E3 mov edi, [esp+8] ; 将clef参数的地址赋寄存器edi
.text:080484E7 mov dh, [edi] ; 将clef参数的首个地址对应的值赋给dh
.text:080484E9 cmp dl, dh ; dl与dh比较
.text:080484EB jnz short loc_8048479 ; 如果dl不等于dh则退出系统
.text:080484ED mov edi, [esp] ; esp指向的栈中保存的是pseudo参数的长度
.text:080484F0 push edi ; 将pseudo参数的长度压栈
.text:080484F1 mov edi, [esp+8]
.text:080484F5 push edi ; 将pseudo参数的首个地址压栈
.text:080484F6 call sub_80485E3 ; 调用第二个处理函数,该函数返回正确的clef的第二个字符
.text:080484FB mov ebx, offset aAChrdw87lns0e9 ; "A-CHRDw87lNS0E9B2TibgpnMVys5XzvtOGJcYLU"...
.text:08048500 add ebx, eax
.text:08048502 mov dl, [ebx]
.text:08048504 mov edi, [esp+8]
.text:08048508 inc edi ; 获得clef参数的第二个字符对应的地址
.text:08048509 mov dh, [edi] ; 将地址对应的值赋给dh
.text:0804850B cmp dl, dh
.text:0804850D jnz loc_8048479 ; 如果dl不等于dh则退出系统
.text:08048513 mov edi, [esp]
.text:08048516 push edi ; 将pseudo参数的长度压栈
.text:08048517 mov edi, [esp+8]
.text:0804851B push edi ; 将pseudo参数的首个地址压栈
.text:0804851C call sub_804861A ; 调用第三个处理函数,该函数返回正确的clef的第三个字符
.text:08048521 mov ebx, offset aAChrdw87lns0e9 ; "A-CHRDw87lNS0E9B2TibgpnMVys5XzvtOGJcYLU"...
.text:08048526 add ebx, eax
.text:08048528 mov dl, [ebx]
.text:0804852A mov edi, [esp+8]
.text:0804852E add edi, 2 ; 获得clef参数的第三个字符对应的地址
.text:08048534 mov dh, [edi] ; 将地址对应的值赋给dh
.text:08048536 cmp dl, dh
.text:08048538 jnz loc_8048479 ; 如果dl不等于dh则退出系统
.text:0804853E mov edi, [esp]
.text:08048541 push edi ; pseudo参数的长度压栈
.text:08048542 mov edi, [esp+8]
.text:08048546 push edi ; 将pseudo参数的首个地址压栈
.text:08048547 call sub_8048650 ; 调用第四个处理函数,该函数返回正确的clef的第四个字符
.text:0804854C mov ebx, offset aAChrdw87lns0e9 ; "A-CHRDw87lNS0E9B2TibgpnMVys5XzvtOGJcYLU"...
.text:08048551 add ebx, eax
.text:08048553 mov dl, [ebx]
.text:08048555 mov edi, [esp+8]
.text:08048559 add edi, 3 ;获得clef参数的第四个字符对应的地址
.text:0804855F mov dh, [edi]
.text:08048561 cmp dl, dh
.text:08048563 jnz loc_8048479 ; 如果dl不等于dh则退出系统
.text:08048569 mov edi, [esp]
.text:0804856C push edi ; pseudo参数的长度压栈
.text:0804856D mov edi, [esp+8]
.text:08048571 push edi ; 将pseudo参数的首个地址压栈
.text:08048572 call sub_804868E ;调用第五个处理函数,该函数返回正确的clef的第五个字符
.text:08048577 mov ebx, offset aAChrdw87lns0e9 ; "A-CHRDw87lNS0E9B2TibgpnMVys5XzvtOGJcYLU"...
.text:0804857C add ebx, eax
.text:0804857E mov dl, [ebx]
.text:08048580 mov edi, [esp+8]
.text:08048584 add edi, 4 ;获得clef参数的第五个字符对应的地址
.text:0804858A mov dh, [edi]
.text:0804858C cmp dl, dh
.text:0804858E jnz loc_8048479 ; 如果dl不等于dh则退出系统
.text:08048594 mov edi, [esp+4]
.text:08048598 xor edx, edx
.text:0804859A mov dl, [edi]
.text:0804859C push edx ;将pseudo参数的首地址对应的值压栈
.text:0804859D call sub_80486D1 ;调用第六个处理函数,该函数返回正确的clef的第六个字符
.text:080485A2 mov ebx, offset aAChrdw87lns0e9 ; "A-CHRDw87lNS0E9B2TibgpnMVys5XzvtOGJcYLU"...
.text:080485A7 add ebx, eax
.text:080485A9 mov dl, [ebx]
.text:080485AB mov edi, [esp+8]
.text:080485AF add edi, 5 ;获取clef参数的第六个字符对应的地址
.text:080485B5 mov dh, [edi]
.text:080485B7 cmp dl, dh
.text:080485B9 jnz loc_8048479 ; 如果dl不等于dh则退出系统,如果相等则打印成功的信息
.text:080485BF push offset aBravo ; "Bravo !!\n"
.text:080485C4 call _printf
.text:080485C9 xor eax, eax
.text:080485CB leave
.text:080485CC retn
.text:080485CC main endp ; sp-analysis failed
从main函数可以看出,clef由6个字符组成,每个处理函数生成一个字符,共6个处理函数,所以需要对6个处理函数进行分析:
下面就是六个处理函数内部的具体实现:
第一个处理函数:
.text:080485CD sub_80485CD proc near
.text:080485CD
.text:080485CD arg_0= dword ptr 8
.text:080485CD
.text:080485CD push ebp
.text:080485CE mov ebp, esp
.text:080485D0 mov eax, [ebp+arg_0];入参,pseudo参数的长度
.text:080485D3 and eax, 0FFh ; 将pseudo参数的长度与0xff相与,将eax的高24位清零
.text:080485D8 xor al, 3Bh ; al与0x3b异或保存
.text:080485DA and eax, 3Fh ; eax与0x3f相与保存
.text:080485DF leave
.text:080485E0 retn 4 ; 返回计算的结果
.text:080485E0 sub_80485CD endp
第二个处理函数:
.text:080485E3 sub_80485E3 proc near ; CODE XREF: main+A6p
.text:080485E3
.text:080485E3 arg_0 = dword ptr 8
.text:080485E3 arg_4 = dword ptr 0Ch
.text:080485E3
.text:080485E3 push ebp
.text:080485E4 mov ebp, esp
.text:080485E6 sub esp, 8
.text:080485EC mov ecx, [ebp+arg_4] ; pseudo参数的长度
.text:080485EF mov esi, [ebp+arg_0];pseudo的起始地址
.text:080485F2 add esi, ecx ; pseudo参数的首地址+参数的长度
.text:080485F4 xor eax, eax
.text:080485F6 jmp loc_8048606 ;循环
.text:080485FB ; ---------------------------------------------------------------------------
.text:080485FB
.text:080485FB loc_80485FB: ; CODE XREF: sub_80485E3+2Aj
.text:080485FB dec esi ;pseudo地址++
.text:080485FC mov dl, [esi] ;将pseudo地址对应的值拷贝给dl
.text:080485FE and edx, 0FFh ;对edx高24位清零
.text:08048604 add eax, edx
.text:08048606
.text:08048606 loc_8048606: ; CODE XREF: sub_80485E3+13j
.text:08048606 dec ecx ;pseudo的长度--
.text:08048607 cmp ecx, 0FFFFFFFFh;pseudo的长度不等于-1,继续循环
.text:0804860D jnz short loc_80485FB
.text:0804860F xor al, 4Fh
.text:08048611 and eax, 3Fh
.text:08048616 leave
.text:08048617 retn 8
.text:08048617 sub_80485E3 endp
第三个处理函数:
.text:0804861A sub_804861A proc near ; CODE XREF: main+CCp
.text:0804861A
.text:0804861A arg_0 = dword ptr 8
.text:0804861A arg_4 = dword ptr 0Ch
.text:0804861A
.text:0804861A push ebp
.text:0804861B mov ebp, esp
.text:0804861D mov eax, 1
.text:08048622 mov esi, [ebp+arg_0] ;pseudo的起始地址
.text:08048625 mov ecx, [ebp+arg_4] ;pseudo的长度
.text:08048628 jmp loc_804863C ;循环
.text:0804862D ; ---------------------------------------------------------------------------
.text:0804862D
.text:0804862D loc_804862D: ; CODE XREF: sub_804861A+29j
.text:0804862D xor ebx, ebx
.text:0804862F mov bl, [esi] ;将pseudo地址对应的字符赋给bl
.text:08048631 and bl, 0FFh
.text:08048634 mul ebx ;eax:edx=eax*ebx
.text:08048636 and eax, 0FFh ;将eax高24位清零
.text:0804863B inc esi ;pseudo的起始地址++
.text:0804863C
.text:0804863C loc_804863C: ; CODE XREF: sub_804861A+Ej
.text:0804863C dec ecx ;pseudo的长度--
.text:0804863D cmp ecx, 0FFFFFFFFh ;pseudo的长度不等于-1,继续循环
.text:08048643 jnz short loc_804862D
.text:08048645 xor al, 55h
.text:08048647 and eax, 3Fh
.text:0804864C leave
.text:0804864D retn 8
.text:0804864D sub_804861A endp
第四个处理函数:
.text:08048650 sub_8048650 proc near ; CODE XREF: main+F7p
.text:08048650
.text:08048650 arg_0 = dword ptr 8
.text:08048650 arg_4 = dword ptr 0Ch
.text:08048650
.text:08048650 push ebp
.text:08048651 mov ebp, esp
.text:08048653 sub esp, 4
.text:08048659 mov esi, [ebp+arg_0] ; pseudo的起始地址
.text:0804865C mov al, [esi] ; 将pseudo的起始地址对应的值赋给al
.text:0804865E mov ecx, [ebp+arg_4] ; pseudo的长度
.text:08048661 jmp loc_804866F ; 循环
.text:08048666 ; ---------------------------------------------------------------------------
.text:08048666
.text:08048666 loc_8048666: ; CODE XREF: sub_8048650+26j
.text:08048666 inc esi ; pseudo起始地址++
.text:08048667 mov bl, [esi] ; 将pseudo地址对应的值赋给bl
.text:08048669 cmp bl, al
.text:0804866B jbe short loc_804866F
.text:0804866D mov al, bl ; 如果后一个字符大于前一个字符,则al等于后一个字符
.text:0804866F
.text:0804866F loc_804866F: ; CODE XREF: sub_8048650+11j
.text:0804866F ; sub_8048650+1Bj
.text:0804866F dec ecx
.text:08048670 cmp ecx, 0FFFFFFFFh
.text:08048676 jnz short loc_8048666 ; pseudo起始地址++
.text:08048678 xor al, 0Eh
.text:0804867A push eax ; seed
.text:0804867B call _srand
.text:08048680 call _rand ; 产生随机数
.text:08048685 and eax, 3Fh
.text:0804868A leave
.text:0804868B retn 8
.text:0804868B sub_8048650 endp
第五个处理函数:
.text:0804868E sub_804868E proc near ; CODE XREF: main+122p
.text:0804868E
.text:0804868E arg_0 = dword ptr 8
.text:0804868E arg_4 = dword ptr 0Ch
.text:0804868E
.text:0804868E push ebp
.text:0804868F mov ebp, esp
.text:08048691 xor ebx, ebx
.text:08048693 mov esi, [ebp+arg_0] ; pseudo的起始地址
.text:08048696 mov ecx, [ebp+arg_4] ; pseudo的长度
.text:08048699 dec ecx
.text:0804869A jmp loc_80486BC
.text:0804869F ; ---------------------------------------------------------------------------
.text:0804869F
.text:0804869F loc_804869F: ; CODE XREF: sub_804868E+34j
.text:0804869F xor edx, edx
.text:080486A1 mov dl, [esi] ; 获得pseudo地址对应的字符
.text:080486A3 push ecx
.text:080486A4 push ebx
.text:080486A5 push 2
.text:080486AA push edx
.text:080486AB call sub_8048708 ; 调用另一个函数
.text:080486B0 pop ebx
.text:080486B1 pop ecx
.text:080486B2 add ebx, eax ; ebx等于ebx+上一个调用的函数返回的值
.text:080486B4 and ebx, 0FFh ; ebx高24位清零
.text:080486BA inc esi ; pseudo起始地址往后偏移一位
.text:080486BB dec ecx ; pseudo长度--
.text:080486BC
.text:080486BC loc_80486BC: ; CODE XREF: sub_804868E+Cj
.text:080486BC cmp ecx, 0FFFFFFFFh
.text:080486C2 jnz short loc_804869F
.text:080486C4 mov eax, ebx
.text:080486C6 xor al, 0EFh
.text:080486C8 and eax, 3Fh
.text:080486CD leave
.text:080486CE retn 8
.text:080486CE sub_804868E endp
5.2
.text:08048708 sub_8048708 proc near ; CODE XREF: sub_804868E+1Dp
.text:08048708
.text:08048708 arg_0 = dword ptr 8
.text:08048708 arg_4 = dword ptr 0Ch
.text:08048708
.text:08048708 push ebp
.text:08048709 mov ebp, esp
.text:0804870B mov ecx, [ebp+arg_4] ; 入参恒为2
.text:0804870E mov eax, 1
.text:08048713 cmp ecx, 0
.text:08048719 jz short locret_804872A
.text:0804871B mov ebx, [ebp+arg_0] ; 该入参对应的是pseudo对应的地址的值
.text:0804871E mul ebx ; eax:edx=eax*ebx
.text:08048720 jmp loc_8048727 ; pseudo长度--
.text:08048725 ; ---------------------------------------------------------------------------
.text:08048725
.text:08048725 loc_8048725: ; CODE XREF: sub_8048708+20j
.text:08048725 mul ebx ; 如果条件满足,继续相乘
.text:08048727
.text:08048727 loc_8048727: ; CODE XREF: sub_8048708+18j
.text:08048727 dec ecx ; pseudo长度--
.text:08048728 jnz short loc_8048725 ; 如果条件满足,继续相乘
.text:0804872A
.text:0804872A locret_804872A: ; CODE XREF: sub_8048708+11j
.text:0804872A leave
.text:0804872B retn 8
.text:0804872B sub_8048708 endp
第六个处理函数:
.text:080486D1 sub_80486D1 proc near ; CODE XREF: main+14Dp
.text:080486D1
.text:080486D1 arg_0 = dword ptr 8
.text:080486D1
.text:080486D1 push ebp
.text:080486D2 mov ebp, esp
.text:080486D4 xor eax, eax
.text:080486D6 mov esi, [ebp+arg_0]
.text:080486D9 cmp esi, 0 ; 首字符不为空
.text:080486DF jz short loc_80486FF
.text:080486E1 call _rand ; 随机数
.text:080486E6 mov ecx, [ebp+arg_0]
.text:080486E9 jmp loc_80486F5
.text:080486EE ; ---------------------------------------------------------------------------
.text:080486EE
.text:080486EE loc_80486EE: ; CODE XREF: sub_80486D1+25j
.text:080486EE push ecx
.text:080486EF call _rand ; 随机数
.text:080486F4 pop ecx
.text:080486F5
.text:080486F5 loc_80486F5: ; CODE XREF: sub_80486D1+18j
.text:080486F5 dec ecx
.text:080486F6 jnz short loc_80486EE
.text:080486F8 and eax, 0FFh ; eax高24位清零
.text:080486FD xor al, 0E5h ; al^=0xe5
.text:080486FF
.text:080486FF loc_80486FF: ; CODE XREF: sub_80486D1+Ej
.text:080486FF and eax, 3Fh
.text:08048704 leave
.text:08048705 retn 4
.text:08048705 sub_80486D1 endp
这6个函数的逻辑都比较简单,搞清楚了每个处理函数的逻辑,写一个注册机就比较简单了,下面是注册机的代码:
#include <stdio.h>
#include <string.h>
char *pszSource = "A-CHRDw87lNS0E9B2TibgpnMVys5XzvtOGJcYLU+4mjW6fxqZeF3Qa1rPhdKIouk";
int fun1(unsigned int uiPseudoLen)
{
uiPseudoLen &= 0xff;
uiPseudoLen ^= 0x3b;
uiPseudoLen &= 0x3f;
return uiPseudoLen;
}
int fun2(char *pszPseudo,unsigned int uiPseudoLen)
{
unsigned int uiPseudoLenTmp = uiPseudoLen;
char *pszPseudoTmp = pszPseudo;
char cFlag = 0;
int iRet = 0;
pszPseudoTmp += uiPseudoLenTmp;
for(uiPseudoLenTmp = (uiPseudoLen - 1); -1 != uiPseudoLenTmp; uiPseudoLenTmp--)
{
pszPseudoTmp--;
cFlag = *(char *)pszPseudoTmp;
iRet += cFlag;
}
iRet ^= 0x4f;
iRet &= 0x3f;
return iRet;
}
int fun3(char *pszPseudo,unsigned int uiPseudoLen)
{
unsigned int uiPseudoLenTmp = uiPseudoLen;
char *pszPseudoTmp = pszPseudo;
char cFlag = 0;
int iRet = 1;
for(uiPseudoLenTmp = (uiPseudoLen - 1); -1 != uiPseudoLenTmp; uiPseudoLenTmp--)
{
cFlag = 0;
cFlag = *(char *)pszPseudoTmp;
iRet = iRet * cFlag;
iRet &= 0xff;
pszPseudoTmp++;
}
iRet ^= 0x55;
iRet &= 0x3f;
return iRet;
}
int fun4(char *pszPseudo,unsigned int uiPseudoLen)
{
unsigned int uiPseudoLenTmp = uiPseudoLen;
char *pszPseudoTmp = pszPseudo;
char cPseudoTmp = *pszPseudoTmp;
char cFlag = 0;
int iRand = 0;
for(uiPseudoLenTmp = (uiPseudoLen - 1); -1 != uiPseudoLenTmp; uiPseudoLenTmp--)
{
pszPseudoTmp++;
cFlag = *pszPseudoTmp;
if (cFlag > cPseudoTmp)
{
cPseudoTmp = cFlag;
}
}
cPseudoTmp ^= 0x0e;
srand(cPseudoTmp);
iRand = rand();
iRand &= 0x3f;
return iRand;
}
int fun5_sta(char cPseudoFlag, unsigned int uiPseudoLen)
{
int iRet;
iRet = 1;
char cPseudoFlagTmp;
unsigned int uiPseudoLenTmp = uiPseudoLen;
if (0 != uiPseudoLenTmp)
{
cPseudoFlagTmp = cPseudoFlag;
iRet = iRet * cPseudoFlagTmp;
for(uiPseudoLenTmp = (uiPseudoLenTmp - 1); 0 != uiPseudoLenTmp; uiPseudoLenTmp--)
{
iRet = iRet * cPseudoFlagTmp;
}
}
return iRet;
}
int fun5(char *pszPseudo,unsigned int uiPseudoLen)
{
unsigned int uiPseudoLenTmp = uiPseudoLen;
char *pszPseudoTmp = pszPseudo;
char cPseudoFlag = 0;
int iRetTmp = 0;
int iRet = 0;
for(uiPseudoLenTmp = (uiPseudoLen - 1); -1 != uiPseudoLenTmp; uiPseudoLenTmp--)
{
cPseudoFlag = *pszPseudoTmp;
iRet = fun5_sta(cPseudoFlag,2);
iRetTmp += iRet;
iRetTmp &= 0xff;
pszPseudoTmp++;
}
iRet = iRetTmp;
iRet ^= 0xef;
iRet &= 0x3f;
return iRet;
}
int fun6(char cPseudoFlag)
{
char cPseudoFlagTmp = cPseudoFlag;
char cFlag = 0;
int iRand = 0;
if (0 != cPseudoFlagTmp)
{
rand();
for(cFlag = (cPseudoFlag - 1); cFlag != 0; cFlag--)
{
iRand = rand();
}
iRand &= 0xff;
iRand ^= 0xe5;
}
iRand &= 0x3f;
return iRand;
}
int main(int argc,char *argv[])
{
if (2 != argc)
{
fprintf(stderr,"Usage:%s <pseaudo> \n",argv[0]);
return -1;
}
char *pszPseudo = argv[1];
char szSerial[10];
szSerial[0] = '\0';
char *pszSerialTmp = szSerial;
unsigned int uiPseudoLen = 0;
int iRet = 0;
char *pszPseudoTmp = NULL;
uiPseudoLen = strlen(pszPseudo);
iRet = fun1(uiPseudoLen);
pszPseudoTmp = pszSource;
pszPseudoTmp += iRet;
*(pszSerialTmp++) = *pszPseudoTmp;
iRet = fun2(pszPseudo,uiPseudoLen);
pszPseudoTmp = pszSource;
pszPseudoTmp += iRet;
*(pszSerialTmp++) = *pszPseudoTmp;
iRet = fun3(pszPseudo,uiPseudoLen);
pszPseudoTmp = pszSource;
pszPseudoTmp += iRet;
*(pszSerialTmp++) = *pszPseudoTmp;
iRet = fun4(pszPseudo,uiPseudoLen);
pszPseudoTmp = pszSource;
pszPseudoTmp += iRet;
*(pszSerialTmp++) = *pszPseudoTmp;
iRet = fun5(pszPseudo,uiPseudoLen);
pszPseudoTmp = pszSource;
pszPseudoTmp += iRet;
*(pszSerialTmp++) = *pszPseudoTmp;
iRet = fun6(*pszPseudo);
pszPseudoTmp = pszSource;
pszPseudoTmp += iRet;
*(pszSerialTmp++) = *pszPseudoTmp;
*pszSerialTmp = '\0';
printf("serial:%s\n",szSerial);
return 0;
}
以上就是分析的过程,软件本身不复杂,只要耐心把函数看完,弄懂了每个字符实现的算法,写注册机就很简单。这篇破文没什么技术含量,权且当做自己的一个破解经历,鼓励自己不断学习。。。