• 标 题:原创-XNview v1.65算法分析
  • 作 者:xbb-NCG
  • 时 间:2003年12月15日 08:28
  • 链 接:http://bbs.pediy.com

XNview v1.65算法分析

【软件简介】:支持多达 70 种格式的图形浏览、转换、编辑软件,还可制作 Slide Show。是否嫌ACDSEE太大功能太少?这个软件能很好地解决问题,他具有抓图、编辑图象、增加特效的功能,支持你所知道的所有格式及你不知道的格式(包括电影、MP3)。支持简体中文语言。 
  
【声    明】:破解旨在学习技术,无其它目的。失误之处敬请诸位大侠赐教!

【程 序 名】:XNview.exe
【版    本】:v1.65   <-不知道它现在的版本是多少,管它的先看看再说。:)
【大    小】:730KB
【语    言】:Microsoft Visual C++ 6.0
【运行平台】:W9x/NT/W2K/WXP
【保护方式】:ASPack / ASProtect x.xx壳/注册码
【分析方式】:追注册码/分析注册算法
【难    度】:简单
【工    具】:AspackDie141/PEid0.9/W32Dasm8.93+/TRW2000 v1.23
【程序下载】:http://www.xnview.com

【作    者】:xbb_NCG

【分    析】:

    用PEid0.9查看程序被ASPack加壳,AspackDie141脱壳(本想尝试手动脱壳,不过功能不够,还需要学习)。查看脱壳后的程序是用Microsoft Visual C++ 6.0编的,点击软件菜单 帮助->注册 会弹出一个注册对话框,输入xbb-NCG和假注册码123456789提示"非法注册"。于是用ResHacker3.4.0.79版打开它。在对话框资源中我们可以找到以NVIEWREGISTRATION名的对话框资源,点击它左边的+号,点击展开的1033项会显示一个一程序中一样的对话框,并且右边窗口中可以找到CAPTION"Registration"字样。OK,复制Registration。用W32Dasm8.93+反汇编程序,打开串式参考,在Search栏粘贴Registration然后搜索,我们会发现第一个字符是"Invalid registration"(非法注册<---:)HOHO就是它)。这个字串的中文含义和我们前面在程序中输入假注册码后的提示信息是一样的:)。现在双击它我们会看到如下代码。
    如果我们要找出软件的注册算法的话就要在TRW2000中下bpx 466E40断点,因为在466E52下面我们可清楚地看到GetDlgItemTextA这个API,很明显程序调用了它来获取注册对话框里的字符。当然直接下bpx getdlgitemtexta断点也行,随个人喜好。因为我要跟踪注册码的算法,所以从前面一步步地跟下来要好些。:)
    OK,开工了(对了,不要忘了准备一些纸和笔,随时在纸上对一些语句做注释,这样不会退出TRW2000后就忘了,以后写手记也要靠它的。做为新手这点一定要做到,不要怕累,做多了,你会对一些汇编语句非常熟悉的,一看就知道是干什么的。遇到不懂的汇编语句就去看汇编的书找找,这样你会记得更牢些。这是我个人的一些做法,你不一定要像我这样。:))

*******************************************************************************

:00466E3C 90                      nop
:00466E3D 90                      nop
:00466E3E 90                      nop
:00466E3F 90                      nop
:00466E40 81EC68010000            sub esp, 00000168
:00466E46 8D442468                lea eaxdword ptr [esp+68]
:00466E4A 56                      push esi
:00466E4B 8BB42470010000          mov esidword ptr [esp+00000170]
:00466E52 57                      push edi

* Reference To: USER32.GetDlgItemTextA, Ord:0104h
                                  |
:00466E53 8B3D40A55300            mov edidword ptr [0053A540]

* Possible Ref to Menu: BROWSERMENU, Item: "Create Panorama..."
                                  |
:00466E59 6800010000              push 00000100
:00466E5E 50                      push eax

* Possible Reference to Dialog: NVIEWAUTOCROP, CONTROL_ID:07D0, ""
                                  |
:00466E5F 68D0070000              push 000007D0
:00466E64 56                      push esi
:00466E65 FFD7                    call edi
:00466E67 8D4C2410                lea ecxdword ptr [esp+10]

* Possible Ref to Menu: NVIEWMENU, Item: "Crop   Ctrl+Y"
                                  |
:00466E6B 6A20                    push 00000020
:00466E6D 51                      push ecx

