看了这个软件的介绍,感觉挺不错的,我从v1.6版开始接触的,断断续续试过几次,偶尔有点时间就捣鼓一下,
这次能够破解它注册码的算法,完全是靠运气,呵呵^_^

       由于写的比较烂,大家凑合着看吧,其实我自已都看不懂了。


    开始以为它是有应该程序SyserApp.exe中进行注册算法的,于是用od跟了进去,
.text:004025E9                 mov     [ecx], al
.text:004025EB                 jnz     short loc_4025E0
.text:004025ED
.text:004025ED loc_4025ED:                             ; CODE XREF: sub_402580+5Bj
.text:004025ED                 push    0               ; int
.text:004025EF                 push    1               ; dwType
.text:004025F1                 lea     eax, [esp+114h+Data]
.text:004025F5                 push    eax             ; lpData
.text:004025F6                 push    offset aHklmSystemCu_2 ; "HKLM\\SYSTEM\\CurrentControlSet\\Services\\"...// 这里是把注册名写入注册表
.text:004025FB                 call    sub_43F4F0
.text:00402600                 mov     WideCharStr, 0
.text:00402609                 mov     esi, [edi+4B4h]
.text:0040260F                 add     esp, 10h
.text:00402612                 test    esi, esi
.text:00402614                 jnz     short loc_40261B
.text:00402616                 mov     esi, offset WideCharStr
.text:0040261B
.text:0040261B loc_40261B:                             ; CODE XREF: sub_402580+94j
.text:0040261B                 mov     al, [esi]
.text:0040261D                 test    al, al
.text:0040261F                 mov     edx, esi
.text:00402621                 lea     ecx, [esp+10Ch+Data]
.text:00402625                 mov     [esp+10Ch+Data], al
.text:00402629                 pop     esi
.text:0040262A                 jz      short loc_40263D
.text:0040262C                 lea     esp, [esp+0]
.text:00402630
.text:00402630 loc_402630:                             ; CODE XREF: sub_402580+BBj
.text:00402630                 mov     al, [edx+2]
.text:00402633                 add     edx, 2
.text:00402636                 inc     ecx
.text:00402637                 test    al, al
.text:00402639                 mov     [ecx], al
.text:0040263B                 jnz     short loc_402630
.text:0040263D
.text:0040263D loc_40263D:                             ; CODE XREF: sub_402580+AAj
.text:0040263D                 push    0               ; int
.text:0040263F                 push    1               ; dwType
.text:00402641                 lea     ecx, [esp+110h+Data]
.text:00402645                 push    ecx             ; lpData
.text:00402646                 push    offset aHklmSystemCu_3 ; "HKLM\\SYSTEM\\CurrentControlSet\\Services\\"...
//这里把注册码写入注册表,而且注册码的长度必须为16个字节
.text:0040264B                 call    sub_43F4F0
.text:00402650                 mov     ecx, [edi+4]
.text:00402653                 add     esp, 10h
.text:00402656                 push    0
.text:00402658                 push    1
.text:0040265A                 push    offset aNotify  ; "Notify"
.text:0040265F                 push    offset aYouMayNeedToRe ; "You may need to restart syser debugger "...
.text:00402664                 call    sub_425D50//提示重启程序验证。
.text:00402669
.text:00402669 loc_402669:                             ; CODE XREF: sub_402580+2Ej
.text:00402669                 mov     ecx, [esp+108h+var_4]
.text:00402670                 mov     al, 1
 
  重启后,根本就断不下来,而且也没有找到进行注册校验的地方,于是怀疑在驱动里面做注册码的校验,以前一直在用Ring3级的调试器,驱动从没有调试过,听说softice很强悍,刚好我这边一个同事有一本最早看雪写的一本加密与解密---软件保护技术及完解决方案。刚好上面有softice的用法,于是在虚拟机中安装了,第一次,感觉真的很别扭,之所以我想用syser debugger,是因为它比softice的界面更直观,一开始我也没有要求得到syser的注册码,只想去这个时间限制,网上找了点资料,驱动里面时间查询用的是KeQuerySystemTime这个函数,首先用IDA反汇编syser.sys这个驱动文件,找到了 KeQuerySystemTime所处的代码t
