【文章标题】: [原创]RealVNC Enterprice Edition 4.5算法分析
【文章作者】: wuwenyao
【作者邮箱】: wuwenyao.gm@gmail.com
【软件名称】: RealVNC Enterprice Edition 4.5
【下载地址】: http://www.realvnc.com/index.html
【加壳方式】: 未加壳
【编写语言】: C
【使用工具】: OllyDbg,peid,IDA
【操作平台】: win32
【软件介绍】: 远程控制软件,有免费版本,企业版需要注册
【作者声明】: 本文只是分析算法,不提供注册机,如果要使用,请向开发商购买。
--------------------------------------------------------------------------------
【详细过程】
  最近用到远程控制,试了几个VNC版本,发现还是最原始的RealVNC好用,不过企业是收费的:(,花了几天分析了一下算法。

  安装后,查看菜单,是使用"vncconfig.exe -noconsole -license"弹出注册码窗口,随便输入一个注册码,会弹出信息窗口提示注册错误。
  OD载入vncconfig.exe,参数-noconsole -license,F9运行后,下MessageBoxW断点,F7,F8,CTRL+F9几次就可以找到验证注册码的部分了,这里不再详述过程。
  下面看看算法过程:

  注册码验证主体
  
  .text:004084B0 ; =============== S U B R O U T I N E =======================================
  .text:004084B0
  .text:004084B0
  .text:004084B0 sub_4084B0      proc near               ; DATA XREF: .rdata:00459DC0o
  .text:004084B0
  .text:004084B0 var_2C          = dword ptr -2Ch
  .text:004084B0 var_28          = dword ptr -28h
  .text:004084B0 Args            = byte ptr -24h
  .text:004084B0 var_20          = dword ptr -20h
  .text:004084B0 Memory          = dword ptr -1Ch
  .text:004084B0 var_18          = dword ptr -18h
  .text:004084B0 var_14          = dword ptr -14h
  .text:004084B0 var_10          = dword ptr -10h
  .text:004084B0 var_C           = dword ptr -0Ch
  .text:004084B0 var_4           = dword ptr -4
  .text:004084B0
  .text:004084B0                 push    -1
  .text:004084B2                 push    offset sub_451258
  .text:004084B7                 mov     eax, large fs:0
  .text:004084BD                 push    eax
  .text:004084BE                 sub     esp, 20h
  .text:004084C1                 push    ebx
  .text:004084C2                 push    ebp
  .text:004084C3                 push    esi
  .text:004084C4                 push    edi
  .text:004084C5                 mov     eax, dword_472404
  .text:004084CA                 xor     eax, esp
  .text:004084CC                 push    eax
  .text:004084CD                 lea     eax, [esp+40h+var_C]
  .text:004084D1                 mov     large fs:0, eax
  .text:004084D7                 mov     edi, ecx
  .text:004084D9                 mov     [esp+40h+var_2C], edi
  .text:004084DD                 xor     ebx, ebx          ;ebx=0
  .text:004084DF                 push    ebx
  .text:004084E0                 lea     ecx, [edi+3Ch]
  .text:004084E3                 call    sub_41FDA0      ; 取注册码
  .text:004084E8                 push    eax
  .text:004084E9                 call    sub_416560      ; 注册码处理
  .text:004084EE                 mov     ebp, eax        ; C结构指针,C[0]指向通过验证的注册码特征码
  .text:004084F0                 add     esp, 4
  .text:004084F3                 mov     [esp+40h+var_28], ebp ; C指针放入v_28
  .text:004084F7                 mov     [esp+40h+Memory], ebx
  .text:004084FB                 mov     [esp+40h+var_18], ebx
  .text:004084FF                 cmp     ebp, ebx            ;C结构指针不为0,跳转,继续
  .text:00408501                 mov     [esp+40h+var_4], ebx
  .text:00408505                 jnz     short loc_40851C
  .text:00408507                 push    -1
  .text:00408509                 push    offset aTheSuppliedL_0 ; "The supplied license key is invalid. Yo"...
  .text:0040850E                 lea     ecx, [esp+48h+Memory]
  .text:00408512                 call    sub_40CBC0
  .text:00408517                 jmp     loc_40870C
  .text:0040851C ; ---------------------------------------------------------------------------
  .text:0040851C
  .text:0040851C loc_40851C:                             ; CODE XREF: sub_4084B0+55j
  .text:0040851C                 mov     ecx, ebp
  .text:0040851E                 call    sub_4165C0      ; C与当前时候校验
  .text:00408523                 test    al, al                 ;返回不为0,跳转,继续
  .text:00408525                 jz      short loc_40853C
  .text:00408527                 push    -1
  .text:00408529                 push    offset aTheSuppliedTri ; "The supplied trial license key has expi"...
  .text:0040852E                 lea     ecx, [esp+48h+Memory]
  .text:00408532                 call    sub_40CBC0
  .text:00408537                 jmp     loc_4086F1
  .text:0040853C ; ---------------------------------------------------------------------------
  .text:0040853C
  .text:0040853C loc_40853C:                             ; CODE XREF: sub_4084B0+75j
  .text:0040853C                 mov     ecx, ds:dword_45AEF0   ;固定值,时间低位
  .text:00408542                 mov     eax, ds:dword_45AEF4   ;固定值,时间高位
  .text:00408547                 sub     ecx, 1E28500h   ; 366天(一年)
  .text:0040854D                 sbb     eax, ebx
  .text:0040854F                 cmp     eax, [ebp+1Ch]  ; [45AEF4]与C[0x1C]比较
  .text:00408552                 jl      short loc_408570 ; 小于继续
  .text:00408554                 jg      short loc_40855B
  .text:00408556                 cmp     ecx, [ebp+18h]  ; [45AEF0]-0x1E28500与C[0x18]比较
  .text:00408559                 jb      short loc_408570 ; 小于继续
  .text:0040855B
  .text:0040855B loc_40855B:                             ; CODE XREF: sub_4084B0+A4j
  .text:0040855B                 push    -1
  .text:0040855D                 push    offset aTheSuppliedL_1 ; "The supplied license key is not valid f"...
  .text:00408562                 lea     ecx, [esp+48h+Memory]
  .text:00408566                 call    sub_40CBC0
  .text:0040856B                 jmp     loc_4086F1
  .text:00408570 ; ---------------------------------------------------------------------------
  .text:00408570
  .text:00408570 loc_408570:                             ; CODE XREF: sub_4084B0+A2j
  .text:00408570                                         ; sub_4084B0+A9j
  .text:00408570                 mov     esi, [ebp+0]            ;C[0]
  .text:00408573                 mov     edi, [edi+50h]         ;特征码0
  .text:00408576                 mov     ecx, esi
  .text:00408578                 mov     eax, edi
  .text:0040857A                 lea     ebx, [ebx+0]
  .text:00408580
  .text:00408580 loc_408580:                             ; CODE XREF: sub_4084B0+EAj
  .text:00408580                 mov     dl, [eax]       ; 比较特征码
  .text:00408582                 cmp     dl, [ecx]
  .text:00408584                 jnz     short loc_4085A0
  .text:00408586                 cmp     dl, bl             ;判断结束符0
  .text:00408588                 jz      short loc_40859C
  .text:0040858A                 mov     dl, [eax+1]
  .text:0040858D                 cmp     dl, [ecx+1]
  .text:00408590                 jnz     short loc_4085A0
  .text:00408592                 add     eax, 2
  .text:00408595                 add     ecx, 2
  .text:00408598                 cmp     dl, bl
  .text:0040859A                 jnz     short loc_408580
  .text:0040859C
  .text:0040859C loc_40859C:                             ; CODE XREF: sub_4084B0+D8j
  .text:0040859C                 xor     eax, eax      ;相等,则eax置0
  .text:0040859E                 jmp     short loc_4085A5
  .text:004085A0 ; ---------------------------------------------------------------------------
  .text:004085A0
  .text:004085A0 loc_4085A0:                             ; CODE XREF: sub_4084B0+D4j
  .text:004085A0                                         ; sub_4084B0+E0j
  .text:004085A0                 sbb     eax, eax
  .text:004085A2                 sbb     eax, 0FFFFFFFFh;不等,则eax置1
  .text:004085A5
  .text:004085A5 loc_4085A5:                             ; CODE XREF: sub_4084B0+EEj
  .text:004085A5                 cmp     eax, ebx
  .text:004085A7                 jz      loc_4086ED     ;相等(eax=0),跳出,不等,继续
  .text:004085AD                 mov     ebp, off_470DB8     ;特征码1
  .text:004085B3                 mov     eax, offset aVncEnterpriseE ; "VNC Enterprise Edition for Windows"
  .text:004085B8                 mov     [esp+40h+var_10], edi
  .text:004085BC                 mov     dword ptr [esp+40h+Args], eax
  .text:004085C0                 mov     [esp+40h+var_20], eax
  .text:004085C4                 mov     [esp+40h+var_14], esi
  .text:004085C8                 xor     edi, edi
  .text:004085CA                 lea     ebx, [ebx+0]
  .text:004085D0
  .text:004085D0 loc_4085D0:                             ; CODE XREF: sub_4084B0+217j
  .text:004085D0                 mov     esi, [esp+edi+40h+var_14]
  .text:004085D4                 mov     ecx, ebp
  .text:004085D6                 mov     eax, esi
  .text:004085D8
  .text:004085D8 loc_4085D8:                             ; CODE XREF: sub_4084B0+142j
  .text:004085D8                 mov     dl, [eax]       ; 比较特征码
  .text:004085DA                 cmp     dl, [ecx]
  .text:004085DC                 jnz     short loc_4085F8
  .text:004085DE                 cmp     dl, bl
  .text:004085E0                 jz      short loc_4085F4
  .text:004085E2                 mov     dl, [eax+1]
  .text:004085E5                 cmp     dl, [ecx+1]
  .text:004085E8                 jnz     short loc_4085F8
  .text:004085EA                 add     eax, 2
  .text:004085ED                 add     ecx, 2
  .text:004085F0                 cmp     dl, bl
  .text:004085F2                 jnz     short loc_4085D8
  .text:004085F4
  .text:004085F4 loc_4085F4:                             ; CODE XREF: sub_4084B0+130j
  .text:004085F4                 xor     eax, eax
  .text:004085F6                 jmp     short loc_4085FD
  .text:004085F8 ; ---------------------------------------------------------------------------
  .text:004085F8
  .text:004085F8 loc_4085F8:                             ; CODE XREF: sub_4084B0+12Cj
  .text:004085F8                                         ; sub_4084B0+138j
  .text:004085F8                 sbb     eax, eax
  .text:004085FA                 sbb     eax, 0FFFFFFFFh
  .text:004085FD
  .text:004085FD loc_4085FD:                             ; CODE XREF: sub_4084B0+146j
  .text:004085FD                 cmp     eax, ebx
  .text:004085FF                 jnz     short loc_40860E     ;相等(eax=0),继续,不等,跳到下个比较
  .text:00408601                 mov     dword ptr [esp+edi+40h+Args], offset aVncPersonalEdi ; "VNC Personal Edition for Windows"
  .text:00408609                 jmp     loc_4086C1           ;转到提示版本不同信息
  .text:0040860E ; ---------------------------------------------------------------------------
  .text:0040860E
  .text:0040860E loc_40860E:                             ; CODE XREF: sub_4084B0+14Fj
  .text:0040860E                 mov     ecx, off_470DB4      ;特征码2
  .text:00408614                 mov     eax, esi
  .text:00408616
  .text:00408616 loc_408616:                             ; CODE XREF: sub_4084B0+180j
  .text:00408616                 mov     dl, [eax]       ; 比较特征码
  .text:00408618                 cmp     dl, [ecx]
  .text:0040861A                 jnz     short loc_408636
  .text:0040861C                 cmp     dl, bl
  .text:0040861E                 jz      short loc_408632
  .text:00408620                 mov     dl, [eax+1]
  .text:00408623                 cmp     dl, [ecx+1]
  .text:00408626                 jnz     short loc_408636
  .text:00408628                 add     eax, 2
  .text:0040862B                 add     ecx, 2
  .text:0040862E                 cmp     dl, bl
  .text:00408630                 jnz     short loc_408616
  .text:00408632
  .text:00408632 loc_408632:                             ; CODE XREF: sub_4084B0+16Ej
  .text:00408632                 xor     eax, eax
  .text:00408634                 jmp     short loc_40863B
  .text:00408636 ; ---------------------------------------------------------------------------
  .text:00408636
  .text:00408636 loc_408636:                             ; CODE XREF: sub_4084B0+16Aj
  .text:00408636                                         ; sub_4084B0+176j
  .text:00408636                 sbb     eax, eax
  .text:00408638                 sbb     eax, 0FFFFFFFFh
  .text:0040863B
  .text:0040863B loc_40863B:                             ; CODE XREF: sub_4084B0+184j
  .text:0040863B                 cmp     eax, ebx
  .text:0040863D                 jnz     short loc_408649
  .text:0040863F                 mov     dword ptr [esp+edi+40h+Args], offset aVncEnterpris_0 ; "VNC Enterprise Edition for UNIX"
  .text:00408647                 jmp     short loc_4086C1
  .text:00408649 ; ---------------------------------------------------------------------------
  .text:00408649
  .text:00408649 loc_408649:                             ; CODE XREF: sub_4084B0+18Dj
  .text:00408649                 mov     ecx, off_470DB0    ;特征码3
  .text:0040864F                 mov     eax, esi
  .text:00408651
  .text:00408651 loc_408651:                             ; CODE XREF: sub_4084B0+1BBj
  .text:00408651                 mov     dl, [eax]       ; 比较特征码
  .text:00408653                 cmp     dl, [ecx]
  .text:00408655                 jnz     short loc_408671
  .text:00408657                 cmp     dl, bl
  .text:00408659                 jz      short loc_40866D
  .text:0040865B                 mov     dl, [eax+1]
  .text:0040865E                 cmp     dl, [ecx+1]
  .text:00408661                 jnz     short loc_408671
  .text:00408663                 add     eax, 2
  .text:00408666                 add     ecx, 2
  .text:00408669                 cmp     dl, bl
  .text:0040866B                 jnz     short loc_408651
  .text:0040866D
  .text:0040866D loc_40866D:                             ; CODE XREF: sub_4084B0+1A9j
  .text:0040866D                 xor     eax, eax
  .text:0040866F                 jmp     short loc_408676
  .text:00408671 ; ---------------------------------------------------------------------------
  .text:00408671
  .text:00408671 loc_408671:                             ; CODE XREF: sub_4084B0+1A5j
  .text:00408671                                         ; sub_4084B0+1B1j
  .text:00408671                 sbb     eax, eax
  .text:00408673                 sbb     eax, 0FFFFFFFFh
  .text:00408676
  .text:00408676 loc_408676:                             ; CODE XREF: sub_4084B0+1BFj
  .text:00408676                 cmp     eax, ebx
  .text:00408678                 jnz     short loc_408684
  .text:0040867A                 mov     dword ptr [esp+edi+40h+Args], offset aVncEnterpris_1 ; "VNC Enterprise Edition for Mac OS X"
  .text:00408682                 jmp     short loc_4086C1
  .text:00408684 ; ---------------------------------------------------------------------------
  .text:00408684
  .text:00408684 loc_408684:                             ; CODE XREF: sub_4084B0+1C8j
  .text:00408684                 mov     ecx, off_470DAC    ;特征码4
  .text:0040868A                 mov     eax, esi
  .text:0040868C                 lea     esp, [esp+0]
  .text:00408690
  .text:00408690 loc_408690:                             ; CODE XREF: sub_4084B0+1FAj
  .text:00408690                 mov     dl, [eax]       ; 比较特征码
  .text:00408692                 cmp     dl, [ecx]
  .text:00408694                 jnz     short loc_4086B0
  .text:00408696                 cmp     dl, bl
  .text:00408698                 jz      short loc_4086AC
  .text:0040869A                 mov     dl, [eax+1]
  .text:0040869D                 cmp     dl, [ecx+1]
  .text:004086A0                 jnz     short loc_4086B0
  .text:004086A2                 add     eax, 2
  .text:004086A5                 add     ecx, 2
  .text:004086A8                 cmp     dl, bl
  .text:004086AA                 jnz     short loc_408690
  .text:004086AC
  .text:004086AC loc_4086AC:                             ; CODE XREF: sub_4084B0+1E8j
  .text:004086AC                 xor     eax, eax
  .text:004086AE                 jmp     short loc_4086B5
  .text:004086B0 ; ---------------------------------------------------------------------------
  .text:004086B0
  .text:004086B0 loc_4086B0:                             ; CODE XREF: sub_4084B0+1E4j
  .text:004086B0                                         ; sub_4084B0+1F0j
  .text:004086B0                 sbb     eax, eax
  .text:004086B2                 sbb     eax, -1
  .text:004086B5
  .text:004086B5 loc_4086B5:                             ; CODE XREF: sub_4084B0+1FEj
  .text:004086B5                 cmp     eax, ebx
  .text:004086B7                 jnz     short loc_4086C1
  .text:004086B9                 mov     dword ptr [esp+edi+40h+Args], offset aVncEnterpris_2 ; "VNC Enterprise Edition (OEM)"
  .text:004086C1
  .text:004086C1 loc_4086C1:                             ; CODE XREF: sub_4084B0+159j
  .text:004086C1                                         ; sub_4084B0+197j ...
  .text:004086C1                 add     edi, 4
  .text:004086C4                 cmp     edi, 8
  .text:004086C7                 jl      loc_4085D0
  .text:004086CD                 mov     eax, [esp+40h+var_20]
  .text:004086D1                 mov     ecx, dword ptr [esp+40h+Args]
  .text:004086D5                 push    eax
  .text:004086D6                 push    ecx             ; Args
  .text:004086D7                 lea     edx, [esp+48h+Memory]
  .text:004086DB                 push    offset aTheSuppliedL_2 ; "The supplied license key is only valid "...
  .text:004086E0                 push    edx             ; int
  .text:004086E1                 call    sub_40CC50
  .text:004086E6                 mov     ebp, [esp+50h+var_28]
  .text:004086EA                 add     esp, 10h
  .text:004086ED
  .text:004086ED loc_4086ED:                             ; CODE XREF: sub_4084B0+F7j
  .text:004086ED                 mov     edi, [esp+40h+var_2C]
  .text:004086F1
  .text:004086F1 loc_4086F1:                             ; CODE XREF: sub_4084B0+87j
  .text:004086F1                                         ; sub_4084B0+BBj
  .text:004086F1                 mov     eax, [ebp+4]
  .text:004086F4                 push    eax             ; Memory
  .text:004086F5                 call    j_j__free
  .text:004086FA                 mov     ecx, [ebp+0]
  .text:004086FD                 push    ecx             ; Memory
  .text:004086FE                 call    j_j__free
  .text:00408703                 push    ebp             ; Memory
  .text:00408704                 call    j__free
  .text:00408709                 add     esp, 0Ch
  .text:0040870C
  .text:0040870C loc_40870C:                             ; CODE XREF: sub_4084B0+67j
  .text:0040870C                 mov     eax, [esp+40h+Memory]
  .text:00408710                 cmp     eax, ebx
  .text:00408712                 jz      short loc_40872A
  .text:00408714                 mov     edx, [edi+8]
  .text:00408717                 push    ebx             ; lpCaption
  .text:00408718                 push    10h             ; Memory
  .text:0040871A                 push    eax             ; int
  .text:0040871B                 push    edx             ; hWnd
  .text:0040871C                 call    sub_420B60
  .text:00408721                 mov     eax, [esp+50h+Memory]
  .text:00408725                 add     esp, 10h
  .text:00408728                 cmp     eax, ebx
  .text:0040872A
  .text:0040872A loc_40872A:                             ; CODE XREF: sub_4084B0+262j
  .text:0040872A                 push    eax             ; Memory
  .text:0040872B                 setz    bl
  .text:0040872E                 call    j__free
  .text:00408733                 add     esp, 4
  .text:00408736                 mov     al, bl
  .text:00408738                 mov     ecx, [esp+40h+var_C]
  .text:0040873C                 mov     large fs:0, ecx
  .text:00408743                 pop     ecx
  .text:00408744                 pop     edi
  .text:00408745                 pop     esi
  .text:00408746                 pop     ebp
  .text:00408747                 pop     ebx
  .text:00408748                 add     esp, 2Ch
  .text:0040874B                 retn
  .text:0040874B sub_4084B0      endp
  
   主体部分的功能在于:
   1.使用5组特征码与注册码特征码进行对比,以确定是注册码是什么版本的,如果版本符合,通过,否则,提示版本错误
   2.对注册码有效期(注册码计算出的结构C中C[0x18],C[0x1C])进行验证

  004165C0时间校验Call

  .text:004165C0 ; =============== S U B R O U T I N E =======================================
  .text:004165C0
  .text:004165C0 ; 校验时间
  .text:004165C0
  .text:004165C0 sub_4165C0      proc near               ; CODE XREF: sub_4084B0+6Ep
  .text:004165C0                                         ; sub_40B150+9p ...
  .text:004165C0                 cmp     byte ptr [ecx+20h], 0 ; C[0x20]=0,返回0
  .text:004165C4                 push    ebp
  .text:004165C5                 jz      short loc_4165FF
  .text:004165C7                 push    ebx
  .text:004165C8                 mov     ebx, [ecx+0Ch]
  .text:004165CB                 push    esi
  .text:004165CC                 mov     esi, [ecx+18h]
  .text:004165CF                 push    edi
  .text:004165D0                 mov     edi, [ecx+1Ch]
  .text:004165D3                 push    0               ; Time
  .text:004165D5                 call    __time64        ; 取当前时间(秒)
  .text:004165DA                 mov     ebp, eax
  .text:004165DC                 mov     eax, ebx
  .text:004165DE                 imul    eax, 15180h     ; C[0xC]*0x15180(天数->秒)
  .text:004165E4                 mov     ecx, edx
  .text:004165E6                 add     esp, 4
  .text:004165E9                 cdq
  .text:004165EA                 add     eax, esi        ; C[0x18]+C[0x0C]*0x1518
  .text:004165EC                 adc     edx, edi        ; C[0x1C]+edx
  .text:004165EE                 cmp     ecx, edx        ; 与当前时间值的高位比较,大于返回1,小于返回0
  .text:004165F0                 pop     edi
  .text:004165F1                 pop     esi
  .text:004165F2                 pop     ebx
  .text:004165F3                 jl      short loc_4165FF
  .text:004165F5                 jg      short loc_4165FB
  .text:004165F7                 cmp     ebp, eax        ; 与当前时间值的低位比较,小于返回0
  .text:004165F9                 jb      short loc_4165FF
  .text:004165FB
  .text:004165FB loc_4165FB:                             ; CODE XREF: sub_4165C0+35j
  .text:004165FB                 mov     al, 1
  .text:004165FD                 pop     ebp
  .text:004165FE                 retn                    ; 0为通过
  .text:004165FF ; ---------------------------------------------------------------------------
  .text:004165FF
  .text:004165FF loc_4165FF:                             ; CODE XREF: sub_4165C0+5j
  .text:004165FF                                         ; sub_4165C0+33j ...
  .text:004165FF                 xor     al, al
  .text:00416601                 pop     ebp
  .text:00416602                 retn
  .text:00416602 sub_4165C0      endp
  
  这部分功能:
  1.C[0x20]为0,返回0,通过
  2.C[0x18],C[0x1C],C[0x0C]与当前时间值对比,小于返回1,不通过,大于返回0,通过

  00416560注册码处理Call的主要部分
  
  .text:00416350 ; =============== S U B R O U T I N E =======================================
  .text:00416350
  .text:00416350 ; 注册码处理
  .text:00416350
  .text:00416350 sub_416350      proc near               ; CODE XREF: sub_416560+3Dp
  .text:00416350
  .text:00416350 var_60          = dword ptr -60h
  .text:00416350 var_5C          = dword ptr -5Ch
  .text:00416350 Memory          = dword ptr -58h
  .text:00416350 var_34          = dword ptr -34h
  .text:00416350 var_30          = dword ptr -30h
  .text:00416350 var_C           = dword ptr -0Ch
  .text:00416350 var_4           = dword ptr -4
  .text:00416350 arg_0           = dword ptr  4
  .text:00416350 arg_4           = dword ptr  8
  .text:00416350 arg_8           = dword ptr  0Ch
  .text:00416350
  .text:00416350                 push    -1
  .text:00416352                 push    offset loc_452995
  .text:00416357                 mov     eax, large fs:0
  .text:0041635D                 push    eax
  .text:0041635E                 sub     esp, 54h
  .text:00416361                 push    ebx
  .text:00416362                 push    ebp
  .text:00416363                 push    esi
  .text:00416364                 push    edi
  .text:00416365                 mov     eax, dword_472404
  .text:0041636A                 xor     eax, esp
  .text:0041636C                 push    eax
  .text:0041636D                 lea     eax, [esp+74h+var_C]
  .text:00416371                 mov     large fs:0, eax
  .text:00416377                 mov     ebp, [esp+74h+arg_0]
  .text:0041637B                 xor     edi, edi
  .text:0041637D                 mov     [esp+74h+var_60], edi
  .text:00416381                 cmp     byte ptr [esp+74h+arg_4], 0
  .text:00416386                 jz      short loc_4163A6
  .text:00416388                 mov     eax, [esp+74h+arg_8]
  .text:0041638F                 mov     ecx, off_470DA4
  .text:00416395                 push    eax             ; int
  .text:00416396                 push    ecx             ; int
  .text:00416397                 push    ebp             ; Memory
  .text:00416398                 lea     ecx, [esp+80h+var_34]
  .text:0041639C                 call    sub_417120      ; 注册码校验2
  .text:004163A1                 lea     ebx, [edi+1]
  .text:004163A4                 jmp     short loc_4163BC
  .text:004163A6 ; ---------------------------------------------------------------------------
  .text:004163A6
  .text:004163A6 loc_4163A6:                             ; CODE XREF: sub_416350+36j
  .text:004163A6                 mov     edx, off_470DA4 ; 2945F7FEh, 0ABAA9F34h
  .text:004163AC                 push    edx             ; Memory
  .text:004163AD                 push    ebp             ; int
  .text:004163AE                 lea     ecx, [esp+7Ch+var_5C]
  .text:004163B2                 call    sub_417000      ; 注册码校验
  .text:004163B7                 mov     ebx, 2
  .text:004163BC
  .text:004163BC loc_4163BC:                             ; CODE XREF: sub_416350+54j
  .text:004163BC                 test    bl, 2
  .text:004163BF                 mov     esi, [eax+10h]
  .text:004163C2                 jz      short loc_4163DE
  .text:004163C4                 mov     eax, [esp+74h+Memory]
  .text:004163C8                 push    eax             ; Memory
  .text:004163C9                 and     ebx, 0FFFFFFFDh
  .text:004163CC                 call    j_j__free
  .text:004163D1                 mov     ecx, [esp+78h+var_5C]
  .text:004163D5                 push    ecx             ; Memory
  .text:004163D6                 call    j_j__free
  .text:004163DB                 add     esp, 8
  .text:004163DE
  .text:004163DE loc_4163DE:                             ; CODE XREF: sub_416350+72j
  .text:004163DE                 test    bl, 1
  .text:004163E1                 mov     [esp+74h+var_4], -1
  .text:004163E9                 jz      short loc_416402
  .text:004163EB                 mov     edx, [esp+74h+var_30]
  .text:004163EF                 push    edx             ; Memory
  .text:004163F0                 call    j_j__free
  .text:004163F5                 mov     eax, [esp+78h+var_34]
  .text:004163F9                 push    eax             ; Memory
  .text:004163FA                 call    j_j__free
  .text:004163FF                 add     esp, 8
  .text:00416402
  .text:00416402 loc_416402:                             ; CODE XREF: sub_416350+99j
  .text:00416402                 mov     eax, esi        ; 验证C[0x10]
  .text:00416404                 sub     eax, 1
  .text:00416407                 jz      loc_4164B5      ; C[0x10]=1跳,1和3使用依次按6个特征码进行运算
  .text:0041640D                 sub     eax, 1
  .text:00416410                 jz      short loc_416431 ; C[0x10]=2跳,2使用用特征码4进行运算
  .text:00416412                 sub     eax, 1
  .text:00416415                 jz      loc_4164B5      ; C[0x10]=3跳
  .text:0041641B
  .text:0041641B loc_41641B:                             ; CODE XREF: sub_416350+160j
  .text:0041641B                                         ; sub_416350+1F4j
  .text:0041641B                 xor     eax, eax
  .text:0041641D                 mov     ecx, [esp+74h+var_C]
  .text:00416421                 mov     large fs:0, ecx
  .text:00416428                 pop     ecx
  .text:00416429                 pop     edi
  .text:0041642A                 pop     esi
  .text:0041642B                 pop     ebp
  .text:0041642C                 pop     ebx
  .text:0041642D                 add     esp, 60h        ; 返回0,校验错
  .text:00416430                 retn
  .text:00416431 ; ---------------------------------------------------------------------------
  .text:00416431
  .text:00416431 loc_416431:                             ; CODE XREF: sub_416350+C0j
  .text:00416431                 push    28h             ; Size
  .text:00416433                 call    ??2@YAPAXI@Z    ; operator new(uint)
  .text:00416438                 add     esp, 4
  .text:0041643B                 cmp     byte ptr [esp+74h+arg_4], 0
  .text:00416440                 mov     [esp+74h+arg_4], eax
  .text:00416444                 jz      short loc_41646B
  .text:00416446                 cmp     eax, edi
  .text:00416448                 mov     [esp+74h+var_4], 3
  .text:00416450                 jz      short loc_416488
  .text:00416452                 mov     ecx, [esp+74h+arg_8]
  .text:00416459                 mov     edx, off_470DB4
  .text:0041645F                 push    ecx             ; int
  .text:00416460                 push    edx             ; int
  .text:00416461                 push    ebp             ; Memory
  .text:00416462                 mov     ecx, eax
  .text:00416464                 call    sub_417120      ; 注册码校验2
  .text:00416469                 jmp     short loc_41648A
  .text:0041646B ; ---------------------------------------------------------------------------
  .text:0041646B
  .text:0041646B loc_41646B:                             ; CODE XREF: sub_416350+F4j
  .text:0041646B                 cmp     eax, edi
  .text:0041646D                 mov     [esp+74h+var_4], 4
  .text:00416475                 jz      short loc_416488
  .text:00416477                 mov     ecx, off_470DB4
  .text:0041647D                 push    ecx             ; Memory
  .text:0041647E                 push    ebp             ; int
  .text:0041647F                 mov     ecx, eax
  .text:00416481                 call    sub_417000      ; 注册码校验
  .text:00416486                 jmp     short loc_41648A
  .text:00416488 ; ---------------------------------------------------------------------------
  .text:00416488
  .text:00416488 loc_416488:                             ; CODE XREF: sub_416350+100j
  .text:00416488                                         ; sub_416350+125j
  .text:00416488                 xor     eax, eax
  .text:0041648A
  .text:0041648A loc_41648A:                             ; CODE XREF: sub_416350+119j
  .text:0041648A                                         ; sub_416350+136j
  .text:0041648A                 mov     esi, eax
  .text:0041648C                 cmp     byte ptr [esi+21h], 0
  .text:00416490                 jnz     loc_416549
  .text:00416496                 mov     edx, [esi+4]
  .text:00416499                 push    edx             ; Memory
  .text:0041649A                 call    j_j__free
  .text:0041649F                 mov     eax, [esi]
  .text:004164A1                 push    eax             ; Memory
  .text:004164A2                 call    j_j__free
  .text:004164A7                 push    esi             ; Memory
  .text:004164A8                 call    j__free
  .text:004164AD                 add     esp, 0Ch
  .text:004164B0                 jmp     loc_41641B
  .text:004164B5 ; ---------------------------------------------------------------------------
  .text:004164B5
  .text:004164B5 loc_4164B5:                             ; CODE XREF: sub_416350+B7j
  .text:004164B5                                         ; sub_416350+C5j ...
  .text:004164B5                 push    28h             ; Size
  .text:004164B7                 call    ??2@YAPAXI@Z    ; operator new(uint)
  .text:004164BC                 add     esp, 4
  .text:004164BF                 cmp     byte ptr [esp+74h+arg_4], 0
  .text:004164C4                 mov     [esp+74h+var_60], eax
  .text:004164C8                 jz      short loc_4164EF
  .text:004164CA                 test    eax, eax
  .text:004164CC                 mov     [esp+74h+var_4], 1
  .text:004164D4                 jz      short loc_41650C
  .text:004164D6                 mov     ecx, [esp+74h+arg_8]
  .text:004164DD                 mov     edx, dword_473F88[edi]
  .text:004164E3                 push    ecx             ; int
  .text:004164E4                 push    edx             ; int
  .text:004164E5                 push    ebp             ; Memory
  .text:004164E6                 mov     ecx, eax
  .text:004164E8                 call    sub_417120      ; 注册码校验2
  .text:004164ED                 jmp     short loc_41650E
  .text:004164EF ; ---------------------------------------------------------------------------
  .text:004164EF
  .text:004164EF loc_4164EF:                             ; CODE XREF: sub_416350+178j
  .text:004164EF                 test    eax, eax
  .text:004164F1                 mov     [esp+74h+var_4], 2
  .text:004164F9                 jz      short loc_41650C
  .text:004164FB                 mov     ecx, dword_473F88[edi] ; 根据edi值取
  .text:004164FB                                         ; 共6组特征码
  .text:004164FB                                         ; 2945F7FEh, ABAA9F34h
  .text:004164FB                                         ; 4CC82057h, AEAB62AAh
  .text:004164FB                                         ; ED4FF7EFh, ABAD904Bh
  .text:004164FB                                         ; E540EAC2h, 81C5753Ch
  .text:004164FB                                         ; C1ACCCF0h, D0EA12ABh
  .text:004164FB                                         ; 1E02EF1h, 17101CEDh
  .text:004164FB                                         ;
  .text:00416501                 push    ecx             ; Memory
  .text:00416502                 push    ebp             ; int
  .text:00416503                 mov     ecx, eax
  .text:00416505                 call    sub_417000      ; 注册码校验
  .text:0041650A                 jmp     short loc_41650E
  .text:0041650C ; ---------------------------------------------------------------------------
  .text:0041650C
  .text:0041650C loc_41650C:                             ; CODE XREF: sub_416350+184j
  .text:0041650C                                         ; sub_416350+1A9j
  .text:0041650C                 xor     eax, eax
  .text:0041650E
  .text:0041650E loc_41650E:                             ; CODE XREF: sub_416350+19Dj
  .text:0041650E                                         ; sub_416350+1BAj
  .text:0041650E                 mov     esi, eax
  .text:00416510                 cmp     byte ptr [esi+21h], 0 ; 比较C[0x21](验证返回值),为0跳
  .text:00416514                 mov     [esp+74h+var_4], -1
  .text:0041651C                 jnz     short loc_416549
  .text:0041651E                 mov     edx, [esi+4]
  .text:00416521                 push    edx             ; Memory
  .text:00416522                 call    j_j__free
  .text:00416527                 mov     eax, [esi]
  .text:00416529                 push    eax             ; Memory
  .text:0041652A                 call    j_j__free
  .text:0041652F                 push    esi             ; Memory
  .text:00416530                 call    j__free         ; 取下一组运算
  .text:00416535                 add     edi, 4
  .text:00416538                 add     esp, 0Ch
  .text:0041653B                 cmp     edi, 18h
  .text:0041653E                 jb      loc_4164B5
  .text:00416544                 jmp     loc_41641B
  .text:00416549 ; ---------------------------------------------------------------------------
  .text:00416549
  .text:00416549 loc_416549:                             ; CODE XREF: sub_416350+140j
  .text:00416549                                         ; sub_416350+1CCj
  .text:00416549                 mov     eax, esi
  .text:0041654B                 mov     ecx, [esp+74h+var_C]
  .text:0041654F                 mov     large fs:0, ecx
  .text:00416556                 pop     ecx
  .text:00416557                 pop     edi
  .text:00416558                 pop     esi
  .text:00416559                 pop     ebp
  .text:0041655A                 pop     ebx
  .text:0041655B                 add     esp, 60h
  .text:0041655E                 retn
  .text:0041655E sub_416350      endp
  
  这部分的功能在于:
    1.根据注册码运算的返回结构C,并根据C[0x10]处的值确定注册码计算的方法,方法1和3使用6组特征码((最后一组在主体验证中无效……),2使用第5组特征码
    2.注册码与特征码结合,运算、比较后,确定验证注册码使用了哪组特征码
 
  00417000处注册码验证主要部分
  .text:00417000 ; =============== S U B R O U T I N E =======================================
  .text:00417000
  .text:00417000 ; 注册码校验
  .text:00417000 ; Attributes: bp-based frame
  .text:00417000
  .text:00417000 ; int __stdcall sub_417000(int, void *Memory)
  .text:00417000 sub_417000      proc near               ; CODE XREF: sub_40BA80+286p
  .text:00417000                                         ; sub_40BA80+2CBp ...
  .text:00417000
  .text:00417000 Args            = byte ptr -18h
  .text:00417000 var_14          = dword ptr -14h
  .text:00417000 var_10          = dword ptr -10h
  .text:00417000 var_C           = dword ptr -0Ch
  .text:00417000 var_4           = dword ptr -4
  .text:00417000 arg_0           = dword ptr  8
  .text:00417000 Memory          = dword ptr  0Ch
  .text:00417000
  .text:00417000                 push    ebp
  .text:00417001                 mov     ebp, esp
  .text:00417003                 push    -1
  .text:00417005                 push    offset loc_452B33
  .text:0041700A                 mov     eax, large fs:0
  .text:00417010                 push    eax
  .text:00417011                 sub     esp, 0Ch
  .text:00417014                 push    ebx
  .text:00417015                 push    esi
  .text:00417016                 push    edi
  .text:00417017                 mov     eax, dword_472404
  .text:0041701C                 xor     eax, ebp
  .text:0041701E                 push    eax
  .text:0041701F                 lea     eax, [ebp+var_C]
  .text:00417022                 mov     large fs:0, eax
  .text:00417028                 mov     [ebp+var_10], esp
  .text:0041702B                 mov     ebx, ecx
  .text:0041702D                 mov     [ebp+var_14], ebx
  .text:00417030                 mov     eax, [ebp+Memory]
  .text:00417033                 push    -1
  .text:00417035                 push    eax
  .text:00417036                 call    sub_40C730      ; strcpy()
  .text:0041703B                 mov     [ebx], eax      ; 字串指针放入[ebx]
  .text:0041703D                 xor     eax, eax
  .text:0041703F                 mov     [ebp+var_4], eax
  .text:00417042                 mov     [ebx+4], eax
  .text:00417045                 mov     [ebx+21h], al
  .text:00417048                 mov     [ebp+Memory], eax
  .text:0041704B                 mov     ecx, [ebp+arg_0] ; 注册码
  .text:0041704E                 push    ecx
  .text:0041704F                 lea     edi, [eax+19h]  ; 0x19
  .text:00417052                 mov     byte ptr [ebp+var_4], 3
  .text:00417056                 call    sub_416CB0      ; 去"-"
  .text:0041705B                 add     esp, 0Ch
  .text:0041705E                 lea     ecx, [ebp+Memory]
  .text:00417061                 mov     [ebp+Memory], eax
  .text:00417064                 call    sub_40C990      ; 转换为大写
  .text:00417069                 mov     esi, [ebp+Memory]
  .text:0041706C                 mov     eax, esi
  .text:0041706E                 lea     edx, [eax+1]
  .text:00417071
  .text:00417071 loc_417071:                             ; CODE XREF: sub_417000+78j
  .text:00417071                 mov     cl, [eax]
  .text:00417073                 add     eax, 1
  .text:00417076                 test    cl, cl
  .text:00417078                 jnz     short loc_417071
  .text:0041707A                 sub     eax, edx        ; 计算长度
  .text:0041707C                 cmp     eax, 19h        ; 长度=25跳
  .text:0041707F                 jz      short loc_4170A1
  .text:00417081                 push    offset aBadKeyLength ; "Bad key length"
  .text:00417086                 push    offset dword_473FA0 ; int
  .text:0041708B                 call    sub_40C650
  .text:00417090                 mov     edx, [ebp+Memory]
  .text:00417093                 add     esp, 8
  .text:00417096                 push    edx             ; Memory
  .text:00417097                 call    j_j__free
  .text:0041709C                 add     esp, 4
  .text:0041709F                 jmp     short loc_417108
  .text:004170A1 ; ---------------------------------------------------------------------------
  .text:004170A1
  .text:004170A1 loc_4170A1:                             ; CODE XREF: sub_417000+7Fj
  .text:004170A1                 push    -1
  .text:004170A3                 push    esi
  .text:004170A4                 call    sub_40C730      ; strcpy()
  .text:004170A9                 mov     esi, eax
  .text:004170AB                 add     esp, 8
  .text:004170AE                 mov     [ebp+arg_0], esi
  .text:004170B1                 mov     eax, [ebp+Memory]
  .text:004170B4                 push    esi
  .text:004170B5                 push    eax
  .text:004170B6                 mov     byte ptr [ebp+var_4], 4
  .text:004170BA                 call    sub_416FB0      ; 注册码处理,字符按位置进行替换,形成一个新的25长字符串
  .text:004170BF                 add     esp, 8
  .text:004170C2                 push    esi             ; 计算后的字符串指针
  .text:004170C3                 mov     ecx, ebx
  .text:004170C5                 call    sub_416E50      ; 按位计算后组成注册信息
  .text:004170CA                 push    esi
  .text:004170CB                 mov     ecx, ebx
  .text:004170CD                 call    sub_416D60      ; 前13字符+特征码计算sha1值,经过处理后与后12字符相等
  .text:004170D2                 push    esi             ; Memory
  .text:004170D3                 mov     [ebx+21h], al   ; 返回值放入C[0x21],1为成功,0为失败
  .text:004170D6                 call    j_j__free
  .text:004170DB                 mov     ecx, [ebp+Memory]
  .text:004170DE                 push    ecx             ; Memory
  .text:004170DF                 call    j_j__free
  .text:004170E4                 add     esp, 8
  .text:004170E7                 jmp     short loc_417108
  .text:004170E9 ; ---------------------------------------------------------------------------
  .text:004170E9                 mov     edx, dword ptr [ebp+Args]
  .text:004170EC                 push    edx             ; Args
  .text:004170ED                 push    offset aS       ; "%s"
  .text:004170F2                 push    offset dword_473FA0 ; int
  .text:004170F7                 call    sub_4089A0
  .text:004170FC                 add     esp, 0Ch
  .text:004170FF                 mov     eax, offset loc_417105
  .text:00417104                 retn
  .text:00417105 ; ---------------------------------------------------------------------------
  .text:00417105
  .text:00417105 loc_417105:                             ; DATA XREF: sub_417000+FFo
  .text:00417105                 mov     ebx, [ebp+var_14]
  .text:00417108
  .text:00417108 loc_417108:                             ; CODE XREF: sub_417000+9Fj
  .text:00417108                                         ; sub_417000+E7j
  .text:00417108                 mov     eax, ebx
  .text:0041710A                 mov     ecx, [ebp+var_C]
  .text:0041710D                 mov     large fs:0, ecx
  .text:00417114                 pop     ecx
  .text:00417115                 pop     edi
  .text:00417116                 pop     esi
  .text:00417117                 pop     ebx
  .text:00417118                 mov     esp, ebp
  .text:0041711A                 pop     ebp
  .text:0041711B                 retn    8
  .text:0041711B sub_417000      endp
  
  这部分的功能在于:
  1.验证注册码长度是否等于25,不等于,报错
  2.验证注册码是否仅包含“2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ”(字串A)中的字符,超出范围,报错
  2.注册码与“2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ”(字串A)进行运算、换位,得出一个新的25字节字符串(B)
  2.利用新的25字节字符串(B)与字串A计算出结构C
  3.利用新的25字符的串与特征码连接,做sha1运算,返回值写了C结构

  00416FB0处call
  
  .text:00416FB0 ; =============== S U B R O U T I N E =======================================
  .text:00416FB0
  .text:00416FB0
  .text:00416FB0 sub_416FB0      proc near               ; CODE XREF: sub_417000+BAp
  .text:00416FB0                                         ; sub_417120+A7p
  .text:00416FB0
  .text:00416FB0 arg_0           = dword ptr  4
  .text:00416FB0 arg_4           = dword ptr  8
  .text:00416FB0
  .text:00416FB0                 push    ebx
  .text:00416FB1                 mov     ebx, [esp+4+arg_0]
  .text:00416FB5                 push    esi
  .text:00416FB6                 push    edi
  .text:00416FB7                 mov     edi, [esp+0Ch+arg_4]
  .text:00416FBB                 xor     esi, esi        ; n=0
  .text:00416FBD                 lea     ecx, [ecx+0]
  .text:00416FC0
  .text:00416FC0 loc_416FC0:                             ; CODE XREF: sub_416FB0+32j
  .text:00416FC0                 movzx   edx, byte ptr [ebx+esi*2+1] ; 注册码2n+1位
  .text:00416FC5                 lea     eax, [esi+edi+0Eh] ; 指向注册码第n+14位
  .text:00416FC9                 push    eax
  .text:00416FCA                 movzx   eax, byte ptr [ebx+esi*2] ; 注册码2n位
  .text:00416FCE                 lea     ecx, [esi+edi]  ; 批向注册码第n位
  .text:00416FD1                 push    ecx
  .text:00416FD2                 push    edx
  .text:00416FD3                 push    eax
  .text:00416FD4                 call    sub_4168B0      ; 处理
  .text:00416FD9                 add     esi, 1
  .text:00416FDC                 add     esp, 10h
  .text:00416FDF                 cmp     esi, 0Bh        ; n<11
  .text:00416FE2                 jl      short loc_416FC0 ; 注册码2n+1位
  .text:00416FE4                 mov     cx, [ebx+16h]   ; 取注册码第22-23位
  .text:00416FE8                 mov     [edi+0Bh], cx   ; 替换计算后的第11-12位
  .text:00416FEC                 mov     dl, [ebx+18h]   ; 取注册码第24位
  .text:00416FEF                 mov     [edi+0Dh], dl   ; 替换计算后的第13位
  .text:00416FF2                 pop     edi
  .text:00416FF3                 pop     esi
  .text:00416FF4                 pop     ebx
  .text:00416FF5                 retn
  .text:00416FF5 sub_416FB0      endp
  
  004168B0处的call
  
  .text:004168B0 ; =============== S U B R O U T I N E =======================================
  .text:004168B0
  .text:004168B0 ; 转换字符串
  .text:004168B0 ; (arg_0&0x55|arg_4&0xAA)->arg_8
  .text:004168B0 ; (arg_0&0xAA|arg_4&0x55)->arg_c
  .text:004168B0
  .text:004168B0 sub_4168B0      proc near               ; CODE XREF: sub_416040+20p
  .text:004168B0                                         ; sub_416FB0+24p
  .text:004168B0
  .text:004168B0 arg_0           = dword ptr  4
  .text:004168B0 arg_4           = dword ptr  8
  .text:004168B0 arg_8           = dword ptr  0Ch
  .text:004168B0 arg_C           = dword ptr  10h
  .text:004168B0
  .text:004168B0                 mov     eax, [esp+arg_0]
  .text:004168B4                 push    esi
  .text:004168B5                 push    edi
  .text:004168B6                 push    eax
  .text:004168B7                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:004168BC                 mov     ecx, [esp+0Ch+arg_4] ; 2n+1位
  .text:004168C0                 push    ecx
  .text:004168C1                 mov     esi, eax
  .text:004168C3                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:004168C8                 mov     edx, eax
  .text:004168CA                 mov     ecx, esi
  .text:004168CC                 and     edx, 0AAh       ; 2n+1位索引取偶数位
  .text:004168D2                 and     ecx, 55h        ; 2n位索引取奇数位
  .text:004168D5                 or      edx, ecx        ; 合成
  .text:004168D7                 add     esp, 8
  .text:004168DA                 and     edx, 8000001Fh  ; 取低5位,并校验高位
  .text:004168E0                 jns     short loc_4168E7 ; 高位未置跳转
  .text:004168E2                 dec     edx
  .text:004168E3                 or      edx, 0FFFFFFE0h
  .text:004168E6                 inc     edx
  .text:004168E7
  .text:004168E7 loc_4168E7:                             ; CODE XREF: sub_4168B0+30j
  .text:004168E7                 mov     ecx, off_470DC0
  .text:004168ED                 mov     dl, [edx+ecx]   ; 取合成数在字符串A中相应字符
  .text:004168F0                 mov     edi, [esp+8+arg_8] ; 替换n处字符
  .text:004168F4                 and     esi, 0AAh       ; 2n位索引取偶数位
  .text:004168FA                 and     eax, 55h        ; 2n+1位索引取奇数位
  .text:004168FD                 or      esi, eax
  .text:004168FF                 and     esi, 8000001Fh  ; 合成后取低5位,并检测高位
  .text:00416905                 mov     [edi], dl
  .text:00416907                 jns     short loc_41690E
  .text:00416909                 dec     esi
  .text:0041690A                 or      esi, 0FFFFFFE0h
  .text:0041690D                 inc     esi
  .text:0041690E
  .text:0041690E loc_41690E:                             ; CODE XREF: sub_4168B0+57j
  .text:0041690E                 mov     al, [esi+ecx]
  .text:00416911                 mov     ecx, [esp+8+arg_C] ; 取合成数在字符串中相应字符替换n+14处字符
  .text:00416915                 pop     edi
  .text:00416916                 mov     [ecx], al
  .text:00416918                 pop     esi
  .text:00416919                 retn
  .text:00416919 sub_4168B0      endp
  
  以上两部分是注册码与“2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ”(字符串A)运算出新的25字节长字符串B的过程

  00416E50处的Call
  
  .text:00416E50 ; =============== S U B R O U T I N E =======================================
  .text:00416E50
  .text:00416E50 ; 按位计算后组成注册信息
  .text:00416E50
  .text:00416E50 sub_416E50      proc near               ; CODE XREF: sub_417000+C5p
  .text:00416E50                                         ; sub_417120+E1p
  .text:00416E50
  .text:00416E50 arg_0           = dword ptr  4
  .text:00416E50
  .text:00416E50                 push    ebx
  .text:00416E51                 push    ebp
  .text:00416E52                 push    esi
  .text:00416E53                 mov     esi, [esp+0Ch+arg_0] ; 第一次运算后的字符串
  .text:00416E57                 movzx   eax, byte ptr [esi+3] ; 取第3个字符
  .text:00416E5B                 push    edi
  .text:00416E5C                 push    eax
  .text:00416E5D                 mov     edi, ecx        ; 栈指针C
  .text:00416E5F                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416E64                 movzx   ecx, byte ptr [esi+2] ; 取第2个字符
  .text:00416E68                 mov     ebp, eax
  .text:00416E6A                 push    ecx
  .text:00416E6B                 shl     ebp, 5          ; 第3字符索引<<5
  .text:00416E6E                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416E73                 movzx   edx, byte ptr [esi+1] ; 取第1个字符
  .text:00416E77                 mov     ebx, eax
  .text:00416E79                 or      ebx, ebp
  .text:00416E7B                 push    edx
  .text:00416E7C                 shl     ebx, 5
  .text:00416E7F                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416E84                 mov     ebp, eax
  .text:00416E86                 movzx   eax, byte ptr [esi] ; 取第0个字符
  .text:00416E89                 or      ebp, ebx
  .text:00416E8B                 push    eax
  .text:00416E8C                 shl     ebp, 5
  .text:00416E8F                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416E94                 or      eax, ebp        ; 产生dw,从低到高每5位为第0,1,2,3字符在字符串中的索引
  .text:00416E96                 mov     [edi+8], eax    ; 放入C[0x8]
  .text:00416E99                 movzx   ecx, byte ptr [esi+6] ; 取第6个字符
  .text:00416E9D                 push    ecx
  .text:00416E9E                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416EA3                 movzx   edx, byte ptr [esi+5] ; 取第5个字符
  .text:00416EA7                 mov     ebp, eax
  .text:00416EA9                 push    edx
  .text:00416EAA                 shl     ebp, 5
  .text:00416EAD                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416EB2                 mov     ebx, eax
  .text:00416EB4                 movzx   eax, byte ptr [esi+4] ; 取第4个字符
  .text:00416EB8                 or      ebx, ebp
  .text:00416EBA                 push    eax
  .text:00416EBB                 shl     ebx, 5
  .text:00416EBE                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416EC3                 or      eax, ebx        ; 产生dw,从低到高每5位为第4,5,6字符在字符串中的索引
  .text:00416EC5                 cdq                     ; eax高位值扩展入edx
  .text:00416EC6                 mov     [edi+18h], eax  ; 放入C[0x18]
  .text:00416EC9                 and     eax, 4000h
  .text:00416ECE                 xor     ecx, ecx
  .text:00416ED0                 add     esp, 1Ch
  .text:00416ED3                 or      eax, ecx        ; 判断eax第14位是否为0
  .text:00416ED5                 mov     [edi+1Ch], edx  ; 放入C[0x1C]
  .text:00416ED8                 jz      short loc_416EDF
  .text:00416EDA                 lea     eax, [ecx+1]    ; eax=1
  .text:00416EDD                 jmp     short loc_416EE1 ; al->C[0x20]
  .text:00416EDF ; ---------------------------------------------------------------------------
  .text:00416EDF
  .text:00416EDF loc_416EDF:                             ; CODE XREF: sub_416E50+88j
  .text:00416EDF                 xor     eax, eax
  .text:00416EE1
  .text:00416EE1 loc_416EE1:                             ; CODE XREF: sub_416E50+8Dj
  .text:00416EE1                 mov     [edi+20h], al   ; al->C[0x20]
  .text:00416EE4                 call    sub_416610      ; 取时间值,设置和判断470DC8和470DCC的值
  .text:00416EE9                 mov     ecx, [edi+18h]  ; 取C[0x18]
  .text:00416EEC                 push    0
  .text:00416EEE                 mov     ebp, edx
  .text:00416EF0                 mov     edx, [edi+1Ch]  ; 取C[0x1C]
  .text:00416EF3                 push    15180h
  .text:00416EF8                 and     ecx, 0FFFFBFFFh ; 取第14位以外各位
  .text:00416EFE                 push    edx             ; C[0x1C]
  .text:00416EFF                 push    ecx             ; C[0x18]
  .text:00416F00                 mov     ebx, eax
  .text:00416F02                 call    __allmul        ; 0x15180*C[0x18]&0xffffbfff 0x15180为每天秒数
  .text:00416F07                 add     ebx, eax        ; [470DC8]+eax->C[0x18]
  .text:00416F09                 adc     ebp, edx        ; [470DCC]+edx->C[0x1C]
  .text:00416F0B                 mov     [edi+18h], ebx
  .text:00416F0E                 mov     [edi+1Ch], ebp
  .text:00416F11                 movzx   eax, byte ptr [esi+7] ; 取第7字符
  .text:00416F15                 push    eax
  .text:00416F16                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416F1B                 movzx   ecx, byte ptr [esi+8] ; 取第8字符
  .text:00416F1F                 mov     ebp, eax
  .text:00416F21                 push    ecx
  .text:00416F22                 shl     ebp, 5
  .text:00416F25                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416F2A                 movzx   edx, byte ptr [esi+9] ; 取第9字符
  .text:00416F2E                 mov     ebx, eax
  .text:00416F30                 or      ebx, ebp
  .text:00416F32                 push    edx
  .text:00416F33                 shl     ebx, 5
  .text:00416F36                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416F3B                 mov     ebp, eax
  .text:00416F3D                 movzx   eax, byte ptr [esi+0Ah] ; 取第10字符
  .text:00416F41                 or      ebp, ebx
  .text:00416F43                 push    eax
  .text:00416F44                 shl     ebp, 5
  .text:00416F47                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416F4C                 movzx   ecx, byte ptr [esi+0Bh] ; 取第11字符
  .text:00416F50                 mov     ebx, eax
  .text:00416F52                 or      ebx, ebp
  .text:00416F54                 push    ecx
  .text:00416F55                 shl     ebx, 5
  .text:00416F58                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416F5D                 movzx   edx, byte ptr [esi+0Ch] ; 取第12字符
  .text:00416F61                 mov     ebp, eax
  .text:00416F63                 or      ebp, ebx
  .text:00416F65                 push    edx
  .text:00416F66                 shl     ebp, 5
  .text:00416F69                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416F6E                 or      eax, ebp        ; 产生dw,从低到高每5位为第7,8,9,10,11,12字符在字符串中的索引
  .text:00416F70                 mov     [edi+0Ch], eax  ; 放入C[0x0C]
  .text:00416F73                 movzx   eax, byte ptr [esi+0Dh] ; 取第13字符
  .text:00416F77                 push    eax
  .text:00416F78                 call    sub_416840      ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416F7D                 push    -1
  .text:00416F7F                 add     esi, 19h        ; esi+25
  .text:00416F82                 push    esi
  .text:00416F83                 mov     [edi+10h], eax  ; 第13字符在字符串中索引放入C[0x10]
  .text:00416F86                 call    sub_40C730      ; strcpy()
  .text:00416F8B                 mov     ecx, [edi+4]
  .text:00416F8E                 push    ecx             ; Memory
  .text:00416F8F                 mov     esi, eax
  .text:00416F91                 call    j_j__free
  .text:00416F96                 add     esp, 28h
  .text:00416F99                 mov     [edi+4], esi    ; 字符串指针放入C[0x4]
  .text:00416F9C                 pop     edi
  .text:00416F9D                 pop     esi
  .text:00416F9E                 pop     ebp
  .text:00416F9F                 pop     ebx
  .text:00416FA0                 retn    4
  .text:00416FA0 sub_416E50      endp
  
  这部分是由25字节长字符串B运算产生结构C的过程

  
  .text:00416840 ; =============== S U B R O U T I N E =======================================
  .text:00416840
  .text:00416840 ; 取在字符串中"2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ"位置
  .text:00416840 ; Attributes: bp-based frame
  .text:00416840
  .text:00416840 sub_416840      proc near               ; CODE XREF: sub_416220+67p
  .text:00416840                                         ; sub_4168B0+7p ...
  .text:00416840
  .text:00416840 var_200         = byte ptr -200h
  .text:00416840 var_100         = dword ptr -100h
  .text:00416840 arg_0           = byte ptr  8
  .text:00416840
  .text:00416840                 push    ebp
  .text:00416841                 mov     ebp, esp
  .text:00416843                 and     esp, 0FFFFFFF8h
  .text:00416846                 movsx   eax, [ebp+arg_0]
  .text:0041684A                 sub     esp, 200h
  .text:00416850                 push    esi
  .text:00416851                 push    edi
  .text:00416852                 push    eax             ; C
  .text:00416853                 call    _toupper
  .text:00416858                 mov     edx, off_470DC0
  .text:0041685E                 add     esp, 4
  .text:00416861                 mov     cl, al
  .text:00416863                 xor     eax, eax
  .text:00416865
  .text:00416865 loc_416865:                             ; CODE XREF: sub_416840+30j
  .text:00416865                 cmp     [edx+eax], cl
  .text:00416868                 jz      short loc_4168A7
  .text:0041686A                 add     eax, 1
  .text:0041686D                 cmp     eax, 20h
  .text:00416870                 jl      short loc_416865
  .text:00416872                 movsx   ecx, cl
  .text:00416875                 push    ecx             ; Args
  .text:00416876                 lea     edx, [esp+20Ch+var_100]
  .text:0041687D                 push    offset aBadKeyCharC ; "bad key char: %c"
  .text:00416882                 push    edx             ; int
  .text:00416883                 call    sub_40F3E0
  .text:00416888                 add     esp, 0Ch
  .text:0041688B                 mov     esi, eax
  .text:0041688D                 push    offset dword_46A684
  .text:00416892                 lea     eax, [esp+20Ch+var_200]
  .text:00416896                 mov     ecx, 40h
  .text:0041689B                 lea     edi, [esp+20Ch+var_200]
  .text:0041689F                 push    eax
  .text:004168A0                 rep movsd
  .text:004168A2                 call    __CxxThrowException@8 ; _CxxThrowException(x,x)
  .text:004168A7
  .text:004168A7 loc_4168A7:                             ; CODE XREF: sub_416840+28j
  .text:004168A7                 pop     edi
  .text:004168A8                 pop     esi
  .text:004168A9                 mov     esp, ebp
  .text:004168AB                 pop     ebp
  .text:004168AC                 retn
  .text:004168AC sub_416840      endp
  
  这部分的功能是查找字符C1在字符串A中索引,如找不到,报错
  
  00416D60处的CAll
  
  .text:00416D60 ; 前13字符+特征码计算sha1值,经过处理后与后12字符相等
  .text:00416D60
  .text:00416D60 sub_416D60      proc near               ; CODE XREF: sub_417000+CDp
  .text:00416D60                                         ; sub_417120+109p
  .text:00416D60
  .text:00416D60 var_C           = dword ptr -0Ch
  .text:00416D60 var_4           = dword ptr -4
  .text:00416D60 arg_0           = dword ptr  4
  .text:00416D60
  .text:00416D60                 push    -1
  .text:00416D62                 push    offset sub_452AE8
  .text:00416D67                 mov     eax, large fs:0
  .text:00416D6D                 push    eax
  .text:00416D6E                 push    ebx
  .text:00416D6F                 push    esi
  .text:00416D70                 push    edi
  .text:00416D71                 mov     eax, dword_472404
  .text:00416D76                 xor     eax, esp
  .text:00416D78                 push    eax
  .text:00416D79                 lea     eax, [esp+1Ch+var_C]
  .text:00416D7D                 mov     large fs:0, eax
  .text:00416D83                 mov     ebx, ecx
  .text:00416D85                 mov     esi, [esp+1Ch+arg_0] ; 第一次运算后字串
  .text:00416D89                 push    -1
  .text:00416D8B                 push    esi
  .text:00416D8C                 call    sub_40C730      ; strcpy()
  .text:00416D91                 mov     edi, eax        ; 目的字串,初始内容与第一次运算后字串相同
  .text:00416D93                 mov     [esp+24h+arg_0], edi ; 返回值地址改为目的字串
  .text:00416D97                 mov     eax, [ebx+4]    ; C[0x4]
  .text:00416D9A                 mov     ecx, [ebx]      ; C
  .text:00416D9C                 push    eax
  .text:00416D9D                 push    ecx
  .text:00416D9E                 push    edi
  .text:00416D9F                 mov     [esp+30h+var_4], 0
  .text:00416DA7                 call    sub_416720      ; 字符串处理(small-endian->big-endian,sha1运算,sha1摘要处理后写回字符串)
  .text:00416DAC                 add     esp, 14h
  .text:00416DAF                 mov     ecx, esi
  .text:00416DB1                 mov     eax, edi
  .text:00416DB3
  .text:00416DB3 loc_416DB3:                             ; CODE XREF: sub_416D60+6Dj
  .text:00416DB3                 mov     dl, [eax]
  .text:00416DB5                 cmp     dl, [ecx]
  .text:00416DB7                 jnz     short loc_416DD3
  .text:00416DB9                 test    dl, dl
  .text:00416DBB                 jz      short loc_416DCF
  .text:00416DBD                 mov     dl, [eax+1]
  .text:00416DC0                 cmp     dl, [ecx+1]
  .text:00416DC3                 jnz     short loc_416DD3
  .text:00416DC5                 add     eax, 2
  .text:00416DC8                 add     ecx, 2
  .text:00416DCB                 test    dl, dl
  .text:00416DCD                 jnz     short loc_416DB3 ; 比较第一次运算和sha1运算后的字符串
  .text:00416DCF
  .text:00416DCF loc_416DCF:                             ; CODE XREF: sub_416D60+5Bj
  .text:00416DCF                 xor     eax, eax
  .text:00416DD1                 jmp     short loc_416DD8
  .text:00416DD3 ; ---------------------------------------------------------------------------
  .text:00416DD3
  .text:00416DD3 loc_416DD3:                             ; CODE XREF: sub_416D60+57j
  .text:00416DD3                                         ; sub_416D60+63j
  .text:00416DD3                 sbb     eax, eax
  .text:00416DD5                 sbb     eax, -1
  .text:00416DD8
  .text:00416DD8 loc_416DD8:                             ; CODE XREF: sub_416D60+71j
  .text:00416DD8                 test    eax, eax
  .text:00416DDA                 jz      short loc_416DE3
  .text:00416DDC                 push    offset aDigestMismatch ; "Digest mismatch"
  .text:00416DE1                 jmp     short loc_416E1A
  .text:00416DE3 ; ---------------------------------------------------------------------------
  .text:00416DE3
  .text:00416DE3 loc_416DE3:                             ; CODE XREF: sub_416D60+7Aj
  .text:00416DE3                 mov     eax, [ebx+10h]
  .text:00416DE6                 cmp     eax, 1          ; 比较C[0x10]处,不为1,2,3返回0,为返回1,eax为返回码
  .text:00416DE9                 jnz     short loc_416E0B
  .text:00416DEB
  .text:00416DEB loc_416DEB:                             ; CODE XREF: sub_416D60+AEj
  .text:00416DEB                                         ; sub_416D60+B3j
  .text:00416DEB                 push    edi             ; Memory
  .text:00416DEC                 call    j_j__free
  .text:00416DF1                 add     esp, 4
  .text:00416DF4                 mov     al, 1
  .text:00416DF6                 mov     ecx, [esp+1Ch+var_C]
  .text:00416DFA                 mov     large fs:0, ecx
  .text:00416E01                 pop     ecx
  .text:00416E02                 pop     edi
  .text:00416E03                 pop     esi
  .text:00416E04                 pop     ebx
  .text:00416E05                 add     esp, 0Ch
  .text:00416E08                 retn    4
  .text:00416E0B ; ---------------------------------------------------------------------------
  .text:00416E0B
  .text:00416E0B loc_416E0B:                             ; CODE XREF: sub_416D60+89j
  .text:00416E0B                 cmp     eax, 2
  .text:00416E0E                 jz      short loc_416DEB
  .text:00416E10                 cmp     eax, 3
  .text:00416E13                 jz      short loc_416DEB
  .text:00416E15                 push    offset aInvalidLicen_0 ; "Invalid license version"
  .text:00416E1A
  .text:00416E1A loc_416E1A:                             ; CODE XREF: sub_416D60+81j
  .text:00416E1A                 push    offset dword_473FA0 ; int
  .text:00416E1F                 call    sub_40C650
  .text:00416E24                 add     esp, 8
  .text:00416E27                 push    edi             ; Memory
  .text:00416E28                 call    j_j__free
  .text:00416E2D                 add     esp, 4
  .text:00416E30                 xor     al, al
  .text:00416E32                 mov     ecx, [esp+1Ch+var_C]
  .text:00416E36                 mov     large fs:0, ecx
  .text:00416E3D                 pop     ecx
  .text:00416E3E                 pop     edi
  .text:00416E3F                 pop     esi
  .text:00416E40                 pop     ebx
  .text:00416E41                 add     esp, 0Ch
  .text:00416E44                 retn    4
  .text:00416E44 sub_416D60      endp
  
  00416720处的Call
  
  .text:00416720 ; =============== S U B R O U T I N E =======================================
  .text:00416720
  .text:00416720 ; 由字符串A1,A2,A3指向拼接后,进行SHA1运算,运算后前0xB位转成定符写回字串A尾部
  .text:00416720
  .text:00416720 sub_416720      proc near               ; CODE XREF: sub_416220+58p
  .text:00416720                                         ; sub_416D60+47p
  .text:00416720
  .text:00416720 var_2C          = byte ptr -2Ch
  .text:00416720 var_28          = dword ptr -28h
  .text:00416720 var_24          = byte ptr -24h
  .text:00416720 var_10          = dword ptr -10h
  .text:00416720 var_C           = dword ptr -0Ch
  .text:00416720 var_4           = dword ptr -4
  .text:00416720 arg_0           = dword ptr  4
  .text:00416720 arg_4           = dword ptr  8
  .text:00416720 arg_8           = dword ptr  0Ch
  .text:00416720
  .text:00416720                 push    -1
  .text:00416722                 push    offset sub_4529E8
  .text:00416727                 mov     eax, large fs:0
  .text:0041672D                 push    eax
  .text:0041672E                 sub     esp, 20h
  .text:00416731                 mov     eax, dword_472404
  .text:00416736                 xor     eax, esp
  .text:00416738                 mov     [esp+2Ch+var_10], eax
  .text:0041673C                 push    ebx
  .text:0041673D                 push    ebp
  .text:0041673E                 push    esi
  .text:0041673F                 push    edi
  .text:00416740                 mov     eax, dword_472404
  .text:00416745                 xor     eax, esp
  .text:00416747                 push    eax
  .text:00416748                 lea     eax, [esp+40h+var_C]
  .text:0041674C                 mov     large fs:0, eax
  .text:00416752                 mov     eax, [esp+40h+arg_4] ; A3
  .text:00416756                 mov     ebp, [esp+40h+arg_0] ; A1
  .text:0041675A                 mov     edi, [esp+40h+arg_8] ; A2
  .text:0041675E                 mov     [esp+40h+var_28], eax
  .text:00416762                 lea     edx, [eax+1]
  .text:00416765
  .text:00416765 loc_416765:                             ; CODE XREF: sub_416720+4Cj
  .text:00416765                 mov     cl, [eax]
  .text:00416767                 add     eax, 1
  .text:0041676A                 test    cl, cl
  .text:0041676C                 jnz     short loc_416765
  .text:0041676E                 sub     eax, edx        ; 计算A3长度
  .text:00416770                 test    edi, edi
  .text:00416772                 mov     ebx, eax
  .text:00416774                 jz      short loc_41678F ; 判断edi,为0跳
  .text:00416776                 mov     eax, edi
  .text:00416778                 lea     edx, [eax+1]
  .text:0041677B                 jmp     short loc_416780
  .text:0041677B ; ---------------------------------------------------------------------------
  .text:0041677D                 align 10h
  .text:00416780
  .text:00416780 loc_416780:                             ; CODE XREF: sub_416720+5Bj
  .text:00416780                                         ; sub_416720+67j
  .text:00416780                 mov     cl, [eax]
  .text:00416782                 add     eax, 1
  .text:00416785                 test    cl, cl
  .text:00416787                 jnz     short loc_416780
  .text:00416789                 sub     eax, edx        ; 计算A2长度
  .text:0041678B                 mov     esi, eax
  .text:0041678D                 jmp     short loc_416791
  .text:0041678F ; ---------------------------------------------------------------------------
  .text:0041678F
  .text:0041678F loc_41678F:                             ; CODE XREF: sub_416720+54j
  .text:0041678F                 xor     esi, esi
  .text:00416791
  .text:00416791 loc_416791:                             ; CODE XREF: sub_416720+6Dj
  .text:00416791                 lea     ecx, [esp+40h+var_2C]
  .text:00416795                 call    sub_42BF30      ; new sha1结构(size,h0,h1,h2,h3,h4)
  .text:0041679A                 mov     eax, 0Eh        ; 取前0xE(14)位
  .text:0041679F                 push    ebp             ; A
  .text:004167A0                 push    eax
  .text:004167A1                 lea     ecx, [esp+48h+var_2C]
  .text:004167A5                 mov     [esp+48h+var_4], 0
  .text:004167AD                 call    sub_42BF50      ; memcpy
  .text:004167B2                 push    edi             ; A2
  .text:004167B3                 push    esi             ; A2长度
  .text:004167B4                 lea     ecx, [esp+48h+var_2C]
  .text:004167B8                 call    sub_42BF50      ; memcpy
  .text:004167BD                 mov     eax, [esp+40h+var_28]
  .text:004167C1                 push    eax             ; A3
  .text:004167C2                 push    ebx             ; A3长度
  .text:004167C3                 lea     ecx, [esp+48h+var_2C]
  .text:004167C7                 call    sub_42BF50      ; memcpy
  .text:004167CC                 lea     ecx, [esp+40h+var_24] ; 缓冲区
  .text:004167D0                 push    ecx
  .text:004167D1                 lea     ecx, [esp+44h+var_2C] ; 总长度
  .text:004167D5                 call    sub_42BF10      ; A+A2+A3进行sha1处理
  .text:004167DA                 mov     ecx, off_470DC0 ; A
  .text:004167E0                 xor     eax, eax        ; eax初始化
  .text:004167E2
  .text:004167E2 loc_4167E2:                             ; CODE XREF: sub_416720+E1j
  .text:004167E2                 movzx   edx, [esp+eax+40h+var_24] ; 从缓冲区中取sha1摘要
  .text:004167E7                 and     edx, 8000001Fh  ; 取低5位和最高位
  .text:004167ED                 jns     short loc_4167F4 ; 高位不为0,直接运算
  .text:004167EF                 dec     edx
  .text:004167F0                 or      edx, 0FFFFFFE0h
  .text:004167F3                 inc     edx
  .text:004167F4
  .text:004167F4 loc_4167F4:                             ; CODE XREF: sub_416720+CDj
  .text:004167F4                 mov     dl, [edx+ecx]   ; 取在字符串A中索引
  .text:004167F7                 mov     [eax+ebp+0Eh], dl ; 写入第一次计算后的字符串,从0xE位起
  .text:004167FB                 add     eax, 1          ; eax++
  .text:004167FE                 cmp     eax, 0Bh        ; eax<0xB
  .text:00416801                 jl      short loc_4167E2
  .text:00416803                 lea     ecx, [esp+40h+var_2C]
  .text:00416807                 mov     [esp+40h+var_4], -1
  .text:0041680F                 call    sub_42BF00      ; 释放内存
  .text:00416814                 mov     ecx, [esp+40h+var_C]
  .text:00416818                 mov     large fs:0, ecx
  .text:0041681F                 pop     ecx
  .text:00416820                 pop     edi
  .text:00416821                 pop     esi
  .text:00416822                 pop     ebp
  .text:00416823                 pop     ebx
  .text:00416824                 mov     ecx, [esp+2Ch+var_10]
  .text:00416828                 xor     ecx, esp
  .text:0041682A                 call    sub_43B3A6      ; 还原seh
  .text:0041682F                 add     esp, 2Ch
  .text:00416832                 retn
  .text:00416832 sub_416720      endp
  
以上两部分是利用新的25字节长字符串B的前13位与特征码连接,做sha1运算,并把摘要的前10个字节,&1F后,做为索引,在“2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ”字符串A中,取出相应字符替换B中16-25位,再与B的原始值进行比较,不等返回0,相等,再检查C[0x10]是否为1、2、3,符合返回1,不符合返回0。

--------------------------------------------------------------------------------
【算法总结】
其实算法不难

1.注册码是由25字符组成

2.注册码必须为“2ABC3DEF4GHJ5KLM6NPQ7RST8UVW9XYZ”(A)中字符,大小写不限

3.注册码2n字节与2n+1字节(0<=n<0xB)在A中的索引(I1,I2),并由两个索引的奇数位和偶数位组合成新的索引i1和i2,i1=(I1 & 0xAA)|(I2 & 0x55),i2=(I1 & 0x55)|(I2 & 0xAA),并根据i1,i2,在A中取出相应字符,填充入新字符B中的n和n+0xE位,顺序完成B的0-21位。最后注册码22-24位(0开始),填入B的11-13位(0开始),形成B

4.产生结构C,C[0]为特征码指针,C[4]为注册码25字节后字符串指针,C[8]为B前4字节(0-3)在A中索引的组合(从低到高每5位),C[0xC]为B7-12字节在A中的索引的组合,C[0x10]为B13字节在A中索引。B4-6字节在A中的索引的组合D取14位放入C[0x20],其他位(0-13)乘0x15180(第天秒数)后,低位加上[470DC8]放入C[0x18],高位加上[470DCC]放入C[0x20]。[470DC8]为某一时间点的高位,[470DCC]为某一时间点的低位。

5.B前13字节,C[4]指向字符串,C[0]指向字符串组合成字符串E,对E进行sha1运算,并把摘要的前12字节顺序写回B的后12字节,形成B1,B与B1进行对比,相同则验证C[0x10]为1,2,3之一,通过置C[0x21]为1,并反回C结构,否则返回0

6.5验证通过则根据C[0x20]值是否为1,使用C[0x18],C[0x1C]以及C[0x1C]与当时时间进行较验,不通过,报过期;通过后则以C[0x18]和C[0x1C]与特定值([45AEF0][45AEF4])进行校验,不通过,报错误版本,通过则返回结构C。5验证不通过则使用下一组特征码重复1-5过程,特征码共6组,代表不同的版本。

--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2009年06月08日 16:43:57