* Possible Reference to Dialog: NVIEWAUTOCROP, CONTROL_ID:07D1, ""
                                  |
:00466E6E 68D1070000              push 000007D1
:00466E73 56                      push esi
:00466E74 FFD7                    call edi
:00466E76 8A442470                mov albyte ptr [esp+70]  <-检测用户名是否为0
:00466E7A 84C0                    test alal
:00466E7C 0F843A010000            je 00466FBC                <-等于0则跳
:00466E82 8A442410                mov albyte ptr [esp+10]  <-检测注册码是否为0
:00466E86 84C0                    test alal
:00466E88 0F842E010000            je 00466FBC                <-等于0测跳
:00466E8E 8D542408                lea edxdword ptr [esp+08]
:00466E92 8D442470                lea eaxdword ptr [esp+70]
:00466E96 52                      push edx
:00466E97 50                      push eax
:00466E98 E8A340FAFF              call 0040AF40                  <-注册码计算CALL,后面跟入分析...
:00466E9D 8D4C2418                lea ecxdword ptr [esp+18]    <-ECX=假注册码  
:00466EA1 51                      push ecx
:00466EA2 E8BC9F0000              call 00470E63                  <-将假注册码转换成16进制数
:00466EA7 8B4C2414                mov ecxdword ptr [esp+14]    <-ECX为真注册码的16进制,在此处键入? ecx即可见到真注册码
:00466EAB 83C40C                  add esp, 0000000C                问题:为什么用?而不用D。答:因为注册码是以16进制显示的。:) 
:00466EAE 3BC8                    cmp ecxeax                   <-真假注册码比较
:00466EB0 745D                    je 00466F0F                    <-真假注册码相等则跳到注册成功处
:00466EB2 A1288C5800              mov eaxdword ptr [00588C28]
:00466EB7 8D542430                lea edxdword ptr [esp+30]

* Possible Ref to Menu: NVIEWMENU, Item: "16 Grey scale (Dither)"
                                  |
:00466EBB 6A40                    push 00000040
:00466EBD 52                      push edx

* Possible Reference to String Resource ID=05011: "Invalid registration"  <-双击后我们来到这里
                                  |
:00466EBE 6893130000              push 00001393
:00466EC3 50                      push eax

* Reference To: USER32.LoadStringA, Ord:01ABh
                                  |
:00466EC4 FF15F8A55300            Call dword ptr [0053A5F8]

* Possible Ref to Menu: NVIEWDEFAULTME, Item: "Slide Show...   Ctrl+L"
                                  |
:00466ECA 6A10                    push 00000010
:00466ECC 8D4C2434                lea ecxdword ptr [esp+34]
:00466ED0 689C325800              push 0058329C
:00466ED5 51                      push ecx
:00466ED6 56                      push esi

* Reference To: USER32.MessageBoxA, Ord:01BEh
                                  |
:00466ED7 FF157CA55300            Call dword ptr [0053A57C]          <-非法注册提示

* Possible Reference to Dialog: NVIEWAUTOCROP, CONTROL_ID:07D0, ""
                                  |
:00466EDD 68D0070000              push 000007D0
:00466EE2 56                      push esi

* Reference To: USER32.GetDlgItem, Ord:0102h
                                  |
:00466EE3 FF151CA65300            Call dword ptr [0053A61C]
:00466EE9 50                      push eax

* Reference To: USER32.SetFocus, Ord:022Fh
                                  |
:00466EEA FF1558A55300            Call dword ptr [0053A558]
:00466EF0 689C325800              push 0058329C

* Possible Reference to Dialog: NVIEWAUTOCROP, CONTROL_ID:07D1, ""
                                  |
:00466EF5 68D1070000              push 000007D1
:00466EFA 56                      push esi

* Reference To: USER32.SetDlgItemTextA, Ord:022Ch
                                  |
:00466EFB FF15FCA55300            Call dword ptr [0053A5FC]
:00466F01 5F                      pop edi

* Possible Ref to Menu: BROWSERMENU, Item: "Open..."
                                  |
:00466F02 B801000000              mov eax, 00000001
:00466F07 5E                      pop esi
:00466F08 81C468010000            add esp, 00000168
:00466F0E C3                      ret



* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00466EB0(C)                                             <--------注册码比对正确后跳来此处
|
:00466F0F 8D542470                lea edxdword ptr [esp+70]

* Possible Ref to Menu: BROWSERMENU, Item: "Create Panorama..."
                                  |