:0001BC59 loc_1BC59:                              ; CODE XREF: sub_1BB28+117j
.text:0001BC59                 push    edi
.text:0001BC5A                 lea     eax, [esi+0C00h]
.text:0001BC60                 push    ebx             ; Handle
.text:0001BC61                 mov     [eax], ebx
.text:0001BC63                 mov     [eax+4], ebx
.text:0001BC66                 push    eax             ; int
.text:0001BC67                 lea     edi, [esi+0BF8h]
.text:0001BC6D                 lea     eax, [ebp+SourceString]
.text:0001BC73                 mov     [edi], ebx
.text:0001BC75                 mov     [edi+4], ebx
.text:0001BC78                 mov     ecx, P
.text:0001BC7E                 push    eax             ; SourceString
.text:0001BC7F                 call    sub_33EDA
.text:0001BC84                 push    edi             ; CurrentTime
.text:0001BC85                 call    ds:KeQuerySystemTime //这里就是了
.text:0001BC8B                 mov     ecx, esi
.text:0001BC8D                 call    sub_1B8EC
.text:0001BC92                 mov     [esi+0C08h], al
.text:0001BC98                 push    offset aWfsuzqf ; "WfsUzqf"//这里的字符减一就是所对应的"verType",注册表中的一个键值
.text:0001BC9D                 lea     eax, [ebp+SourceString]
.text:0001BCA3                 push    eax
.text:0001BCA4                 call    sub_12EEE

好了,开始用softice加载syser.sys驱动了,
bpload syser.sys
让它在加载syser.sys时,断下来
在syser.sys的加载地址加上0x300再加上0x738处下断点,因为这儿就是算注册码的地方。

:bpload syser.sys
:x
NTICE: Load32 START=00400000  SIZE=75000  KPEB=817345E0  MOD=SyserApp
NTICE: Load32 START=77F80000  SIZE=7B000  KPEB=817345E0  MOD=NTDLL
NTICE: Load32 START=72760000  SIZE=46000  KPEB=817345E0  MOD=ddraw
NTICE: Load32 START=78000000  SIZE=46000  KPEB=817345E0  MOD=msvcrt
NTICE: Load32 START=77E60000  SIZE=D5000  KPEB=817345E0  MOD=KERNEL32
NTICE: Load32 START=77DF0000  SIZE=65000  KPEB=817345E0  MOD=USER32
NTICE: Load32 START=77F40000  SIZE=3C000  KPEB=817345E0  MOD=GDI32
NTICE: Load32 START=72800000  SIZE=6000  KPEB=817345E0  MOD=dciman32
NTICE: Load32 START=77D90000  SIZE=5D000  KPEB=817345E0  MOD=ADVAPI32
NTICE: Load32 START=786F0000  SIZE=71000  KPEB=817345E0  MOD=rpcrt4
NTICE: Load32 START=76BC0000  SIZE=73000  KPEB=817345E0  MOD=wininet
NTICE: Load32 START=77C50000  SIZE=4A000  KPEB=817345E0  MOD=shlwapi
NTICE: Load32 START=74FB0000  SIZE=13000  KPEB=817345E0  MOD=ws2_32
NTICE: Load32 START=74FA0000  SIZE=8000  KPEB=817345E0  MOD=ws2help
NTICE: Load32 START=76AF0000  SIZE=3D000  KPEB=817345E0  MOD=COMDLG32
NTICE: Load32 START=77B30000  SIZE=89000  KPEB=817345E0  MOD=COMCTL32
NTICE: Load32 START=78F90000  SIZE=246000  KPEB=817345E0  MOD=SHELL32
NTICE: Load32 START=75E00000  SIZE=1A000  KPEB=817345E0  MOD=imm32
NTICE: Load32 START=6DD30000  SIZE=6000  KPEB=817345E0  MOD=indicdll
NTICE: Load32 START=F801B000  SIZE=116300  KPEB=819E60C0  MOD=SYSER
Break due to BP 00: BPLOAD "syser" L
:bpx f801b300+7c936
:bpx f801b300+7c938
:bl
00)  BPLOAD "syser" L
01)  BPX 0008:F8097C36
02)  BPX 0008:F8097C38
:bc 1
:u f8097c38
:u f8097c38 l 20
0008:F8097C38  CALL     F8097AD0
0008:F8097C3D  MOVZX     ECX,AL
0008:F8097C40  TEST      ECX,ECX
0008:F8097C42  JNZ      F8097C5E
0008:F8097C44  MOV       BYTE PTR [EBP-0092],00
0008:F8097C4B  LEA       ECX,[EBP-0090]
0008:F8097C51  CALL     F801D9E6
0008:F8097C56  MOV       AL,[EBP-0092]
:x
Syser : CPU Numbers = 1
Syser : Host machine is VMWare!
Syser : OSVersion Major 5 Minor 0 Build 2195
Syser : Find SyserBoot DevEx = 819BDD98
Syser : Find SysLang DevEx = 819BDAB8
Syser : Start Init
Syser : Init FileIO!
Syser : Load API 2791 records
Syser : Init Wisp GUI!
Syser : Create Frame Window!
Break due to BP 02: BPX 0008:F8097C38 (ET=1.14 seconds)
//
:u f8097b16 l 100
0008:F8097B16  XOR       ECX,ECX
0008:F8097B18  TEST      ECX,ECX
0008:F8097B1A  JNZ      F8097B0F
0008:F8097B1C  MOV       DWORD PTR [EBP-1C],00000000
0008:F8097B23  JMP      F8097B2E
0008:F8097B25  MOV       EDX,[EBP-1C]//
0008:F8097B28  ADD       EDX,01
0008:F8097B2B  MOV       [EBP-1C],EDX
0008:F8097B2E  LEA       ECX,[EBP-18]
0008:F8097B31  CALL     F801DD00
0008:F8097B36  CMP       [EBP-1C],EAX
0008:F8097B39  JGE      F8097BA1
0008:F8097B3B  MOV       DWORD PTR [EBP-20],00000000
0008:F8097B42  JMP      F8097B4D
0008:F8097B44  MOV       EAX,[EBP-20]
0008:F8097B47  ADD       EAX,01
0008:F8097B4A  MOV       [EBP-20],EAX
0008:F8097B4D  CMP       DWORD PTR [EBP-20],08
0008:F8097B51  JGE      F8097B9F
0008:F8097B53  MOV       ECX,[EBP-1C]
0008:F8097B56  PUSH      ECX
0008:F8097B57  LEA       ECX,[EBP-18]
0008:F8097B5A  CALL     F8097CE0
0008:F8097B5F  MOVSX     EDX,BYTE PTR [EAX]//
0008:F8097B62  MOV       EAX,[EBP-20]//
0008:F8097B65  MOVZX     ECX,BYTE PTR [EAX+EBP-08]//
0008:F8097B6A  XOR       ECX,EDX
0008:F8097B6C  MOV       EDX,[EBP-20]
0008:F8097B6F  MOV       [EDX+EBP-08],CL
0008:F8097B73  MOV       ESI,00000007
0008:F8097B78  SUB       ESI,[EBP-20]
0008:F8097B7B  MOV       EAX,[EBP-1C]
0008:F8097B7E  PUSH      EAX
0008:F8097B7F  LEA       ECX,[EBP-18]
0008:F8097B82  CALL     F8097CE0
0008:F8097B87  MOVSX     ECX,BYTE PTR [EAX]
0008:F8097B8A  MOVZX     EDX,BYTE PTR [ESI+EBP-08]
0008:F8097B8F  ADD       EDX,ECX
0008:F8097B91  MOV       EAX,00000007
0008:F8097B96  SUB       EAX,[EBP-20]
0008:F8097B99  MOV       [EAX+EBP-08],DL
0008:F8097B9D  JMP      F8097B44
0008:F8097B9F  JMP      F8097B25

