【文章标题】: 2nd Speech Center3.30 算法分析
【文章作者】: qifeon
【软件名称】: 2nd Speech Center
【下载地址】: http://www.onlinedown.net/soft/25446.htm
【加壳方式】: ASPack 
【保护方式】: 壳+注册码
【编写语言】: English
【使用工具】: od,peid
【软件介绍】: 将任何文本转换成声音或MP3/WAVE音频文件的工具。2n
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  一、调试分析过程
  
  peid查壳为ASPack 2.12 -> Alexey Solodovnikov,懒得脱了,带壳调试。od载入,输入“qifeon,123456”,出现错误提示。F12暂停。观察调用堆栈
  
  ************************************************************************************************************************************************************
  
  调用堆栈:     主线程
  地址       堆栈       函数过程 / 参数                       调用来自                      结构
  0012F614   77D19418   包含ntdll.KiFastSystemCallRet           user32.77D19416               0012F648
  0012F618   77D2DBA8   user32.WaitMessage                    user32.77D2DBA3               0012F648
  0012F64C   77D2593F   user32.77D2DA19                       user32.77D2593A               0012F648
  0012F674   77D3A91E   user32.77D25889                       user32.77D3A919               0012F670
  0012F934   77D3A284   user32.SoftModalMessageBox            user32.77D3A27F               0012F930
  0012FA84   77D661D3   user32.77D3A10F                       user32.77D661CE               0012FA80
  0012FADC   77D66278   user32.MessageBoxTimeoutW             user32.77D66273               0012FAD8
  0012FB10   77D50617   ? user32.MessageBoxTimeoutA           user32.77D50612               0012FB0C
  0012FB30   77D505CF   ? user32.MessageBoxExA                user32.77D505CA               0012FB2C
  0012FB34   000A0340     hOwner = 000A0340 ('2nd Speech Cen
  0012FB38   00601E3C     Text = "Registered Code Error!"
  0012FB3C   010963A8     Title = "iisc"
  0012FB40   00000010     Style = MB_OK|MB_ICONHAND|MB_APPLM
  0012FB44   00000000     LanguageID = 0 (LANG_NEUTRAL)
  0012FB4C   004A5F0F   ? iisc.00408048                       iisc.004A5F0A                 0012FB48
  0012FB50   000A0340     hOwner = 000A0340 ('2nd Speech Cen
  0012FB54   00601E3C     Text = "Registered Code Error!"
  0012FB58   010963A8     Title = "iisc"
  0012FB5C   00000010     Style = MB_OK|MB_ICONHAND|MB_APPLM
  0012FB7C   004A5F3E   ? iisc.004A5EC0                       iisc.004A5F39                 0012FB78
  0012FB80   00601D3B   iisc.004A5F34                         iisc.00601D36                 0012FBB0
  
  *********************************************************************************************************************************************************************
  
  双击 iisc.00601D36  返回后向上找到段首
  
  **********************************************************************************************************************************************************************
  
  00601C69    55              push    ebp                            段首
  00601C6A    68 6B1D6000     push    00601D6B
  00601C6F    64:FF30         push    dword ptr fs:[eax]
  00601C72    64:8920         mov     dword ptr fs:[eax], esp
  00601C75    8D55 F4         lea     edx, dword ptr [ebp-C]
  00601C78    8B83 1C030000   mov     eax, dword ptr [ebx+31C]
  00601C7E    E8 3940EFFF     call    004F5CBC
  00601C83    8B45 F4         mov     eax, dword ptr [ebp-C]
  00601C86    8D55 FC         lea     edx, dword ptr [ebp-4]
  00601C89    E8 1E7DE0FF     call    004099AC
  00601C8E    8D55 F0         lea     edx, dword ptr [ebp-10]
  00601C91    8B83 20030000   mov     eax, dword ptr [ebx+320]
  00601C97    E8 2040EFFF     call    004F5CBC
  00601C9C    8B45 F0         mov     eax, dword ptr [ebp-10]          ; 试炼码
  00601C9F    8D55 F8         lea     edx, dword ptr [ebp-8]
  00601CA2    E8 057DE0FF     call    004099AC
  00601CA7    837D FC 00      cmp     dword ptr [ebp-4], 0             ; 用户名是否为空?
  00601CAB    0F84 80000000   je      00601D31
  00601CB1    837D F8 00      cmp     dword ptr [ebp-8], 0             ; 试炼码是否为空?
  00601CB5    74 7A           je      short 00601D31
  00601CB7    8D45 EC         lea     eax, dword ptr [ebp-14]
  00601CBA    50              push    eax
  00601CBB    B9 801D6000     mov     ecx, 00601D80
  00601CC0    BA 8C1D6000     mov     edx, 00601D8C                    ; ASCII "2nd Speech Center"
  00601CC5    8B45 FC         mov     eax, dword ptr [ebp-4]
  00601CC8    E8 4BFAFFFF     call    00601718                         ; 算法CALL,待会进入
  00601CCD    8B55 EC         mov     edx, dword ptr [ebp-14]          ; 真正注册码
  00601CD0    8B45 F8         mov     eax, dword ptr [ebp-8]           ; 试炼码
  00601CD3    E8 E033E0FF     call    004050B8                         ; 比较
  00601CD8    75 57           jnz     short 00601D31                   ; 关键跳转
  00601CDA    C605 40BD6100 0>mov     byte ptr [61BD40], 1
  00601CE1    8B4D FC         mov     ecx, dword ptr [ebp-4]
  00601CE4    BA A81D6000     mov     edx, 00601DA8                    ; ASCII "RegName"
  00601CE9    B8 B81D6000     mov     eax, 00601DB8                    ; ASCII "\Software\Microsoft\02k\JJTD4"
  00601CEE    E8 5946EAFF     call    004A634C
  00601CF3    8B45 FC         mov     eax, dword ptr [ebp-4]
  00601CF6    8945 E4         mov     dword ptr [ebp-1C], eax
  00601CF9    C645 E8 0B      mov     byte ptr [ebp-18], 0B
  00601CFD    8D55 E4         lea     edx, dword ptr [ebp-1C]
  00601D00    33C9            xor     ecx, ecx
  00601D02    B8 E01D6000     mov     eax, 00601DE0                    ; ASCII "Congratulations! ",CR,LF,"This software is licensed to %s.",CR,LF,"Thanks for your supporting."
  00601D07    E8 5841EAFF     call    004A5E64
  00601D0C    8BC3            mov     eax, ebx
  00601D0E    E8 81DBE8FF     call    0048F894
  00601D13    A1 8C866100     mov     eax, dword ptr [61868C]
  00601D18    8338 00         cmp     dword ptr [eax], 0
  00601D1B    74 1E           je      short 00601D3B
  00601D1D    A1 8C866100     mov     eax, dword ptr [61868C]
  00601D22    8B00            mov     eax, dword ptr [eax]
  00601D24    8A15 40BD6100   mov     dl, byte ptr [61BD40]
  00601D2A    E8 C1A20000     call    0060BFF0
  00601D2F    EB 0A           jmp     short 00601D3B
  00601D31    B8 3C1E6000     mov     eax, 00601E3C                    ; ASCII "Registered Code Error!"
  00601D36    E8 F941EAFF     call    004A5F34                              返回处
  
  ***************************************************************************************************************************************************************************
  
  段首下硬件断点,重载,输入试炼码,断下后单步进入算法call    00601718
  
  ****************************************************************************************************************************************************************************
  
  00601718    55              push    ebp
  00601719    8BEC            mov     ebp, esp
  0060171B    51              push    ecx
  0060171C    B9 06000000     mov     ecx, 6
  00601721    6A 00           push    0
  00601723    6A 00           push    0
  00601725    49              dec     ecx
  00601726  ^ 75 F9           jnz     short 00601721
  00601728    874D FC         xchg    dword ptr [ebp-4], ecx
  0060172B    53              push    ebx
  0060172C    56              push    esi
  0060172D    57              push    edi
  0060172E    894D F4         mov     dword ptr [ebp-C], ecx
  00601731    8955 F8         mov     dword ptr [ebp-8], edx
  00601734    8945 FC         mov     dword ptr [ebp-4], eax
  00601737    8B45 FC         mov     eax, dword ptr [ebp-4]
  0060173A    E8 1D3AE0FF     call    0040515C
  0060173F    8B45 F8         mov     eax, dword ptr [ebp-8]
  00601742    E8 153AE0FF     call    0040515C
  00601747    8B45 F4         mov     eax, dword ptr [ebp-C]
  0060174A    E8 0D3AE0FF     call    0040515C
  0060174F    33C0            xor     eax, eax
  00601751    55              push    ebp
  00601752    68 8E186000     push    0060188E
  00601757    64:FF30         push    dword ptr fs:[eax]
  0060175A    64:8920         mov     dword ptr fs:[eax], esp
  0060175D    33C0            xor     eax, eax
  0060175F    55              push    ebp
  00601760    68 37186000     push    00601837
  00601765    64:FF30         push    dword ptr fs:[eax]
  00601768    64:8920         mov     dword ptr fs:[eax], esp
  0060176B    8D55 E8         lea     edx, dword ptr [ebp-18]
  0060176E    8B45 F8         mov     eax, dword ptr [ebp-8]
  00601771    E8 3682E0FF     call    004099AC
  00601776    8B45 E8         mov     eax, dword ptr [ebp-18]          ; 程序名字符串地址
  00601779    B1 01           mov     cl, 1                            ; cl=1
  0060177B    BA 6E740300     mov     edx, 3746E                       ; edx=0x3746E
  00601780    E8 87FEFFFF     call    0060160C                         ; 算法,待会进入
  00601785    8BD8            mov     ebx, eax                         ; 程序名字符串sn1计算取得值
  00601787    8D55 E4         lea     edx, dword ptr [ebp-1C]
  0060178A    8B45 F4         mov     eax, dword ptr [ebp-C]
  0060178D    E8 1A82E0FF     call    004099AC
  00601792    8B45 E4         mov     eax, dword ptr [ebp-1C]          ; 固定字符'3"(猜测是版本?)的地址
  00601795    33C9            xor     ecx, ecx                         ; 使cl=0
  00601797    BA 01EB0B00     mov     edx, 0BEB01                      ; 参与计算数0xBEB01 
  0060179C    E8 6BFEFFFF     call    0060160C                         ; 算法
  006017A1    8BF0            mov     esi, eax                         ; "3"运算后的值设为sn2
  006017A3    8D55 E0         lea     edx, dword ptr [ebp-20]
  006017A6    8B45 FC         mov     eax, dword ptr [ebp-4]
  006017A9    E8 FE81E0FF     call    004099AC
  006017AE    8B45 E0         mov     eax, dword ptr [ebp-20]          ; 用户名地址
  006017B1    B1 01           mov     cl, 1                            ; cl=1
  006017B3    8BD3            mov     edx, ebx                         ; sn1参与计算
  006017B5    E8 52FEFFFF     call    0060160C                         ; 关键
  006017BA    8BD8            mov     ebx, eax                         ; 取得值sn3
  006017BC    8D55 DC         lea     edx, dword ptr [ebp-24]
  006017BF    8B45 FC         mov     eax, dword ptr [ebp-4]
  006017C2    E8 E581E0FF     call    004099AC
  006017C7    8B45 DC         mov     eax, dword ptr [ebp-24]          ; 用户名地址
  006017CA    33C9            xor     ecx, ecx                         ; cl=0
  006017CC    8BD6            mov     edx, esi                         ; sn2参与计算
  006017CE    E8 39FEFFFF     call    0060160C                         ; 关键
  006017D3    8BF0            mov     esi, eax                         ; 取得值sn4
  006017D5    8D45 F0         lea     eax, dword ptr [ebp-10]
  006017D8    50              push    eax
  006017D9    8D55 D8         lea     edx, dword ptr [ebp-28]
  006017DC    8BC3            mov     eax, ebx
  006017DE    E8 2586E0FF     call    00409E08
  006017E3    8B45 D8         mov     eax, dword ptr [ebp-28]          ; sn3由整数转化为字符串reg
  006017E6    B9 05000000     mov     ecx, 5
  006017EB    BA 01000000     mov     edx, 1
  006017F0    E8 D739E0FF     call    004051CC                         ; 取reg前5位后得到字符串reg1
  006017F5    8D45 EC         lea     eax, dword ptr [ebp-14]
  006017F8    50              push    eax
  006017F9    8D55 D4         lea     edx, dword ptr [ebp-2C]
  006017FC    8BC6            mov     eax, esi
  006017FE    E8 0586E0FF     call    00409E08
  00601803    8B45 D4         mov     eax, dword ptr [ebp-2C]          ; sn4由整数转化为字符串code
  00601806    B9 05000000     mov     ecx, 5
  0060180B    BA 02000000     mov     edx, 2
  00601810    E8 B739E0FF     call    004051CC
  00601815    FF75 EC         push    dword ptr [ebp-14]               ; 取字符串code后5位得到字符串code1
  00601818    68 A8186000     push    006018A8
  0060181D    FF75 F0         push    dword ptr [ebp-10]
  00601820    8B45 08         mov     eax, dword ptr [ebp+8]
  00601823    BA 03000000     mov     edx, 3
  00601828    E8 FF37E0FF     call    0040502C
  0060182D    33C0            xor     eax, eax
  0060182F    5A              pop     edx
  00601830    59              pop     ecx
  00601831    59              pop     ecx
  00601832    64:8910         mov     dword ptr fs:[eax], edx
  00601835    EB 3C           jmp     short 00601873
  00601837  ^ E9 C82AE0FF     jmp     00404304
  0060183C    8D55 D0         lea     edx, dword ptr [ebp-30]
  0060183F    B8 6E740300     mov     eax, 3746E
  00601844    E8 BF85E0FF     call    00409E08
  00601849    FF75 D0         push    dword ptr [ebp-30]
  0060184C    68 A8186000     push    006018A8
  00601851    8D55 CC         lea     edx, dword ptr [ebp-34]
  00601854    B8 01EB0B00     mov     eax, 0BEB01
  00601859    E8 AA85E0FF     call    00409E08
  0060185E    FF75 CC         push    dword ptr [ebp-34]
  00601861    8B45 08         mov     eax, dword ptr [ebp+8]
  00601864    BA 03000000     mov     edx, 3
  00601869    E8 BE37E0FF     call    0040502C
  0060186E    E8 F92DE0FF     call    0040466C
  00601873    33C0            xor     eax, eax
  00601875    5A              pop     edx
  00601876    59              pop     ecx
  00601877    59              pop     ecx
  00601878    64:8910         mov     dword ptr fs:[eax], edx
  0060187B    68 95186000     push    00601895
  00601880    8D45 CC         lea     eax, dword ptr [ebp-34]
  00601883    BA 0D000000     mov     edx, 0D
  00601888    E8 3334E0FF     call    00404CC0                         ; "-"连接字符串code1和reg1
  
  
  *******************************************************************************************************************************************************
  
     00601780   处进入算法   call    0060160C  
  
  *******************************************************************************************************************************************************
  
  0060160C    55              push    ebp
  0060160D    8BEC            mov     ebp, esp
  0060160F    83C4 F4         add     esp, -0C
  00601612    53              push    ebx
  00601613    56              push    esi
  00601614    57              push    edi
  00601615    884D F7         mov     byte ptr [ebp-9], cl             ; cl值赋予 ebp-9
  00601618    8955 F8         mov     dword ptr [ebp-8], edx           ; 参与计算数保存于ebp-8
  0060161B    8945 FC         mov     dword ptr [ebp-4], eax           ; 程序名字符串地址保存于ebp-4
  0060161E    8B45 FC         mov     eax, dword ptr [ebp-4]
  00601621    E8 363BE0FF     call    0040515C
  00601626    33C0            xor     eax, eax
  00601628    55              push    ebp
  00601629    68 08176000     push    00601708
  0060162E    64:FF30         push    dword ptr fs:[eax]
  00601631    64:8920         mov     dword ptr fs:[eax], esp
  00601634    33C0            xor     eax, eax
  00601636    55              push    ebp
  00601637    68 D6166000     push    006016D6
  0060163C    64:FF30         push    dword ptr fs:[eax]
  0060163F    64:8920         mov     dword ptr fs:[eax], esp
  00601642    33DB            xor     ebx, ebx
  00601644    837D FC 00      cmp     dword ptr [ebp-4], 0
  00601648    74 70           je      short 006016BA
  0060164A    8B45 FC         mov     eax, dword ptr [ebp-4]
  0060164D    E8 1A39E0FF     call    00404F6C
  00601652    8BF0            mov     esi, eax                         ; 字符串长度
  00601654    85F6            test    esi, esi
  00601656    7E 3B           jle     short 00601693
  00601658    B9 01000000     mov     ecx, 1
  0060165D    807D F7 00      cmp     byte ptr [ebp-9], 0              ; 这里由[ebp-9],即cl是否为0,进入2种不同算法saunfa1和suanfa2
  00601661    74 15           je      short 00601678                      第一种算法suanfa1开始
  00601663    8BC1            mov     eax, ecx
  00601665    F7E8            imul    eax                              ; eax自乘
  00601667    03C0            add     eax, eax                         ; eax自加
  00601669    40              inc     eax                              ; eax增1
  0060166A    8B55 FC         mov     edx, dword ptr [ebp-4]           ; 字符串地址送入edx
  0060166D    0FB6540A FF     movzx   edx, byte ptr [edx+ecx-1]        ; 字符串逐位扩展送入edx
  00601672    F7EA            imul    edx                              ; eax=eax*edx
  00601674    03D8            add     ebx, eax                         ; ebx=ebx+eax,循环之和sum保存于ebx
  00601676    EB 17           jmp     short 0060168F
  00601678    8B45 FC         mov     eax, dword ptr [ebp-4]           ; 第二种算法saunfa2开始
  0060167B    0FB64408 FF     movzx   eax, byte ptr [eax+ecx-1]        ; 字符串逐位扩展送入eax
  00601680    F7E8            imul    eax                              ; eax自乘
  00601682    0FBFC0          movsx   eax, ax
  00601685    BF A0860100     mov     edi, 186A0                       ; edi=186A0h
  0060168A    99              cdq
  0060168B    F7FF            idiv    edi                              ; eax/edi
  0060168D    03DA            add     ebx, edx                            循环之和sum保存于ebx
  0060168F    41              inc     ecx                              ; ecx增1,控制取字符串字符的位置
  00601690    4E              dec     esi                              ; esi减1,控制循环次数
  00601691  ^ 75 CA           jnz     short 0060165D
  00601693    8BC3            mov     eax, ebx                         ; 字符串逐位计算后的值sum,送入eax
  00601695    B9 10270000     mov     ecx, 2710                        ; ecx=2710h
  0060169A    99              cdq                                      ; edx清零
  0060169B    F7F9            idiv    ecx                              ; eax/ecx,商保存于eax,余数保存在edx
  0060169D    8BC2            mov     eax, edx                         ; 余数送入eax
  0060169F    F7E8            imul    eax                              ; eax自乘
  006016A1    0345 F8         add     eax, dword ptr [ebp-8]           ; eax=eax+[ebp-8]
  006016A4    8BD8            mov     ebx, eax
  006016A6    8BC3            mov     eax, ebx
  006016A8    B9 A0860100     mov     ecx, 186A0                       ; ecx=186A0h
  006016AD    99              cdq                                      ; edx清零
  006016AE    F7F9            idiv    ecx                              ; eax/ecx
  006016B0    81C2 A0860100   add     edx, 186A0                       ; edx=余数+186A0h
  006016B6    8BDA            mov     ebx, edx                         ; 上面计算值sn送入ebx
  006016B8    EB 12           jmp     short 006016CC
  006016BA    807D F7 00      cmp     byte ptr [ebp-9], 0
  006016BE    74 07           je      short 006016C7
  006016C0    BB 6E740300     mov     ebx, 3746E
  006016C5    EB 05           jmp     short 006016CC
  006016C7    BB 01EB0B00     mov     ebx, 0BEB01
  006016CC    33C0            xor     eax, eax
  006016CE    5A              pop     edx
  006016CF    59              pop     ecx
  006016D0    59              pop     ecx
  006016D1    64:8910         mov     dword ptr fs:[eax], edx
  006016D4    EB 1C           jmp     short 006016F2
  006016D6  ^ E9 292CE0FF     jmp     00404304
  006016DB    807D F7 00      cmp     byte ptr [ebp-9], 0
  006016DF    74 07           je      short 006016E8
  006016E1    BB 6E740300     mov     ebx, 3746E
  006016E6    EB 05           jmp     short 006016ED
  006016E8    BB 01EB0B00     mov     ebx, 0BEB01
  006016ED    E8 7A2FE0FF     call    0040466C
  006016F2    33C0            xor     eax, eax
  006016F4    5A              pop     edx
  006016F5    59              pop     ecx
  006016F6    59              pop     ecx
  006016F7    64:8910         mov     dword ptr fs:[eax], edx
  006016FA    68 0F176000     push    0060170F
  006016FF    8D45 FC         lea     eax, dword ptr [ebp-4]
  00601702    E8 9535E0FF     call    00404C9C
  00601707    C3              retn
  00601708  ^ E9 AB2EE0FF     jmp     004045B8
  0060170D  ^ EB F0           jmp     short 006016FF
  0060170F    8BC3            mov     eax, ebx                         ; sn又传入eax
  00601711    5F              pop     edi
  00601712    5E              pop     esi
  00601713    5B              pop     ebx
  00601714    8BE5            mov     esp, ebp
  00601716    5D              pop     ebp
  00601717    C3              retn
  
  ***********************************************************************************************************************************************************
  
  二、算法总结
  
  注册码由2部分连接而成,每一部分经过2次运算而成。4次运算调用同一个算法CALL(call    0060160C ),这个算法CALL内部由传入参数cl值的不同,又分为2种算法,suanfa1和suanfa2
  
  
  ------------
  1、注册码第1部分
  
  a、固定字符"3"由suanfa2运算后的值设为sn2(cl=0,参与计算数0xBEB01);
  
  b、用户名name,由算法2suanfa2计算得到sn4( cl=0,参与计算数sn2);
  
  c、 sn4转化为字符串code;
  
  d、取code后5位后得到字符串code1,即注册码第2部分;
  
  
  2、注册码第2部分
  
  
  a、程序名“2nd Speech Cente'由suanfa1计算得到sn1(cl=1,参与计算数为0x3746E);
  
  b、用户名name,由算法1suanfa1计算得到sn3( cl=1,参与计算数为sn1);
  
  c、sn3转化为字符串reg;
  
  d、取reg前5位后得到字符串reg1,即注册码第2部分;
  
  
  3、第1和第2部分由”-“连接得到对应用户名的注册码。
  
  
  为缩短篇幅suanfa1和suanfa2可以参照注释和下面注册机部分。
  
  
  三、c 语言注册机源代码
  
  #include "stdio.h"
  #include "string.h"
  int suanfa1(string, c )
  char string[50];
  {  int a,b,sn,sum=0,len,i;
    len=strlen(string);
    for (i=0;i<len;i++)
    {   
      a=(i+1)*(i+1)*2+1;
      sum=sum+a*string[i];
      b=(sum % 10000)*(sum % 10000 )+c;
      sn=(b % 100000)+100000;
          
      }
    
    return(sn);
  }
  
  int suanfa2(string, c )
  char string[50];
  {
    int a,b,sn,sum=0,len,i;
    len=strlen(string);
     for (i=0;i<len;i++)
     {  
       a=string[i]*string[i];
       sum=sum+a % 100000;
       b=(sum % 10000)*(sum % 10000 )+c;
      sn=(b % 100000)+100000;
            
     }
     
    return(sn);  
    
    }
  
  void main()
  { 
    int sn1,sn2,sn3,sn4,constant,dd;
    char chengxu[30]="2nd Speech Center";
    char gd[20]="3";
    char name[20];
    char reg[20]="\0";
    char code[20]="\0";
    char reg1[20]="\0";
    char code1[20]="\0";
    printf("请输入用户名:");
    scanf("%s",name);
    constant=226414;
    dd=781057;
    sn1= suanfa1( chengxu,constant);
    sn2=suanfa2(gd,dd);
    sn3= suanfa1( name,sn1);
    sn4=suanfa2( name,sn2);
    itoa(sn4, code, 10); 
    itoa(sn3, reg, 10); 
      strncpy(reg1,reg,5);
      strncpy(code1,code+1,5);
      strcat(code1,"-");
      strcat(code1,reg1);
    printf("注册码是:");
    printf("%s",code1);
    system("PAUSE");
    
      
  }
  
  
--------------------------------------------------------------------------------