:00466F13 6800010000              push 00000100
:00466F18 52                      push edx

* Possible Reference to Dialog: NVIEWAUTOCROP, CONTROL_ID:07D0, ""
                                  |
:00466F19 68D0070000              push 000007D0
:00466F1E 56                      push esi
:00466F1F FFD7                    call edi
:00466F21 8D442410                lea eaxdword ptr [esp+10]

* Possible Ref to Menu: NVIEWMENU, Item: "Crop   Ctrl+Y"
                                  |
:00466F25 6A20                    push 00000020
:00466F27 50                      push eax

* Possible Reference to Dialog: NVIEWAUTOCROP, CONTROL_ID:07D1, ""
                                  |
:00466F28 68D1070000              push 000007D1
:00466F2D 56                      push esi
:00466F2E FFD7                    call edi
:00466F30 8D4C2470                lea ecxdword ptr [esp+70]
:00466F34 51                      push ecx

* Possible StringData Ref from Data Obj ->"LicenseName"
                                  |
:00466F35 6828365600              push 00563628
:00466F3A 6A00                    push 00000000
:00466F3C E8FF5DFDFF              call 0043CD40              <-用户名写入注册表
:00466F41 8D54241C                lea edxdword ptr [esp+1C]
:00466F45 52                      push edx

* Possible StringData Ref from Data Obj ->"LicenseNumber"
                                  |
:00466F46 6818365600              push 00563618
:00466F4B 6A00                    push 00000000
:00466F4D E8EE5DFDFF              call 0043CD40              <-注册码写入注册表
:00466F52 A12C8C5800              mov eaxdword ptr [00588C2C]
:00466F57 83C418                  add esp, 00000018             问题:你怎么知道上面是写注册表?答:因为我用Regmon这个软件
                                                                      对软件启动时的动作进行了监测的。:)
* Possible Ref to Menu: BROWSERMENU, Item: "Open..."
                                  |
:00466F5A C705488C580001000000    mov dword ptr [00588C48], 00000001

* Possible Ref to Menu: BROWSERMENU, Item: "Open..."
                                  |
:00466F64 6A01                    push 00000001

* Possible Ref to Menu: BROWSERMENU, Item: "Registration"
                                  |
:00466F66 68DE000000              push 000000DE
:00466F6B 50                      push eax

* Reference To: USER32.GetMenu, Ord:011Ch
                                  |
:00466F6C FF154CA55300            Call dword ptr [0053A54C]
:00466F72 50                      push eax

* Reference To: USER32.EnableMenuItem, Ord:00B5h
                                  |
:00466F73 FF1530A55300            Call dword ptr [0053A530]      <-将帮助菜单中注册选项禁用(显示为灰色)
:00466F79 8B15288C5800            mov edxdword ptr [00588C28]    问题:你怎么知道这里是对菜单的禁用?答:因为EnableMenuItem,
:00466F7F 8D4C2430                lea ecxdword ptr [esp+30]            这在编程中是对一个控件的可用或不可能进行控制的,当它的
                                                                         为TRUE时,可用;为FALSE时,则不可用。:)
* Possible Ref to Menu: NVIEWMENU, Item: "16 Grey scale (Dither)"
                                  |
:00466F83 6A40                    push 00000040
:00466F85 51                      push ecx

* Possible Reference to String Resource ID=05012: "Registration succesfull"
                                  |
:00466F86 6894130000              push 00001394
:00466F8B 52                      push edx

* Reference To: USER32.LoadStringA, Ord:01ABh
                                  |
:00466F8C FF15F8A55300            Call dword ptr [0053A5F8]

* Possible Ref to Menu: NVIEWMENU, Item: "16 Grey scale (Dither)"
                                  |
:00466F92 6A40                    push 00000040
:00466F94 8D442434                lea eaxdword ptr [esp+34]
:00466F98 689C325800              push 0058329C
:00466F9D 50                      push eax
:00466F9E 56                      push esi

* Reference To: USER32.MessageBoxA, Ord:01BEh
                                  |
:00466F9F FF157CA55300            Call dword ptr [0053A57C]    <-注册成功提示
:00466FA5 6A00                    push 00000000
:00466FA7 56                      push esi

* Reference To: USER32.EndDialog, Ord:00B9h
                                  |
:00466FA8 FF15F4A55300            Call dword ptr [0053A5F4]
:00466FAE 5F                      pop edi

