• 标 题:加密精灵 (EncryptGenie) 2.61
  • 作 者:summon
  • 时 间:2003/04/22 10:03am
  • 链 接:http://bbs.pediy.com

加密精灵注册机算法分析:
请各位大侠多多指点!谢谢!
软件:加密精灵加密精灵 (EncryptGenie) 2.61 版
工具:trw1.22娃娃修正版,VC++6.0,fi2.5。
软件简介:
加密精灵 (EncryptGenie) 2.61 版是一个功能强大非常方便和
容易使用的加密文件和邮件的软件,
安装后的软件为未注册版本,有两个功能限制:
1. 未注册版最多只可以输入10个字符长的密码。注册版最多可以输入128个字符长的密码。
2. 未注册版软件不能保存编辑的加密规则。
首先用fi查看有无壳,结果无壳,并且是用VC++6.0编写的。
运行加密精灵,弹出注册对话框,输入姓名:crackerboy
注册码:7878787878
运行trw1.22
Ctrl+N呼出trw
下断点bpx hmemcpy
bc *
pmodule
来到下面的代码:

:004018C1 6A1E                    push 0000001E
:004018C3 68E84E4400              push 00444EE8
:004018C8 6815040000              push 00000415
:004018CD 53                      push ebx
:004018CE FFD6                    call esi/*得到注册名*/
:004018D0 50                      push eax
:004018D1 FFD7                    call edi/*得到注册码*/
:004018D3 6A02                    push 00000002
:004018D5 6A00                    push 00000000
:004018D7 E844CE0100              call 0041E720
:004018DC 6A00                    push 00000000
:004018DE 68E84E4400              push 00444EE8
:004018E3 68EC594400              push 004459EC

* Reference To: Rule.CheckRegister, Ord:0000h
                                 |
:004018E8 E82B060300              Call 00431F18/*检查注册码*/
:004018ED 83C414                  add esp, 00000014
:004018F0 F7D8                    neg eax
:004018F2 1BC0                    sbb eax, eax
Rule.CheckRegister顾名思义是检查注册,这是关键call,按F8跟进去。

004734B0 > 8B4424 04        MOV EAX,DWORD PTR SS:[ESP+4]            
004734B4   83EC 28          SUB ESP,28
004734B7   85C0             TEST EAX,EAX
004734B9   57               PUSH EDI
004734BA   74 5A            JE SHORT RULE.00473516
004734BC   8B7C24 34        MOV EDI,DWORD PTR SS:[ESP+34]
004734C0   85FF             TEST EDI,EDI
004734C2   74 52            JE SHORT RULE.00473516
004734C4   8D4C24 04        LEA ECX,DWORD PTR SS:[ESP+4]
004734C8   51               PUSH ECX
004734C9   50               PUSH EAX
004734CA   E8 51000000      CALL RULE.CreateRegisterSerial/*产生注册码*/
004734CF   83C4 08          ADD ESP,8
004734D2   85C0             TEST EAX,EAX
004734D4   74 40            JE SHORT RULE.00473516
004734D6   53               PUSH EBX
004734D7   56               PUSH ESI
004734D8   8D7424 0C        LEA ESI,DWORD PTR SS:[ESP+C]
004734DC   8BC7             MOV EAX,EDI
004734DE   8A10             MOV DL,BYTE PTR DS:[EAX]
004734E0   8A1E             MOV BL,BYTE PTR DS:[ESI]
004734E2   8ACA             MOV CL,DL
004734E4   3AD3             CMP DL,BL
004734E6   75 1E            JNZ SHORT RULE.00473506
004734E8   84C9             TEST CL,CL
004734EA   74 16            JE SHORT RULE.00473502
004734EC   8A50 01          MOV DL,BYTE PTR DS:[EAX+1]
004734EF   8A5E 01          MOV BL,BYTE PTR DS:[ESI+1]
004734F2   8ACA             MOV CL,DL
004734F4   3AD3             CMP DL,BL
004734F6   75 0E            JNZ SHORT RULE.00473506
004734F8   83C0 02          ADD EAX,2
004734FB   83C6 02          ADD ESI,2
004734FE   84C9             TEST CL,CL
00473500  ^75 DC            JNZ SHORT RULE.004734DE
00473502   33C0             XOR EAX,EAX
00473504   EB 05            JMP SHORT RULE.0047350B
00473506   1BC0             SBB EAX,EAX
00473508   83D8 FF          SBB EAX,-1
0047350B   5E               POP ESI
0047350C   5B               POP EBX
0047350D   85C0             TEST EAX,EAX
0047350F   75 05            JNZ SHORT RULE.00473516
00473511   5F               POP EDI
00473512   83C4 28          ADD ESP,28
00473515   C3               RETN
00473516   B8 01000000      MOV EAX,1
0047351B   5F               POP EDI
0047351C   83C4 28          ADD ESP,28
0047351F   C3               RETN
走到004734CA 时按F8跟进去,它是产生注册码的子程序。
按F8后就来到这里:

