【软件名称】   超级通讯王1.83

【加密方式】   序列号/注册码

【破解工具】   ollydbg/ida

【破解难度】   +++初级+++ 

【作者声明】:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教



----------------------------------------------------------------------------------------------
【软件简介】

一款多种功能的优秀个人信息管理软件.

----------------------------------------------------------------------------------------------
【破解过程】

0041FB00 >  6A FF           push -1
0041FB02    68 A8BE4D00     push <SuperPIM.unknown_libname_477>
0041FB07    64:A1 00000000  mov eax,dword ptr fs:[0]
0041FB0D    50              push eax
0041FB0E    64:8925 0000000>mov dword ptr fs:[0],esp
0041FB15    83EC 08         sub esp,8
0041FB18    53              push ebx
0041FB19    56              push esi
0041FB1A    57              push edi
0041FB1B    6A 01           push 1
0041FB1D    8BF1            mov esi,ecx
0041FB1F    E8 DC530800     call <SuperPIM.sub_4A4F00>
0041FB24    8D4424 0C       lea eax,dword ptr ss:[esp+C]
0041FB28    50              push eax
0041FB29    E8 322A0400     call <SuperPIM.sub_462560>
0041FB2E    83C4 04         add esp,4
0041FB31    8B4E 74         mov ecx,dword ptr ds:[esi+74]                        ;取输入注册码
0041FB34    8B41 F4         mov eax,dword ptr ds:[ecx-C]
0041FB37    85C0            test eax,eax
0041FB39    8D7E 74         lea edi,dword ptr ds:[esi+74]
0041FB3C    C74424 1C 00000>mov dword ptr ss:[esp+1C],0
0041FB44    0F84 D6000000   je <SuperPIM.loc_41FC20>                            ; 输入注册码长度为0?
0041FB4A    6A 28           push 28
0041FB4C    8D5424 14       lea edx,dword ptr ss:[esp+14]
0041FB50    57              push edi
0041FB51    52              push edx
0041FB52    E8 B97E0300     call <SuperPIM.sub_457A10>
0041FB57    8B4C24 18       mov ecx,dword ptr ss:[esp+18]
0041FB5B    8B00            mov eax,dword ptr ds:[eax]
0041FB5D    51              push ecx
0041FB5E    50              push eax
0041FB5F    E8 790D0700     call <SuperPIM.__mbscmp>                            ; 比较机器码变换后的字符串
0041FB64    8BD8            mov ebx,eax                                         ; 和输入的注册码变换后的字符串
0041FB66    8B4424 24       mov eax,dword ptr ss:[esp+24]                       ; 相同则注册成功
0041FB6A    83C4 14         add esp,14
0041FB6D    F7DB            neg ebx                                             ;相同则bl为0
0041FB6F    1ADB            sbb bl,bl
0041FB71    83C0 F0         add eax,-10
0041FB74    FEC3            inc bl
0041FB76    8D50 0C         lea edx,dword ptr ds:[eax+C]
0041FB79    83C9 FF         or ecx,FFFFFFFF
0041FB7C    F0:0FC10A       lock xadd dword ptr ds:[edx],ecx
0041FB80    49              dec ecx
0041FB81    85C9            test ecx,ecx
0041FB83    7F 08           jg short <SuperPIM.loc_41FB8D>
0041FB85    8B08            mov ecx,dword ptr ds:[eax]                          ; SuperPIM.0052C3B8
0041FB87    8B11            mov edx,dword ptr ds:[ecx]
0041FB89    50              push eax
0041FB8A    FF52 04         call dword ptr ds:[edx+4]
0041FB8D >  84DB            test bl,bl
0041FB8F    0F84 8B000000   je <SuperPIM.loc_41FC20>
0041FB95    8D4424 10       lea eax,dword ptr ss:[esp+10]
0041FB99    6A 71           push 71                                             ; 注册成功
0041FB9B    50              push eax
0041FB9C    E8 AF270400     call <SuperPIM.sub_462350>                          ;注册成功的消息框

跟进关键call,0041FB52    E8 B97E0300     call <SuperPIM.sub_457A10>