* Possible Ref to Menu: BROWSERMENU, Item: "Open..."
                                  |
:00466FAF B801000000              mov eax, 00000001
:00466FB4 5E                      pop esi
:00466FB5 81C468010000            add esp, 00000168
:00466FBB C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00466E7C(C), :00466E88(C)                                          <-用户名和注册码为空跳到这里
|
:00466FBC 8B15288C5800            mov edxdword ptr [00588C28]
:00466FC2 8D4C2430                lea ecxdword ptr [esp+30]

* Possible Ref to Menu: NVIEWMENU, Item: "16 Grey scale (Dither)"
                                  |
:00466FC6 6A40                    push 00000040
:00466FC8 51                      push ecx

* Possible Reference to String Resource ID=05011: "Invalid registration"
                                  |
:00466FC9 6893130000              push 00001393
:00466FCE 52                      push edx

* Reference To: USER32.LoadStringA, Ord:01ABh
                                  |
:00466FCF FF15F8A55300            Call dword ptr [0053A5F8]

* Possible Ref to Menu: NVIEWDEFAULTME, Item: "Slide Show...   Ctrl+L"
                                  |
:00466FD5 6A10                    push 00000010
:00466FD7 8D442434                lea eaxdword ptr [esp+34]
:00466FDB 689C325800              push 0058329C
:00466FE0 50                      push eax
:00466FE1 56                      push esi

* Reference To: USER32.MessageBoxA, Ord:01BEh
                                  |
:00466FE2 FF157CA55300            Call dword ptr [0053A57C]        <-非法注册提示
:00466FE8 5F                      pop edi

* Possible Ref to Menu: BROWSERMENU, Item: "Open..."
                                  |
:00466FE9 B801000000              mov eax, 00000001
:00466FEE 5E                      pop esi
:00466FEF 81C468010000            add esp, 00000168
:00466FF5 C3                      ret


*************************************************************************************
    跟入注册码算法call 0040AF40...
    
.............

* Referenced by a CALL at Addresses:
|:0040B0FC   , :00466E98       <-程序有两处调用此CALL检查注册码的正确性,40B0FC显然为程序启动时的调用。
|
:0040AF40 8B542404                mov edxdword ptr [esp+04]         <-EDX为用户名
:0040AF44 53                      push ebx
:0040AF45 55                      push ebp
:0040AF46 56                      push esi
:0040AF47 57                      push edi
:0040AF48 8BFA                    mov ediedx                        <-EDIX=用户名
:0040AF4A 83C9FF                  or ecx, FFFFFFFF
:0040AF4D 33C0                    xor eaxeax                        <-EAX=0
:0040AF4F F2                      repnz                               <_取用户名
:0040AF50 AE                      scasb                               < 的位数
:0040AF51 F7D1                    not ecx
:0040AF53 49                      dec ecx

* Possible StringData Ref from Data Obj ->"獕宁Fx鹦琪绻?蒔s"
                                  |
:0040AF54 BE80355600              mov esi, 00563580                   <-字符表道地址入ESI
:0040AF59 8BE9                    mov ebpecx                        <-用户名位数入EBP

* Possible Ref to Menu: NVIEWMENU, Item: "Reopen   Ctrl+R"
                                  |
:0040AF5B B905000000              mov ecx, 00000005                   <-ECX=5
:0040AF60 BFA8325800              mov edi, 005832A8                   <-EDI=5832A8这个地址
:0040AF65 F3                      repz                                <_将563580处的字符表移到
:0040AF66 A5                      movsd                               < 5832A8处,共20位
:0040AF67 8BF0                    mov esieax                        <-ESI=0
:0040AF69 7421                    je 0040AF8C                               +---------------------+
                                                                            |字符表:             |