00473520 > 8B5424 04        MOV EDX,DWORD PTR SS:[ESP+4]
00473524   83EC 2C          SUB ESP,2C
00473527   85D2             TEST EDX,EDX
00473529   57               PUSH EDI
0047352A   0F84 B6000000    JE RULE.004735E6
00473530   8B4424 38        MOV EAX,DWORD PTR SS:[ESP+38]
00473534   85C0             TEST EAX,EAX
00473536   0F84 AA000000    JE RULE.004735E6
0047353C   8BFA             MOV EDI,EDX
0047353E   83C9 FF          OR ECX,FFFFFFFF
00473541   33C0             XOR EAX,EAX
00473543   F2:AE            REPNE SCAS BYTE PTR ES:[EDI]
00473545   F7D1             NOT ECX
00473547   49               DEC ECX    /*得到用户名长度*/
00473548   83F9 03          CMP ECX,3
0047354B   0F8C 95000000    JL RULE.004735E6/*小于3则跳走*/
00473551   53               PUSH EBX
00473552   55               PUSH EBP
00473553   56               PUSH ESI
00473554   B3 41            MOV BL,41                       /*
00473556   885C04 14        MOV BYTE PTR SS:[ESP+EAX+14],BL /*
0047355A   FEC3             INC BL                          /*
0047355C   40               INC EAX
0047355D   83F8 1A          CMP EAX,1A                      /*
00473560  ^75 F4            JNZ SHORT RULE.00473556         /*
这里产生密码表:从A到Z

00473562   B3 30            MOV BL,30                       /*
00473564   885C04 14        MOV BYTE PTR SS:[ESP+EAX+14],BL /*
00473568   FEC3             INC BL                          /*
0047356A   40               INC EAX                         /*
0047356B   83F8 25          CMP EAX,25                      /*
0047356E  ^75 F4            JNZ SHORT RULE.00473564         /*
产生0到9

00473570   33ED             XOR EBP,EBP/*清ebp*/
00473572   33C0             XOR EAX,EAX/*清eax*/
00473574   85C9             TEST ECX,ECX
00473576   896C24 10        MOV DWORD PTR SS:[ESP+10],EBP
0047357A   7E 10            JLE SHORT RULE.0047358C/*长度小于零则跳走*/
0047357C   33DB             XOR EBX,EBX/*ebx清零*/
0047357E   8A1C10           MOV BL,BYTE PTR DS:[EAX+EDX]/*把注册码的第一个字符送给Bl*/
00473581   03EB             ADD EBP,EBX/*
00473583   40               INC EAX/*
00473584   3BC1             CMP EAX,ECX/*
00473586  ^7C F4            JL SHORT RULE.0047357C/*
从47357c到473586是这样的:它把注册名的所有注册名累加,并送入ebp保存。

00473588   896C24 10        MOV DWORD PTR SS:[ESP+10],EBP
0047358C   33FF             XOR EDI,EDI
0047358E   33DB             XOR EBX,EBX
00473590   BE 08184800      MOV ESI,RULE.00481808
00473595   EB 08            JMP SHORT RULE.0047359F
00473597   8B6C24 10        MOV EBP,DWORD PTR SS:[ESP+10]
0047359B   8B5424 40        MOV EDX,DWORD PTR SS:[ESP+40]
0047359F   33C0             XOR EAX,EAX
004735A1   8A0417           MOV AL,BYTE PTR DS:[EDI+EDX]/*送注册名的字符给al*/
004735A4   03C5             ADD EAX,EBP/*与所有注册名的ascii值相加*/
004735A6   8B2E             MOV EBP,DWORD PTR DS:[ESI]/*送常数数组给esi*/
004735A8   03C1             ADD EAX,ECX
004735AA   03C5             ADD EAX,EBP
004735AC   3BF9             CMP EDI,ECX/*比较是否超过了注册名长度*/
004735AE   7C 04            JL SHORT RULE.004735B4/*没超过就跳*/
004735B0   33FF             XOR EDI,EDI
004735B2   EB 01            JMP SHORT RULE.004735B5/*跳*/
004735B4   47               INC EDI/*指向下一个注册名*/
004735B5   99               CDQ
004735B6   BD 24000000      MOV EBP,24
004735BB   83C6 04          ADD ESI,4
004735BE   F7FD             IDIV EBP/*除以0x24即36*/
004735C0   8B6C24 44        MOV EBP,DWORD PTR SS:[ESP+44]
004735C4   43               INC EBX
004735C5   81FE 48184800    CMP ESI,RULE.00481848  /*是否超过了常数数组*/              
004735CB   8A4414 14        MOV AL,BYTE PTR SS:[ESP+EDX+14]/*dl是除数,这样就在密码表中定位了
注册码*/