00457AD2    8A140A          mov dl,byte ptr ds:[edx+ecx]                        ; sratr 待处理的字符串
00457AD5    885424 20       mov byte ptr ss:[esp+20],dl
00457AD9    8B4424 20       mov eax,dword ptr ss:[esp+20]
00457ADD    50              push eax
00457ADE    E8 8DFDFFFF     call <SuperPIM.sub_457870>
00457AE3    33D2            xor edx,edx                                         ;把计算结果转换成可显示字符
00457AE5    B9 2B000000     mov ecx,2B
00457AEA    F7F1            div ecx
00457AEC    83C4 08         add esp,8
00457AEF    8BDA            mov ebx,edx
00457AF1    80C3 30         add bl,30
00457AF4    80FB 39         cmp bl,39
00457AF7    7E 08           jle short <SuperPIM.loc_457B01>
00457AF9    80FB 41         cmp bl,41
00457AFC    7D 03           jge short <SuperPIM.loc_457B01>
00457AFE    80C3 F6         add bl,0F6
00457B01 >  3BEF            cmp ebp,edi
00457B03    7D 3B           jge short <SuperPIM.loc_457B40>
00457B05    8B46 FC         mov eax,dword ptr ds:[esi-4]
00457B08    8B56 F4         mov edx,dword ptr ds:[esi-C]
00457B0B    B9 01000000     mov ecx,1
00457B10    2BC8            sub ecx,eax
00457B12    8B46 F8         mov eax,dword ptr ds:[esi-8]
00457B15    8D7A 01         lea edi,dword ptr ds:[edx+1]
00457B18    2BC7            sub eax,edi
00457B1A    0BC1            or eax,ecx
00457B1C    895424 20       mov dword ptr ss:[esp+20],edx
00457B20    7D 12           jge short <SuperPIM.loc_457B34>                    ;比较循环记数

待处理的字符串分别为:硬盘物理序列号+硬盘厂商标识,序列号,输入的注册码等等,通过变换
分别得到变换后的字符串.

设转换函数为F(sourctr,counter)注册验证过程为:
serial number=F(硬盘物理序列号+硬盘厂商标识),
tmpstr1=F(serial number)
tmpstr2=F(tmpstr1)

tmpstr3=F(input code)

其中变换函数F相同,只是其中循环次数不一样。
测试是否tmp3=tmp2,结果为真则注册成功,所以,只要
input code=tmpstr1(F(serial number))就可以了,而这个中间字符串tmpstr1是
以明码状态出现的 ,也就是说这个软件其实还是属于明码比较的.

变换的具体实现:

00457870 >  51              push ecx
00457871    0FB64424 08     movzx eax,byte ptr ss:[esp+8]                       ; 字符在串中的序数(由0开始)
00457876    894424 00       mov dword ptr ss:[esp],eax
0045787A    8B4424 0C       mov eax,dword ptr ss:[esp+C]
0045787E    8BC8            mov ecx,eax
00457880    0FAFC8          imul ecx,eax
00457883    8D4C49 07       lea ecx,dword ptr ds:[ecx+ecx*2+7]
00457887    0FAFC8          imul ecx,eax
0045788A    83C1 0D         add ecx,0D
0045788D    0FAFC8          imul ecx,eax                                         ;预计算结果
00457890    56              push esi
00457891    8D70 05         lea esi,dword ptr ds:[eax+5]
00457894    56              push esi
00457895    8D5424 10       lea edx,dword ptr ss:[esp+10]
00457899    6A 04           push 4
0045789B    52              push edx
0045789C    894C24 18       mov dword ptr ss:[esp+18],ecx
004578A0    E8 CBFEFFFF     call <SuperPIM.sub_457770>
004578A5    56              push esi
004578A6    8D4424 14       lea eax,dword ptr ss:[esp+14]
004578AA    6A 04           push 4
004578AC    50              push eax
004578AD    E8 3EFFFFFF     call <SuperPIM.sub_4577F0>
004578B2    8B4424 24       mov eax,dword ptr ss:[esp+24]
004578B6    8B4C24 1C       mov ecx,dword ptr ss:[esp+1C]
004578BA    83C4 18         add esp,18
004578BD    33C1            xor eax,ecx
004578BF    5E              pop esi
004578C0    59              pop ecx
004578C1    C3              retn