我把上面的代码简单的说一下,我真的不知道怎么写注释,太乱了,
先是8个字节的固定值
67   2E   F3   C1   CD   A8   45   9B
用注册名的每一个字节与每个数据进行异操作,存入里面,还是用这个注册名与数据另一端的数据相加。也就是注册名的每个字节都要进行8次计算,完了以后这数组中的8个字节转化为16个字节的字符串,这就是注册码了。
算法如下
 for(j=0;j<length;j++)
 {
      for(i=0;i<8;i++)
      {
          key[i]=key[i]^lic[j];
          key[7-i]=key[7-i]+lic[j];
      }
 }

表达的不好意思,请见谅,最后附上注册机完整的源代码。

#include <stdio.h>
#include <string.h>

unsigned char map[]={'0','1','2','3',
                     '4','5','6','7',
                     '8','9','a','b',
                     'c','d','e','f'};
char *hextostring(const char* in,char *out);

main()
{
 unsigned char key[]={0x67,0x2e,0xf3,0xc1,0xcd,0xa8,0x45,0x9b};
 unsigned char lic[]="vessial";
 unsigned char genkey[17]={'\0'};
 int i,j;

 int length=strlen(lic);
 for(j=0;j<length;j++)
 {
      for(i=0;i<8;i++)
      {
          key[i]=key[i]^lic[j];
          key[7-i]=key[7-i]+lic[j];
      }
 }
 
   hextostring(key,genkey);
   printf("the key is : %s\n",genkey);
   return 0;
}

char *hextostring(const char* in,char *out)
{
    char *p=in;
    int i;
    for (i=0;i<8;i++)
    {
       if (p!=NULL)
       {
        out[2*i]=map[((*p)>>4)&0x0f];
        out[2*i+1]=map[(*p)&0x0f];
        p++;
       }
   }
}

省掉了很多查找的细节,还望大家见谅,我刚开始用softice调试驱动,没什么经验。
ps: syser debugger 的驱动有点问题,softice调试时经常会蓝屏。