qifeon 发表于 2008-8-9 16:00:14

Techra Virtual Programmable Keyboard 1.02算法分析

【文章标题】: Techra Virtual Programmable Keyboard 1.02算法分析
【文章作者】: qifeon
【软件名称】: Techra Virtual Programmable Keyboard
【下载地址】: http://www.techrasoft.com/index.asp
【保护方式】: 注册码
【编写语言】: 英文
【操作平台】: winxp sp2
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
一、分析过程

首先PEID查壳,Borland Delphi 6.0 - 7.0编写,无壳。运行程序,输入“qifeon,123456”,有错误提示"invalid unlock information"。好的,我们就利用最简单而有效的查找字符串的方法。

不要小瞧它哦,不必再去麻烦DeDe先生了。OD载入,插件查找上面的错误提示。
Ultra String Reference, 条目 3004
   Address=0056D6B0
   Disassembly=mov   eax, 0056D7D4
   Text String=invalid unlock information!

双击后来到

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

0056D6A9   .^\E9 2A69E9FF   jmp   00403FD8                         ;向上找到跳转
0056D6AE   .^ EB F0         jmp   short 0056D6A0
0056D6B0   > \B8 D4D75600   mov   eax, 0056D7D4                  ;invalid unlock information!
0056D6B5   .E8 C66AECFF   call    00434180
0056D6BA   .8B83 18030000 mov   eax, dword ptr
0056D6C0   .8B10          mov   edx, dword ptr
0056D6C2   .FF92 C4000000 call    dword ptr
0056D6C8   >33C0          xor   eax, eax
0056D6CA   .5A            pop   edx
0056D6CB   .59            pop   ecx
0056D6CC   .59            pop   ecx

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

由跳转向上找到注册按钮事件段首

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