004577D0 >  57              push edi                                            ;外循环
004577D1    53              push ebx
004577D2    E8 09FFFFFF     call <SuperPIM.sub_4576E0>
004577D7    83C4 08         add esp,8
004577DA    4E              dec esi
004577DB  ^ 75 F3           jnz short <SuperPIM.loc_4577D0>                     ; 初始为5,按照序数递增



004576E0 >  8B4424 08       mov eax,dword ptr ss:[esp+8]                        ;内循环,次数为固定值:4
004576E4    56              push esi
004576E5    8B7424 08       mov esi,dword ptr ss:[esp+8]
004576E9    33D2            xor edx,edx
004576EB    8A5406 FF       mov dl,byte ptr ds:[esi+eax-1]                      ; 
004576EF    8BCE            mov ecx,esi
004576F1    81E2 80000000   and edx,80
004576F7    85C0            test eax,eax
004576F9    8BF2            mov esi,edx
004576FB    74 22           je short <SuperPIM.loc_45771F>
004576FD    57              push edi
004576FE    8BF8            mov edi,eax
00457700 >  8A01            mov al,byte ptr ds:[ecx]                            ; 
00457702    33D2            xor edx,edx
00457704    8AD0            mov dl,al
00457706    D0E0            shl al,1
00457708    8801            mov byte ptr ds:[ecx],al
0045770A    81E2 80000000   and edx,80
00457710    85F6            test esi,esi
00457712    74 04           je short <SuperPIM.loc_457718>
00457714    0C 01           or al,1                                             ; 
00457716    8801            mov byte ptr ds:[ecx],al
00457718 >  41              inc ecx
00457719    4F              dec edi
0045771A    8BF2            mov esi,edx
0045771C  ^ 75 E2           jnz short <SuperPIM.loc_457700>
0045771E    5F              pop edi                                             ; 
0045771F >  5E              pop esi
00457720    C3              retn

以上为循环1,设这个结果为tmp1.


00457850 >  57              push edi                                            ; 外循环
00457851    53              push ebx
00457852    E8 D9FEFFFF     call <SuperPIM.sub_457730>
00457857    83C4 08         add esp,8
0045785A    4E              dec esi                                             ; 初始循环5次,按照字符在串中序数依次加1
0045785B  ^ 75 F3           jnz short <SuperPIM.loc_457850>
0045785D >  5F              pop edi
0045785E    5E              pop esi
0045785F    5B              pop ebx
00457860 >  C3              retn



00457730 >  8B4C24 04       mov ecx,dword ptr ss:[esp+4]                        ;内循环,次数为固定值:4
00457734    33C0            xor eax,eax
00457736    8A01            mov al,byte ptr ds:[ecx]
00457738    56              push esi
00457739    83E0 01         and eax,1
0045773C    8BF0            mov esi,eax
0045773E    8B4424 0C       mov eax,dword ptr ss:[esp+C]
00457742    85C0            test eax,eax
00457744    8D4C01 FF       lea ecx,dword ptr ds:[ecx+eax-1]
00457748    74 22           je short <SuperPIM.loc_45776C>
0045774A    57              push edi
0045774B    8BF8            mov edi,eax
0045774D    8D49 00         lea ecx,dword ptr ds:[ecx]
00457750 >  8A01            mov al,byte ptr ds:[ecx]                            ; 
00457752    33D2            xor edx,edx
00457754    8AD0            mov dl,al
00457756    D0E8            shr al,1
00457758    8801            mov byte ptr ds:[ecx],al
0045775A    83E2 01         and edx,1
0045775D    85F6            test esi,esi
0045775F    74 04           je short <SuperPIM.loc_457765>
00457761    0C 80           or al,80
00457763    8801            mov byte ptr ds:[ecx],al
00457765 >  49              dec ecx
00457766    4F              dec edi                                             ; 循环4次
00457767    8BF2            mov esi,edx
00457769  ^ 75 E5           jnz short <SuperPIM.loc_457750>
0045776B    5F              pop edi
0045776C >  5E              pop esi
0045776D    C3              retn


以上为循环2,设结果为tmp2.