* Referenced by a (U)nconditional or (C)onditional Jump at Address:         |4347622D4E 78F0D003E7|
|:0040AF8A(C)                                                               |F7FDF4E7B9 B51BC95073|
|                                                                           +---------------------+
:0040AF6B 8A0C16                  mov clbyte ptr [esi+edx]----     <-CL为用户名的ASCII码
:0040AF6E 8AD9                    mov blcl                     
:0040AF70 3298A8325800            xor blbyte ptr [eax+005832A8]    <-BL与EAX+5832A8(字符表1-5位)进行异或运算
:0040AF76 40                      inc eax      <-EAX+1             
:0040AF77 83F805                  cmp eax, 00000005   <-EAX=5吗?   |此循环将用户名逐位与字符表中1-5
:0040AF7A 881C16                  mov byte ptr [esi+edx], bl        |位进行异或运算。循环算出的结果
:0040AF7D 8888A7325800            mov byte ptr [eax+005832A7], cl   |放入ESI+EDX中。
:0040AF83 7502                    jne 0040AF87   <-EAX不等于5则跳   |
:0040AF85 33C0                    xor eaxeax   <-EAX=5则EAX=0     |结果:D2EBA6D3083B25  <---中间数1
                                                                    |
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |第一次循环
|:0040AF83(C)                                                      /
|                                                                 /
:0040AF87 46                      inc esi   <-计数器             /
:0040AF88 3BF5                    cmp esiebp                  /     <-计数器是否等于用户名位数
:0040AF8A 72DF                    jb 0040AF6B__________________/

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040AF69(C)
|
:0040AF8C 33FF                    xor ediedi
:0040AF8E 33C9                    xor ecxecx
:0040AF90 85ED                    test ebpebp
:0040AF92 7626                    jbe 0040AFBA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:   
|:0040AFB8(C)
|
:0040AF94 8A9FAD325800            mov blbyte ptr [edi+005832AD]-   <-BL指向字符表第6位
:0040AF9A 8BF5                    mov esiebp                       <-ESI=用户名位数
:0040AF9C 2BF1                    sub esiecx                       
:0040AF9E 4E                      dec esi            <-ESI-1         |
:0040AF9F 8A0416                  mov albyte ptr [esi+edx]         |<-ESI+EDX=中间数1
:0040AFA2 32D8                    xor blal                         |此循环将第一次循环的结果从右向左依次
:0040AFA4 47                      inc edi            <-计数器        |与字符表中6-10位进行异或运算,结果保
:0040AFA5 881C16                  mov byte ptr [esi+edx], bl         |存在ESI+EDX中。
:0040AFA8 8887AC325800            mov byte ptr [edi+005832AC], al    |
:0040AFAE 83FF05                  cmp edi, 00000005  <-EDI与5比较    |结果:E9CE41D0D8CB5D  <---中间数2
:0040AFB1 7502                    jne 0040AFB5                       |
:0040AFB3 33FF                    xor ediedi                       |
                                                                     |
* Referenced by a (U)nconditional or (C)onditional Jump at Address:  |第二次循环
|:0040AFB1(C)                                                       /
|                                                                  / 
:0040AFB5 41                      inc ecx                         /  
:0040AFB6 3BCD                    cmp ecxebp                   /    <-循环结束了吗?
:0040AFB8 72DA                    jb 0040AF94 __________________/     <-没结束就跳   

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040AF92(C)
|
:0040AFBA 33F6                    xor esiesi
:0040AFBC 33FF                    xor ediedi
:0040AFBE 85ED                    test ebpebp
:0040AFC0 7621                    jbe 0040AFE3

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040AFE1(C)
|
:0040AFC2 8A0417                  mov albyte ptr [edi+edx]----     <-EDI+EDX=中间数2
:0040AFC5 8A8EB2325800            mov clbyte ptr [esi+005832B2]
:0040AFCB 32C8                    xor clal                         <-CL与AL做异或运算
:0040AFCD 46                      inc esi                            
:0040AFCE 880C17                  mov byte ptr [edi+edx], cl        |
:0040AFD1 8886B1325800            mov byte ptr [esi+005832B1], al   |
:0040AFD7 83FE05                  cmp esi, 00000005                 |此循环将第二次循环的结果从左向右依次
:0040AFDA 7502                    jne 0040AFDE                      |与字符表中11-15位进行异或运算,结果保
:0040AFDC 33F6                    xor esiesi                      |存在EDI+EDX中。
                                                                    |
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |结果:1E33B537612293  <---中间数3
|:0040AFDA(C)                                                       |第三次循环
|                                                                  /
:0040AFDE 47                      inc edi                         /   <-计数器
:0040AFDF 3BFD                    cmp ediebp                   /  
:0040AFE1 72DF                    jb 0040AFC2___________________/

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040AFC0(C)
|
:0040AFE3 33FF                    xor ediedi
:0040AFE5 33C9                    xor ecxecx
:0040AFE7 85ED                    test ebpebp
:0040AFE9 7626                    jbe 0040B011

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B00F(C)
|
:0040AFEB 8A9FB7325800            mov blbyte ptr [edi+005832B7]
:0040AFF1 8BF5                    mov esiebp                    
:0040AFF3 2BF1                    sub esiecx                     
:0040AFF5 4E                      dec esi                           
:0040AFF6 8A0416                  mov albyte ptr [esi+edx]         | <-ESI+EDX=1E33B537612293
:0040AFF9 32D8                    xor blal                         | <-BL与AL异或
:0040AFFB 47                      inc edi                            |此循环将第三次循环的结果从右向左依次
:0040AFFC 881C16                  mov byte ptr [esi+edx], bl         |与字符表中16-20位进行异或运算,结果保
:0040AFFF 8887B6325800            mov byte ptr [edi+005832B6], al    |存在ESI+EDX中。
:0040B005 83FF05                  cmp edi, 00000005                  |
:0040B008 7502                    jne 0040B00C                       |
:0040B00A 33FF                    xor ediedi                       |结果:3CA0C667A83926  <---中间数4
                                                                     |