0056D536   .55            push    ebp                              ;段首
0056D537   .68 F8D65600   push    0056D6F8
0056D53C   .64:FF30       push    dword ptr fs:
0056D53F   .64:8920       mov   dword ptr fs:, esp
0056D542   .8D55 F8       lea   edx, dword ptr
0056D545   .8B83 18030000 mov   eax, dword ptr
0056D54B   .E8 7069EEFF   call    00453EC0                         ;取用户名长度
0056D550   .837D F8 00    cmp   dword ptr , 0
0056D554   .74 14         je      short 0056D56A                   ;用户名为空则跳
0056D556   .8D55 F4       lea   edx, dword ptr
0056D559   .8B83 1C030000 mov   eax, dword ptr
0056D55F   .E8 5C69EEFF   call    00453EC0                         ;取试炼码长度
0056D564   .837D F4 00    cmp   dword ptr , 0               试炼码是否为空?
0056D568   .75 1D         jnz   short 0056D587                     
0056D56A   >B8 0CD75600   mov   eax, 0056D70C                  ;please enter unlock information!
0056D56F   .E8 0C6CECFF   call    00434180
0056D574   .8B83 18030000 mov   eax, dword ptr
0056D57A   .8B10          mov   edx, dword ptr
0056D57C   .FF92 C4000000 call    dword ptr
0056D582   .E9 41010000   jmp   0056D6C8
0056D587   >8D55 F0       lea   edx, dword ptr
0056D58A   .8B83 1C030000 mov   eax, dword ptr
0056D590   .E8 2B69EEFF   call    00453EC0
0056D595   .8B45 F0       mov   eax, dword ptr           ;试炼码放入eax
0056D598   .50            push    eax
0056D599   .8D55 E8       lea   edx, dword ptr
0056D59C   .8B83 18030000 mov   eax, dword ptr
0056D5A2   .E8 1969EEFF   call    00453EC0
0056D5A7   .8B55 E8       mov   edx, dword ptr           ;用户名放入edx
0056D5AA   .8D4D EC       lea   ecx, dword ptr
0056D5AD   .A1 74B75800   mov   eax, dword ptr
0056D5B2   .8B00          mov   eax, dword ptr
0056D5B4   .E8 D3140000   call    0056EA8C                         ;算法call,我们马上进入
0056D5B9   .8B55 EC       mov   edx, dword ptr           ;真正注册码
0056D5BC   .58            pop   eax                              ;试炼码
0056D5BD   .E8 A274E9FF   call    00404A64                         ;真正注册码与假码相比较
0056D5C2   .0F85 E8000000 jnz   0056D6B0                         ;关键跳转
0056D5C8   .33C0          xor   eax, eax
0056D5CA   .55            push    ebp
0056D5CB   .68 A9D65600   push    0056D6A9
0056D5D0   .64:FF30       push    dword ptr fs:
0056D5D3   .64:8920       mov   dword ptr fs:, esp
0056D5D6   .B2 01         mov   dl, 1
0056D5D8   .A1 489E4300   mov   eax, dword ptr
0056D5DD   .E8 6AC9ECFF   call    00439F4C
0056D5E2   .8945 FC       mov   dword ptr , eax
0056D5E5   .BA 02000080   mov   edx, 80000002
0056D5EA   .8B45 FC       mov   eax, dword ptr
0056D5ED   .E8 FAC9ECFF   call    00439FEC
0056D5F2   .B1 01         mov   cl, 1
0056D5F4   .BA 38D75600   mov   edx, 0056D738                  ;software\vpk
0056D5F9   .8B45 FC       mov   eax, dword ptr
0056D5FC   .E8 2FCBECFF   call    0043A130
0056D601   .8D55 E4       lea   edx, dword ptr
0056D604   .8B83 18030000 mov   eax, dword ptr
0056D60A   .E8 B168EEFF   call    00453EC0
0056D60F   .8B45 E4       mov   eax, dword ptr
0056D612   .50            push    eax
0056D613   .B9 50D75600   mov   ecx, 0056D750                  ;registeredto
0056D618   .33D2          xor   edx, edx
0056D61A   .8B45 FC       mov   eax, dword ptr
0056D61D   .E8 9ECFECFF   call    0043A5C0
0056D622   .8D55 E0       lea   edx, dword ptr
0056D625   .8B83 1C030000 mov   eax, dword ptr
0056D62B   .E8 9068EEFF   call    00453EC0
0056D630   .8B45 E0       mov   eax, dword ptr
0056D633   .50            push    eax
0056D634   .B9 68D75600   mov   ecx, 0056D768                  ;unlockcode
0056D639   .33D2          xor   edx, edx
0056D63B   .8B45 FC       mov   eax, dword ptr
0056D63E   .E8 7DCFECFF   call    0043A5C0
0056D643   .A1 74B75800   mov   eax, dword ptr
0056D648   .8B00          mov   eax, dword ptr
0056D64A   .E8 FD120000   call    0056E94C
0056D64F   .84C0          test    al, al
0056D651   .74 2F         je      short 0056D682
0056D653   .B8 7CD75600   mov   eax, 0056D77C                  ;software has been successfully unlocked!
0056D658   .E8 236BECFF   call    00434180
0056D65D   .A1 74B75800   mov   eax, dword ptr
0056D662   .8B00          mov   eax, dword ptr
0056D664   .8B80 28030000 mov   eax, dword ptr
0056D66A   .33D2          xor   edx, edx
0056D66C   .E8 078AEFFF   call    00466078
0056D671   .C783 4C020000>mov   dword ptr , 1
0056D67B   .E8 3C6AE9FF   call    004040BC
0056D680   .EB 46         jmp   short 0056D6C8
0056D682   >B8 B0D75600   mov   eax, 0056D7B0                  ;error unlocking software!
0056D687   .E8 F46AECFF   call    00434180
0056D68C   .E8 2B6AE9FF   call    004040BC

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

0056D5B4处,进入算法 call    0056EA8C

*********************************************************************************************************************************************8**********