004578B2    8B4424 24       mov eax,dword ptr ss:[esp+24]                   ;tmp1
004578B6    8B4C24 1C       mov ecx,dword ptr ss:[esp+1C]                   ;tmp2
004578BA    83C4 18         add esp,18
004578BD    33C1            xor eax,ecx                                     ;tmp1 xor tmp2
004578BF    5E              pop esi
004578C0    59              pop ecx
004578C1    C3              retn


把tmp xor tmp2的结果转换成可显示字符:
00457AE3    33D2            xor edx,edx
00457AE5    B9 2B000000     mov ecx,2B
00457AEA    F7F1            div ecx
00457AEC    83C4 08         add esp,8
00457AEF    8BDA            mov ebx,edx
00457AF1    80C3 30         add bl,30
00457AF4    80FB 39         cmp bl,39
00457AF7    7E 08           jle short <SuperPIM.loc_457B01>
00457AF9    80FB 41         cmp bl,41
00457AFC    7D 03           jge short <SuperPIM.loc_457B01>
00457AFE    80C3 F6         add bl,0F6
00457B01 >  3BEF            cmp ebp,edi
00457B03    7D 3B           jge short <SuperPIM.loc_457B40>

这就是对待处理字符串中一个字符进行处理的完整过程。这两段循环计算开始看时候很
乱,花了很久才搞明白是怎么回事,其实就是很简单的dword乘除计算。
归根到底还是自己的汇编基础太差了,对汇编中的一些常用计算都不能很快识别。
我说的也不清楚,具体的实现,大家还是自己看下面的注册机代码吧。

//---------------------key.cpp---------------------
#include <iostream>

#include <string>

using namespace std; 


//循环1
long change1(char input, int count)
{
long tmpCode;

int flag;

tmpCode = count - 5;

tmpCode *= tmpCode;

tmpCode = tmpCode * 3 + 7;

tmpCode *= (count - 5);

tmpCode += 0xd;

tmpCode *= (count - 5);


//tmpCode *= pow(2,count);
for(int i =0; i< count;i++)
{
  flag = 0;

  if(tmpCode>=0x80000000)
  {
    flag = 1;
  }

  tmpCode *=2;

  if(flag)
  {
    tmpCode += 1;
  }

}

                          
return tmpCode;

}

//循环2
long change2(char input, int count)
{
  unsigned long tmp,tmpCode;

  bool flag;

  tmp = input;

  tmpCode = 0;

  while(count)
  {
    flag = false;

    if(tmp & 1)
    {
      flag = true;
    }
    tmp /=2;

    tmpCode /=2;

    if(flag)
    {
      tmpCode |= 0x80000000;

    }

    count --;
  }

  tmpCode += tmp;

  return tmpCode;
}

//把计算结果转换成可显示字符
long change(char input, int count)
{
  unsigned long code,tmp;

  code = change1(input, count) ^ change2(input, count);

  tmp = code % 0x2b;

  tmp += 0x30;
  if((tmp > 0x39) && (tmp <0x41) )
  {
    tmp = (tmp + 0xf6) - 0x100;
  }

  code = tmp;
                          
  return code;


}

int main()
{
  char *strMcode,*tmpStr,*code;
  
  strMcode = new char [20];

  tmpStr = new char [40];

  code = new char [21];
  
  cout << "Serial Number:";
  
  cin >> strMcode;

  cout << endl;
  
  strcpy(tmpStr,strMcode);
  
  while(strlen( tmpStr ) < 20)
  {
    strcat(tmpStr,strMcode);
    
  }

  for(int i = 0,j = 5; i < 20 ; i++)
  {
    code[i] = change(tmpStr[i], j);

    j++;
  }

  code[i] = '\0';

  cout << "Reg Code:" << code << endl;

  cout << "Press any key to exit." << endl;

  cin.get();  cin.get();

  delete [] strMcode;
  
  delete [] tmpStr;

  delete [] code;
  
  return 0;


}

//-------------------key.cpp----------------------------

例子:
serial number:
BZIR21250R4LKPF
reg code:
3WDNL0511KM52E5W063Y


----------------------------------------------------------


by ikki[D.4s]