【文章标题】: Wav Combiner V1.1.0.0340算法分析
【文章作者】: qifeon
【软件名称】: Wav Combiner V1.1.0.0340
【下载地址】: http://tele.skycn.com/soft/34436.html
【保护方式】: 注册码
【使用工具】: od,peid
【操作平台】: winxp2
【软件介绍】:  可以将多个wav波形文件拼接成一个wav文件.
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  一、peid检测为Microsoft Visual C++ 7.0,无壳。
  
  二、OD载入,F9运行,输入“qifeon,12345678”程序出现错误对话框,"Registration failed!"。F12暂停,双击工具栏“K”按钮,出现
  
  调用堆栈:     主线程
  地址       堆栈       函数过程 / 参数                       调用来自                      结构
  0009E480   77D19418   包含ntdll.KiFastSystemCallRet           USER32.77D19416               0009E4B4
  0009E484   77D2DBA8   USER32.WaitMessage                    USER32.77D2DBA3               0009E4B4
  0009E4B8   77D2593F   USER32.77D2DA19                       USER32.77D2593A               0009E4B4
  0009E4E0   77D3A91E   USER32.77D25889                       USER32.77D3A919               0009E4DC
  0009E7A0   77D3A284   USER32.SoftModalMessageBox            USER32.77D3A27F               0009E79C
  0009E8F0   77D661D3   USER32.77D3A10F                       USER32.77D661CE               0009E8EC
  0009E948   77D66278   USER32.MessageBoxTimeoutW             USER32.77D66273               0009E944
  0009E97C   77D50617   ? USER32.MessageBoxTimeoutA           USER32.77D50612               0009E978
  0009E99C   77D505CF   ? USER32.MessageBoxExA                USER32.77D505CA               0009E998
  0009E9A0   000406DE     hOwner = 000406DE ('Please registe
  0009E9A4   00445E08     Text = "Registration failed!"
  0009E9A8   00B224A0     Title = "WavCombiner"
  0009E9AC   00000030     Style = MB_OK|MB_ICONEXCLAMATION|M
  0009E9B0   00000000     LanguageID = 0 (LANG_NEUTRAL)
  0009E9B8   00438E24   ? USER32.MessageBoxA                  WavCombi.00438E1E             0009E9B4
  0009E9BC   000406DE     hOwner = 000406DE ('Please registe
  0009E9C0   00445E08     Text = "Registration failed!"
  0009E9C4   00B224A0     Title = "WavCombiner"
  0009E9C8   00000030     Style = MB_OK|MB_ICONEXCLAMATION|M
  0009EAF4   0041498C   ? WavCombi.00438E63                   WavCombi.00414987             0009EA58
  ***************************************************************************************************
  然后双击WavCombi.00414987,来到
  **************************************************************************************************
  00414979   . /E9 64E90100   jmp     004332E2
  0041497E   > |6A 00         push    0
  00414980   . |6A 00         push    0
  00414982   . |68 085E4400   push    00445E08                         ;  ASCII "Registration failed!"
  00414987   . |E8 D7440200   call    00438E63
  0041498C   . |5B            pop     ebx
  0041498D   . |5F            pop     edi
  0041498E   . |5E            pop     esi
  0041498F   . |5D            pop     ebp
  00414990   . |83C4 0C       add     esp, 0C
  00414993   . |C3            retn
  ****************************************************************************************************
  向上可以找到段首,即注册按钮事件。
  ****************************************************************************************************
  
  004146C3   .  55            push    ebp                            段首
  004146C4   .  56            push    esi
  004146C5   .  57            push    edi
  004146C6   .  BF 01000000   mov     edi, 1
  004146CB   .  57            push    edi
  004146CC   .  8BF1          mov     esi, ecx
  004146CE   .  E8 7DAC0100   call    0042F350
  004146D3   .  8B46 70       mov     eax, dword ptr [esi+70]          ;  用户名
  004146D6   .  8B68 F4       mov     ebp, dword ptr [eax-C]           ;  用户名长度
  004146D9   .  83FD 02       cmp     ebp, 2                           ;  不小于2位
  004146DC   .  7D 15         jge     short 004146F3
  004146DE   .  6A 00         push    0
  004146E0   .  6A 00         push    0
  004146E2   .  68 645E4400   push    00445E64                         ;  ASCII "Please input correct User Name!"
  004146E7   .  E8 77470200   call    00438E63
  004146EC   .  5F            pop     edi
  004146ED   .  5E            pop     esi
  004146EE   .  5D            pop     ebp
  004146EF   .  83C4 0C       add     esp, 0C
  004146F2   .  C3            retn
  004146F3   >  8B4E 74       mov     ecx, dword ptr [esi+74]          ;  试炼码
  004146F6   .  8379 F4 08    cmp     dword ptr [ecx-C], 8             ;  不小于8位
  004146FA   .  7D 15         jge     short 00414711
  004146FC   .  6A 00         push    0
  004146FE   .  6A 00         push    0
  00414700   .  68 3C5E4400   push    00445E3C                         ;  ASCII "Please input correct Registration Code!"
  00414705   .  E8 59470200   call    00438E63
  0041470A   .  5F            pop     edi
  0041470B   .  5E            pop     esi
  0041470C   .  5D            pop     ebp
  0041470D   .  83C4 0C       add     esp, 0C
  00414710   .  C3            retn
  00414711   >  8B46 70       mov     eax, dword ptr [esi+70]          ;  用户名送入EAX
  00414714   .  8B48 F4       mov     ecx, dword ptr [eax-C]           ;  试炼码送入ECX
  00414717   .  85C9          test    ecx, ecx
  00414719   .  7D 0A         jge     short 00414725
  0041471B   .  68 57000780   push    80070057
  00414720   .  E8 CBCBFEFF   call    004012F0
  00414725   >  8A10          mov     dl, byte ptr [eax]               ;  用户名第1位送入DL
  00414727   .  8B46 70       mov     eax, dword ptr [esi+70]
  0041472A   .  3978 F4       cmp     dword ptr [eax-C], edi           ;  用户名长度大于等于1则跳
  0041472D   .  7D 0A         jge     short 00414739
  0041472F   .  68 57000780   push    80070057
  00414734   .  E8 B7CBFEFF   call    004012F0
  00414739   >  8A40 01       mov     al, byte ptr [eax+1]             ;  用户名2位送入al
  0041473C   .  884424 0E     mov     byte ptr [esp+E], al
  00414740   .  8B46 70       mov     eax, dword ptr [esi+70]
  00414743   .  8B48 F4       mov     ecx, dword ptr [eax-C]
  00414746   .  85C9          test    ecx, ecx
  00414748   .  7D 0A         jge     short 00414754
  0041474A   .  68 57000780   push    80070057
  0041474F   .  E8 9CCBFEFF   call    004012F0
  00414754   >  8B4E 70       mov     ecx, dword ptr [esi+70]
  00414757   .  53            push    ebx
  00414758   .  8A18          mov     bl, byte ptr [eax]               ;  用户名第1位送入bl
  0041475A   .  3979 F4       cmp     dword ptr [ecx-C], edi
  0041475D   .  7D 0A         jge     short 00414769
  0041475F   .  68 57000780   push    80070057
  00414764   .  E8 87CBFEFF   call    004012F0
  00414769   >  0FB6C2        movzx   eax, dl                          ;  用户名第1位扩展送入eax
  0041476C   .  83C8 57       or      eax, 57                          ;  与57H相或
  0041476F   .  99            cdq                                      ;  edx清零
  00414770   .  BF 0A000000   mov     edi, 0A                          ;  设余数为yu1
  00414775   .  F7FF          idiv    edi                              ;  eax/edi
  00414777   .  0FB64424 12   movzx   eax, byte ptr [esp+12]           ;  用户名第2位扩展送入eax
  0041477C   .  83C8 41       or      eax, 41                          ;  与41H相或
  0041477F   .  885424 16     mov     byte ptr [esp+16], dl            ;  余数yu1送入[esp+16]
  00414783   .  99            cdq
  00414784   .  F7FF          idiv    edi                              ;  设余数为yu2
  00414786   .  0FB6C3        movzx   eax, bl                          ;  用户名首位扩展送入eax
  00414789   .  83C8 56       or      eax, 56                          ;  与56H相或
  0041478C   .  885424 12     mov     byte ptr [esp+12], dl            ;  余数yu2送入[esp+12]
  00414790   .  99            cdq
  00414791   .  F7FF          idiv    edi                              ;  设余数为yu3
  00414793   .  0FB641 01     movzx   eax, byte ptr [ecx+1]            ;  用户名第2位扩展送入eax
  00414797   .  83C8 4A       or      eax, 4A                          ;  与4AH相或
  0041479A   .  8BCF          mov     ecx, edi                         ;  使ECX值为10
  0041479C   .  885424 17     mov     byte ptr [esp+17], dl            ;  余数yu3送入[esp+17]
  004147A0   .  99            cdq
  004147A1   .  F7F9          idiv    ecx                              ;  设余数为yu4
  004147A3   .  33C0          xor     eax, eax
  004147A5   .  33C9          xor     ecx, ecx
  004147A7   .  85ED          test    ebp, ebp
  004147A9   .  885424 18     mov     byte ptr [esp+18], dl            ;  余数yu4送入[esp+18]
  004147AD   .  7E 20         jle     short 004147CF
  004147AF   .  90            nop
  004147B0   >  85C9          test    ecx, ecx
  004147B2   .  0F8C D2000000 jl      0041488A
  004147B8   .  8B7E 70       mov     edi, dword ptr [esi+70]
  004147BB   .  3B4F F4       cmp     ecx, dword ptr [edi-C]           ;  循环长度与用户名比较
  004147BE   .  0F8F C6000000 jg      0041488A
  004147C4   .  0FB6140F      movzx   edx, byte ptr [edi+ecx]          ;  用户名依次扩展送入edx
  004147C8   .  03C2          add     eax, edx                         ;  用户名值依次相加设为sum保存于EAX
  004147CA   .  41            inc     ecx                              ;  循环次数加1
  004147CB   .  3BCD          cmp     ecx, ebp                         ;  与用户名长度比较
  004147CD   .^ 7C E1         jl      short 004147B0
  004147CF   >  8B4E 74       mov     ecx, dword ptr [esi+74]          ;  试炼码
  004147D2   .  8B51 F4       mov     edx, dword ptr [ecx-C]           ;  长度
  004147D5   .  85D2          test    edx, edx
  004147D7   .  7D 0A         jge     short 004147E3
  004147D9   .  68 57000780   push    80070057
  004147DE   .  E8 0DCBFEFF   call    004012F0
  004147E3   >  8A11          mov     dl, byte ptr [ecx]               ;  试炼码第1位送入DL
  004147E5   .  8B4E 74       mov     ecx, dword ptr [esi+74]
  004147E8   .  8379 F4 01    cmp     dword ptr [ecx-C], 1
  004147EC   .  885424 19     mov     byte ptr [esp+19], dl            ;  dl值送入[esp+19]
  004147F0   .  7D 0A         jge     short 004147FC
  004147F2   .  68 57000780   push    80070057
  004147F7   .  E8 F4CAFEFF   call    004012F0
  004147FC   >  8A49 01       mov     cl, byte ptr [ecx+1]             ;  试炼码第2位送入cl
  004147FF   .  8B7E 74       mov     edi, dword ptr [esi+74]
  00414802   .  884C24 13     mov     byte ptr [esp+13], cl            ;  cl值送入[esp+13]
  00414806   .  837F F4 02    cmp     dword ptr [edi-C], 2
  0041480A   .  7D 0A         jge     short 00414816
  0041480C   .  68 57000780   push    80070057
  00414811   .  E8 DACAFEFF   call    004012F0
  00414816   >  8A4F 02       mov     cl, byte ptr [edi+2]             ;  试炼码第3位送入cl
  00414819   .  8B7E 74       mov     edi, dword ptr [esi+74]
  0041481C   .  884C24 14     mov     byte ptr [esp+14], cl            ;  cl值送入[esp+14]
  00414820   .  837F F4 03    cmp     dword ptr [edi-C], 3
  00414824   .  7D 0A         jge     short 00414830
  00414826   .  68 57000780   push    80070057
  0041482B   .  E8 C0CAFEFF   call    004012F0
  00414830   >  8A4F 03       mov     cl, byte ptr [edi+3]             ;  试炼码第4位送入cl
  00414833   .  8B7E 74       mov     edi, dword ptr [esi+74]
  00414836   .  884C24 15     mov     byte ptr [esp+15], cl            ;  cl值送入[esp+15]
  0041483A   .  837F F4 04    cmp     dword ptr [edi-C], 4
  0041483E   .  7D 0A         jge     short 0041484A
  00414840   .  68 57000780   push    80070057
  00414845   .  E8 A6CAFEFF   call    004012F0
  0041484A   >  8A5F 04       mov     bl, byte ptr [edi+4]             ;  试炼码第5位送入bl
  0041484D   .  8B7E 74       mov     edi, dword ptr [esi+74]
  00414850   .  837F F4 05    cmp     dword ptr [edi-C], 5
  00414854   .  7D 0A         jge     short 00414860
  00414856   .  68 57000780   push    80070057
  0041485B   .  E8 90CAFEFF   call    004012F0
  00414860   >  8A4F 05       mov     cl, byte ptr [edi+5]             ;  试炼码第6位送入cl
  00414863   .  8B7E 74       mov     edi, dword ptr [esi+74]
  00414866   .  884C24 1A     mov     byte ptr [esp+1A], cl            ;  cl值送入[esp+1A]
  0041486A   .  837F F4 06    cmp     dword ptr [edi-C], 6
  0041486E   .  7D 0A         jge     short 0041487A
  00414870   .  68 57000780   push    80070057
  00414875   .  E8 76CAFEFF   call    004012F0
  0041487A   >  8A4F 06       mov     cl, byte ptr [edi+6]             ;  试炼码第7位送入cl
  0041487D   .  8B7E 74       mov     edi, dword ptr [esi+74]
  00414880   .  884C24 1B     mov     byte ptr [esp+1B], cl            ;  cl值送入[esp+1B]
  00414884   .  837F F4 07    cmp     dword ptr [edi-C], 7
  00414888   .  7D 0A         jge     short 00414894
  0041488A   >  68 57000780   push    80070057
  0041488F   .  E8 5CCAFEFF   call    004012F0
  00414894   >  8A4F 07       mov     cl, byte ptr [edi+7]             ;  试炼码第8位送入cl
  00414897   .  0FB67C24 16   movzx   edi, byte ptr [esp+16]           ;  余数yu1扩展送入edi
  0041489C   .  0FB6D2        movzx   edx, dl                          ;  试炼码第1位扩充送入edx
  0041489F   .  83EA 30       sub     edx, 30                          ;  edx减去30h
  004148A2   .  3BFA          cmp     edi, edx                         ;  试炼码首位16进制值是否等于yu1+30h
  004148A4   .  75 48         jnz     short 004148EE                   ;  这里的跳转产生2组注册码可能
  004148A6   .  0FB65424 13   movzx   edx, byte ptr [esp+13]
  004148AB   .  0FB67C24 12   movzx   edi, byte ptr [esp+12]
  004148B0   .  83EA 30       sub     edx, 30
  004148B3   .  3BFA          cmp     edi, edx                         ;  试炼码第2位16进制值是否等于yu2+30h
  004148B5   .  75 37         jnz     short 004148EE
  004148B7   .  0FB65424 14   movzx   edx, byte ptr [esp+14]
  004148BC   .  0FB67C24 17   movzx   edi, byte ptr [esp+17]
  004148C1   .  83EA 30       sub     edx, 30
  004148C4   .  3BFA          cmp     edi, edx                         ;  试炼码第3位16进制值是否等于yu3+30h
  004148C6   .  75 26         jnz     short 004148EE
  004148C8   .  0FB65424 15   movzx   edx, byte ptr [esp+15]
  004148CD   .  0FB67C24 18   movzx   edi, byte ptr [esp+18]
  004148D2   .  83EA 30       sub     edx, 30
  004148D5   .  3BFA          cmp     edi, edx                         ;  试炼码第4位16进制值是否等于yu4+30h
  004148D7   .  75 15         jnz     short 004148EE
  004148D9   .  99            cdq
  004148DA   .  BF 0A000000   mov     edi, 0A
  004148DF   .  F7FF          idiv    edi
  004148E1   .  0FB6C2        movzx   eax, dl                          ;  用户名值之和sum/10的余数yu5
  004148E4   .  0FB6D3        movzx   edx, bl                          ;  试炼码第5位
  004148E7   .  83EA 30       sub     edx, 30
  004148EA   .  3BC2          cmp     eax, edx                         ;  试炼码第5位16进制值是否等于yu0+30h
  004148EC   .  74 3A         je      short 00414928
  004148EE   >  807C24 19 35  cmp     byte ptr [esp+19], 35            ;  [esp+19]即试炼码第1位是否等于35h
  004148F3   .  0F85 85000000 jnz     0041497E
  004148F9   .  8A5424 13     mov     dl, byte ptr [esp+13]
  004148FD   .  B0 33         mov     al, 33
  004148FF   .  3AD0          cmp     dl, al                           ;  试炼码第2位16进制值是否等于33h
  00414901   .  75 7B         jnz     short 0041497E
  00414903   .  384424 14     cmp     byte ptr [esp+14], al            ;  试炼码第3位16进制值是否等于33h
  00414907   .  75 75         jnz     short 0041497E
  00414909   .  807C24 15 39  cmp     byte ptr [esp+15], 39            ;  试炼码第4位16进制值是否等于39h
  0041490E   .  75 6E         jnz     short 0041497E
  00414910   .  80FB 37       cmp     bl, 37                           ;  试炼码第5位16进制值是否等于37h
  00414913   .  75 69         jnz     short 0041497E
  00414915   .  807C24 1A 36  cmp     byte ptr [esp+1A], 36            ;  试炼码第6位16进制值是否等于36h
  0041491A   .  75 62         jnz     short 0041497E
  0041491C   .  807C24 1B 32  cmp     byte ptr [esp+1B], 32            ;  试炼码第7位16进制值是否等于32h
  00414921   .  75 5B         jnz     short 0041497E
  00414923   .  80F9 39       cmp     cl, 39                           ;  试炼码第8位16进制值是否等于39h
  00414926   .  75 56         jnz     short 0041497E
  00414928   >  6A 00         push    0
  0041492A   .  6A 00         push    0
  0041492C   .  68 205E4400   push    00445E20                         ;  ASCII "Registration has succeeded!"
  00414931   .  E8 2D450200   call    00438E63
  00414936   .  8B7E 70       mov     edi, dword ptr [esi+70]
  00414939   .  E8 0E840200   call    0043CD4C
  0041493E   .  8B40 04       mov     eax, dword ptr [eax+4]
  00414941   .  57            push    edi
  00414942   .  68 84534400   push    00445384                         ;  ASCII "username"
  00414947   .  68 7C534400   push    0044537C                         ;  ASCII "Option"
  0041494C   .  8BC8          mov     ecx, eax
  0041494E   .  E8 16460200   call    00438F69
  00414953   .  8B7E 74       mov     edi, dword ptr [esi+74]
  00414956   .  E8 F1830200   call    0043CD4C
  0041495B   .  8B40 04       mov     eax, dword ptr [eax+4]
  0041495E   .  57            push    edi
  0041495F   .  68 68534400   push    00445368                         ;  ASCII "registration_code"
  00414964   .  68 7C534400   push    0044537C                         ;  ASCII "Option"
  00414969   .  8BC8          mov     ecx, eax
  0041496B   .  E8 F9450200   call    00438F69
  00414970   .  5B            pop     ebx
  00414971   .  5F            pop     edi
  00414972   .  8BCE          mov     ecx, esi
  00414974   .  5E            pop     esi
  00414975   .  5D            pop     ebp
  00414976   .  83C4 0C       add     esp, 0C
  00414979   .  E9 64E90100   jmp     004332E2
  0041497E   >  6A 00         push    0
  00414980   .  6A 00         push    0
  00414982   .  68 085E4400   push    00445E08                         ;  ASCII "Registration failed!"
  00414987   .  E8 D7440200   call    00438E63
  0041498C   .  5B            pop     ebx
  0041498D   .  5F            pop     edi
  0041498E   .  5E            pop     esi
  0041498F   .  5D            pop     ebp
  00414990   .  83C4 0C       add     esp, 0C
  00414993   .  C3            retn
  
  
  三、算法总结:
  
  1、用户名至少为2位,注册码至少为8位;
  
  2、注册码可以分为2组:
     为便于表达,分别设
    yu1=用户名第1位16进制 相或 57H ,然后除以10的余数;
    yu2=用户名第2位16进制 相或 41H ,然后除以10的余数;
    yu3=用户名第1位16进制 相或 56H ,然后除以10的余数;
    yu1=用户名第2位16进制 相或 4AH ,然后除以10的余数;
    yu5=用户名值16进制之和sum/10的余数;
  
  a;当注册码第1位等于用户名yu1的十进制时:
  
    注册码第2位等于用户名yu2的十进制;
    注册码第3位等于用户名yu3的十进制;
    注册码第4位等于用户名yu4的十进制;
    注册码第5位等于用户名yu5的十进制;
  
    从第6位开始注册码任意,只要满足总位数不小于8位即可。
  
  b.当注册码第1位不等于用户名yu1的十进制时:
  
   注册码是一组固定码:53397629
  
  
  四。C算法注册机源码,这里注册码固定为8位,6到8位定为123。
  
  
  #include "stdio.h"
  #include "string.h"
  void main()
  {int sum=0,len,i,yu1,yu2,yu3,yu4,yu5;
    char name[20];
    printf("请输入用户名:");
    scanf("%s",name);
    len=strlen(name);
    if (len>=2)
    {for (i=0;i<len;i++)
    sum=sum+name[i];
    yu5=sum % 10;
    yu1=(name[0] | 0x57) % 10;
    yu2=(name[1] | 0x41) % 10;
    yu3=(name[0] | 0x56) % 10;
    yu4=(name[1] | 0x4A) % 10;
    printf("注册码是:");
    printf("%d%d%d%d%d%d",yu1,yu2,yu3,yu4,yu5,123);}
    else
    printf("用户名至少为2位。\n");
    system("PAUSE");
      
  }
  
--------------------------------------------------------------------------------
                                              2008年08月02日 16:13:57