0056EA8C   $55            push    ebp
0056EA8D   .8BEC          mov   ebp, esp
0056EA8F   .6A 00         push    0
0056EA91   .6A 00         push    0
0056EA93   .6A 00         push    0
0056EA95   .6A 00         push    0
0056EA97   .6A 00         push    0
0056EA99   .53            push    ebx
0056EA9A   .56            push    esi
0056EA9B   .57            push    edi
0056EA9C   .8BF9          mov   edi, ecx
0056EA9E   .8955 FC       mov   dword ptr , edx
0056EAA1   .8B45 FC       mov   eax, dword ptr
0056EAA4   .E8 5F60E9FF   call    00404B08
0056EAA9   .33C0          xor   eax, eax
0056EAAB   .55            push    ebp
0056EAAC   .68 E2EB5600   push    0056EBE2
0056EAB1   .64:FF30       push    dword ptr fs:
0056EAB4   .64:8920       mov   dword ptr fs:, esp
0056EAB7   .33C0          xor   eax, eax
0056EAB9   .55            push    ebp
0056EABA   .68 B5EB5600   push    0056EBB5
0056EABF   .64:FF30       push    dword ptr fs:
0056EAC2   .64:8920       mov   dword ptr fs:, esp
0056EAC5   .8D45 F4       lea   eax, dword ptr
0056EAC8   .8B4D FC       mov   ecx, dword ptr          ;用户名
0056EACB   .BA F8EB5600   mov   edx, 0056EBF8                  ;ASCII "TEST123"
0056EAD0   .E8 8F5EE9FF   call    00404964                         ;连接固定字符串"TEST123"与用户名,设为link
0056EAD5   .8B45 F4       mov   eax, dword ptr
0056EAD8   .8BD7          mov   edx, edi
0056EADA   .E8 598AECFF   call    00437538                         ;把连接后字符串link翻转,设为reverse
0056EADF   .33C0          xor   eax, eax
0056EAE1   .8945 F8       mov   dword ptr , eax
0056EAE4   .8B07          mov   eax, dword ptr
0056EAE6   .E8 2D5EE9FF   call    00404918
0056EAEB   .8BF0          mov   esi, eax                         ;字符串reverse长度设为len放入esi
0056EAED   .85F6          test    esi, esi
0056EAEF   .7E 15         jle   short 0056EB06
0056EAF1   .BB 01000000   mov   ebx, 1                           ;ebx=1
0056EAF6   >8B07          mov   eax, dword ptr              ;字符串reverse放入eax
0056EAF8   .0FB64418 FF   movzx   eax, byte ptr       ;字符串reverse逐位取扩展放入eax
0056EAFD   .F7EB          imul    ebx                              ;eax=eax*ebx
0056EAFF   .0145 F8       add   dword ptr , eax         ;=+eax,循环最后计算值保存于ebp-8,设为sum
0056EB02   .43            inc   ebx                              ;ebx增1
0056EB03   .4E            dec   esi                              ;esi减1
0056EB04   .^ 75 F0         jnz   short 0056EAF6                   ;esi不为0则继续循环
0056EB06   >8B07          mov   eax, dword ptr
0056EB08   .E8 0B5EE9FF   call    00404918
0056EB0D   .8BF0          mov   esi, eax
0056EB0F   .85F6          test    esi, esi
0056EB11   .7E 3C         jle   short 0056EB4F
0056EB13   .BB 01000000   mov   ebx, 1
0056EB18   >8B07          mov   eax, dword ptr              ;字符串reverse放入eax
0056EB1A   .0FB64418 FF   movzx   eax, byte ptr       ;字符串reverse逐位取扩展放入eax
0056EB1F   .F7EB          imul    ebx                              ;eax=eax*ebx
0056EB21   .83C0 02       add   eax, 2                           ;eax=eax+2
0056EB24   .3345 F8       xor   eax, dword ptr          ;eax=eax xor sum
0056EB27   .B9 0A000000   mov   ecx, 0A                        ;ecx=0Ah
0056EB2C   .99            cdq                                    ;edx清零
0056EB2D   .F7F9          idiv    ecx                              ;eax/ecx 商保存在 eax余数保存于edx
0056EB2F   .8BC2          mov   eax, edx
0056EB31   .8D55 F0       lea   edx, dword ptr
0056EB34   .E8 17A4E9FF   call    00408F50                         ;把上面逐位计算的余数16进制数字转换为对应字符
0056EB39   .8B45 F0       mov   eax, dword ptr
0056EB3C   .8A00          mov   al, byte ptr                ;转换后字符放入al
0056EB3E   .50            push    eax
0056EB3F   .8BC7          mov   eax, edi
0056EB41   .E8 2A60E9FF   call    00404B70
0056EB46   .5A            pop   edx                              ;dl内的值等于上面al数值
0056EB47   .885418 FF   mov   byte ptr , dl         ;dl值替换字符串reverse内字符
0056EB4B   .43            inc   ebx
0056EB4C   .4E            dec   esi                              ;esi不为0则继续循环
0056EB4D   .^ 75 C9         jnz   short 0056EB18
0056EB4F   >8B07          mov   eax, dword ptr              ;reverse全部替换后得到字符串设为replace
0056EB51   .E8 C25DE9FF   call    00404918
0056EB56   .8BF0          mov   esi, eax                         ;字符串replace长度
0056EB58   .85F6          test    esi, esi
0056EB5A   .7E 3D         jle   short 0056EB99
0056EB5C   .BB 01000000   mov   ebx, 1
0056EB61   >8B07          mov   eax, dword ptr              ;字符串replace放入eax
0056EB63   .0FB64418 FF   movzx   eax, byte ptr       ;字符串replace逐位取扩展放入eax
0056EB68   .F7EB          imul    ebx                              ;eax值乘以ebx
0056EB6A   .8BD0          mov   edx, eax                         ;相乘得值由eax放入edx
0056EB6C   .C1E0 03       shl   eax, 3                           ;eax值左移3位
0056EB6F   .2BC2          sub   eax, edx                         ;eax=eax-edx
0056EB71   .B9 0A000000   mov   ecx, 0A                        ;ecx=10
0056EB76   .99            cdq                                    ;edx清零
0056EB77   .F7F9          idiv    ecx                              ;eax/ecx 商保存在 eax余数保存于edx
0056EB79   .8BC2          mov   eax, edx                         ;余数传送给eax
0056EB7B   .8D55 EC       lea   edx, dword ptr
0056EB7E   .E8 CDA3E9FF   call    00408F50                         ;把上面逐位计算的余数16进制数字转换为对应字符
0056EB83   .8B45 EC       mov   eax, dword ptr
0056EB86   .8A00          mov   al, byte ptr                ;转换后字符放入al
0056EB88   .50            push    eax
0056EB89   .8BC7          mov   eax, edi
0056EB8B   .E8 E05FE9FF   call    00404B70
0056EB90   .5A            pop   edx                              ;dl内的值等于上面al数值
0056EB91   .885418 FF   mov   byte ptr , dl         ;dl值替换字符串reverse内字符
0056EB95   .43            inc   ebx
0056EB96   .4E            dec   esi
0056EB97   .^ 75 C8         jnz   short 0056EB61
0056EB99   >57            push    edi
0056EB9A   .8B07          mov   eax, dword ptr              ;replace全部替换后的字符串设为regcode
0056EB9C   .B9 06000000   mov   ecx, 6                           ;ecx=6
0056EBA1   .BA 01000000   mov   edx, 1
0056EBA6   .E8 CD5FE9FF   call    00404B78                         ;取字符串regcode前6位作为注册码
0056EBAB   .33C0          xor   eax, eax
0056EBAD   .5A            pop   edx
0056EBAE   .59            pop   ecx
0056EBAF   .59            pop   ecx
0056EBB0   .64:8910       mov   dword ptr fs:, edx
0056EBB3   .EB 0A         jmp   short 0056EBBF
0056EBB5   .^ E9 6A51E9FF   jmp   00403D24
0056EBBA   .E8 CD54E9FF   call    0040408C
0056EBBF   >33C0          xor   eax, eax
0056EBC1   .5A            pop   edx
0056EBC2   .59            pop   ecx
0056EBC3   .59            pop   ecx
0056EBC4   .64:8910       mov   dword ptr fs:, edx
0056EBC7   .68 E9EB5600   push    0056EBE9
0056EBCC   >8D45 EC       lea   eax, dword ptr
0056EBCF   .BA 03000000   mov   edx, 3
0056EBD4   .E8 A35AE9FF   call    0040467C
0056EBD9   .8D45 FC       lea   eax, dword ptr
0056EBDC   .E8 775AE9FF   call    00404658
0056EBE1   .C3            retn

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