* Referenced by a (U)nconditional or (C)onditional Jump at Address:  |第四次循环
|:0040B008(C)                                                       /
|                                                                  /
:0040B00C 41                      inc ecx                         /    <-计数器
:0040B00D 3BCD                    cmp ecxebp                   /
:0040B00F 72DA                    jb 0040AFEB___________________/

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040AFE9(C)
|
:0040B011 8B7C2418                mov edidword ptr [esp+18]          <-EDI=假注册码
:0040B015 33C0                    xor eaxeax
:0040B017 85ED                    test ebpebp
:0040B019 C70700000000            mov dword ptr [edi], 00000000        <-将[EDI]所指向的地址按DW格式清零
:0040B01F 7617                    jbe 0040B038

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B036(C)
|                                                                    第五次循环
:0040B021 8BC8                    mov ecxeax---------------
:0040B023 83E103                  and ecx, 00000003                   <-ECX=4时,EAX=0
:0040B026 8A1C39                  mov blbyte ptr [ecx+edi]   
:0040B029 8D3439                  lea esidword ptr [ecx+edi]  
:0040B02C 8A0C10                  mov clbyte ptr [eax+edx]     |此循环将中间数4前4位依次放入EDI所指向的
:0040B02F 02D9                    add blcl                     |地址中,第5位数继续放入地址的第一位,但
:0040B031 40                      inc eax     <-EAX加1,计数器  / 要加上此地址中原来存在的数;第6位放入地址
:0040B032 3BC5                    cmp eaxebp                 /  的第二位并加上原来存在的数,依此类推,直
:0040B034 881E                    mov byte ptr [esi], bl      /   至中间数取完。得到的4位数的十进制就是注册码。
:0040B036 72E9                    jb 0040B021________________/ 结果:E4D9EC67=67ECD9E4=174375524 <-注册码:)
                                                                         
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B01F(C)
|
:0040B038 5F                      pop edi
:0040B039 5E                      pop esi
:0040B03A 5D                      pop ebp
:0040B03B 5B                      pop ebx
:0040B03C C3                      ret                          <-返回ESI=67ECD9E4到主程序

*************************************************************************************
【算法总结】:

    通过上面对算法CALL的逐句分析我们可以看出,软件是通过我们输入的用户名与给定的字符表中的字符进行四次循环计算后得出一个中间数,然后把这个中间数进行按4位拆分进行相加计算,即如果中间数是七位,则把第一位与第五位相加,结果放入第一位地址;第二位与第六位相加,结果放入第二位地址,依此类推,直到中间数取完为止。最后得到一个4位数(16进制的),这个数由算法CALL返回到主程序,与我们输入的假注册码的16进制进行比对。正确就写注册表,错误就提示注册码错误。
    另,用户名超过10位注册码会是个负数,不过一样注册码,没事的。:)
*************************************************************************************
【注册信息】:

用Regmon可以监测到软件在注册成功后在注册里写入注册信息:

HKCUSoftwareXnViewLicenseName  <-用户名"xbb-NCG"  
  
HKCUSoftwareXnViewLicenseNumber  <-注册码"1743575524"  

取注册注册只需把LicenseName和LicenseNumber两个键值删除即可。

*************************************************************************************
【注 册 机】:

    我的编程非常差,虽然能找追算法,可还不够能力用代码还原它,正在学习C,争取能在以后能写出注册机。
    
                            xbb-NCG
                                                2003.12.15 上午