004735CF   88442B FF        MOV BYTE PTR DS:[EBX+EBP-1],AL/*存注册码*/
004735D3  ^7C C2            JL SHORT RULE.00473597/*没超过就继续*/
004735D5   C6042B 00        MOV BYTE PTR DS:[EBX+EBP],0
004735D9   5E               POP ESI
004735DA   5D               POP EBP
004735DB   5B               POP EBX
004735DC   B8 01000000      MOV EAX,1
004735E1   5F               POP EDI
004735E2   83C4 2C          ADD ESP,2C
004735E5   C3               RETN
注册码的长度等于常数数组的长度,也是16位。
注册机的VC源程序如下(关键部分):

void CPatch0Dlg::OnOK()
{  UpdateData();
int length=m_hstr0.GetLength();
m_hcode="";
// TODO: Add extra validation here
GetDlgItem(IDC_EDIT1)->SetFocus();
  char  password[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";//密码表
   int count[]={0x16,0x1e,0x13,0x0c,0x09,0x04,0x19,0x1a,0x24,0x20,0x13,0x07,0x36,0x0e,0x32,0x3c};//常数数组
   int name1[17],flag0=0,flag1=1,flag2=0,countnum=0,i,j,k=0,l=0;
if((length<0)||(length<4))
{MessageBox("输入名字不能是空或者名字少于4个字符!!",0,MB_OK);
flag2=1;
}
   else
{for(i=0;i<length;i++)
 {name1[i]=(int)m_hstr0[i];
 flag1=isupper(m_hstr0[i])|isdigit(m_hstr0[i])|islower(m_hstr0[i]);
 if(!flag1)
 {flag0=1;
   flag2=1;
     };
}
 if(flag0)
 MessageBox("你输入的字符有非ASCII字符,请重新输入!!",0,MB_OK);
 else if(!flag2)
 { for(i=length;i<17;i++)
 name1[i]=0;
for(i=0;i<length;i++)
    countnum+=name1[i];
      i=0;
  CString temp;
  m_hcode+=temp;
      for(j=0;j<16;j++)
  {if(k>length)//k是当前的注册名长度
        k=0;
       i=countnum+length+name1[k++]+count[j];
    l=i%0x24;
   temp.format("%c",password[l]);//定位注册码
m_hcode+=temp;
   i=0;
      }
  GetDlgItem(IDC_EDIT2)->SetWindowText(m_hcode);
 }
}
if(flag2)
{GetDlgItem(IDC_EDIT2)->SetWindowText("");
GetDlgItem(IDC_EDIT1)->SetWindowText("");
}

//CDialog::OnOK();
}