二、注册算法总结

算法有些琐碎,经过多次转换。本人尝试描述清楚。

         
1、固定字符串"TEST123"与用户名name连接得到字符串link;

2、翻转字符串link得到字符串reverse;

3、字符reverse乘以字符串对应位置(i+1)依次相加之和为sum;

4、字符reverse乘以字符串对应位置(i+1),然后加上2,再与sum异或,异或后的值除以10,

    余数转化为16进制对应的字符替换掉reverse,得到字符串replace;(如0x1转为字符"1")

5、字符replace乘以字符串对应位置(i+1),所得数值左移3位,减去replace*(i+1),再除以10,

   余数转化为16进制对应的字符替换掉replace,得到字符串regcode;

6、取字符串regcode前6位组成的字符串即为注册码。


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

三、C语言注册机源码


#include "stdio.h"
#include "string.h"
void main()
{   
        int i,j,k,len,o,p;
       static int sum=0;
        char regcode;
        char replace;
        char reverse;
        char name;
        char link="TEST123";
        printf("请输入用户名:");
        scanf("%s",name);
        strcat (link,name);
          strrev(link);
          strcpy(reverse,link);
        len=strlen(reverse);
        for (i=0;i<len;i++)
        sum=sum+reverse*(i+1);
        for (i=0;i<len;i++)
        {k=reverse*(i+1)+2 ;
                j=k ^ sum;
        replace=j % 10+0x30;
       }
       
        for (i=0;i<len;i++)
        {
                o=replace*(i+1);
                p=o<< 3;
                regcode=(p-o) % 10+0x30;
        }
        regcode='\0';
       
        printf("注册码是:%s",regcode);
       
}
页: [1]
查看完整版本: Techra Virtual Programmable Keyboard 1.02算法分析