首页
社区
课程
招聘
[原创]一个简单的linux crackme分析
发表于: 2014-8-18 12:17 6214

[原创]一个简单的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;
}

以上就是分析的过程,软件本身不复杂,只要耐心把函数看完,弄懂了每个字符实现的算法,写注册机就很简单。这篇破文没什么技术含量,权且当做自己的一个破解经历,鼓励自己不断学习。。。


[培训]科锐逆向工程师培训第53期2025年7月8日开班!

上传的附件:
收藏
免费 3
支持
分享
最新回复 (1)
雪    币: 19
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
嗯,的确 Linux crackme 很难找
2014-10-16 14:55
0
游客
登录 | 注册 方可回帖
返回